Implement SIZE_FMT and vec_append_fmt
SIZE_FMT gets the size of a cstr with the given sprintf formatted string and arguments using `snprintf`. vec_append_fmt formats a cstr with the given sprintf arguments then appends it to the given vector. This simplifies a little bit of the wordy implementation of the assembler.
This commit is contained in:
91
assembler.c
91
assembler.c
@@ -72,53 +72,49 @@ void asm_translate_nodes(vec_t *asm_buffer, struct PResult nodes,
|
||||
for (size_t i = 0; i < nodes.size; ++i)
|
||||
{
|
||||
node_t node = nodes.nodes[i];
|
||||
if (node.type == LIN || node.type == LOUT)
|
||||
{
|
||||
// Translate the node-relative addresses to assembly-label-relative
|
||||
// addresses
|
||||
i64 cur_asm_label = 0, next_asm_label = 0;
|
||||
ast_ref_to_asm_label(i, labels, nodes.labels * 2, &cur_asm_label,
|
||||
&next_asm_label);
|
||||
if (cur_asm_label == -1 || next_asm_label == -1)
|
||||
{
|
||||
print_error(
|
||||
src_name, node.row, node.col,
|
||||
"[ASSEMBLY ERROR]: Could not find label for current jump!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Format labels
|
||||
char current_label[128], next_label[128];
|
||||
|
||||
sprintf(current_label, ".L%lu", cur_asm_label);
|
||||
sprintf(next_label, ".L%lu", next_asm_label);
|
||||
|
||||
// Setup format string for assembly jump code
|
||||
char *format_string = NULL;
|
||||
if (node.type == LIN)
|
||||
{
|
||||
format_string = "%s:\n"
|
||||
" cmp byte [r9], 0\n"
|
||||
" je %s\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
format_string = "%s:\n"
|
||||
" cmp byte [r9], 0\n"
|
||||
" jne %s\n";
|
||||
}
|
||||
char formatted_string[snprintf(NULL, 0, format_string, current_label,
|
||||
next_label) +
|
||||
1];
|
||||
snprintf(formatted_string, sizeof(formatted_string), format_string,
|
||||
current_label, next_label);
|
||||
vec_append(asm_buffer, formatted_string, sizeof(formatted_string) - 1);
|
||||
}
|
||||
else
|
||||
// Something we can compile with only the information at hand
|
||||
if (!(node.type == LIN || node.type == LOUT))
|
||||
{
|
||||
// I love tables so goddamn much
|
||||
vec_append(asm_buffer, table[node.type].str, table[node.type].len);
|
||||
continue;
|
||||
}
|
||||
|
||||
// NOTE: Must be a label
|
||||
|
||||
// Translate the node-relative addresses to assembly-label-relative
|
||||
// addresses
|
||||
i64 cur_asm_label = 0, next_asm_label = 0;
|
||||
ast_ref_to_asm_label(i, labels, nodes.labels * 2, &cur_asm_label,
|
||||
&next_asm_label);
|
||||
if (cur_asm_label == -1 || next_asm_label == -1)
|
||||
{
|
||||
print_error(src_name, node.row, node.col,
|
||||
"[ASSEMBLY ERROR]: Could not find label for current jump!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Format labels
|
||||
char current_label[128], next_label[128];
|
||||
|
||||
sprintf(current_label, ".L%lu", cur_asm_label);
|
||||
sprintf(next_label, ".L%lu", next_asm_label);
|
||||
|
||||
// Setup format string for assembly jump code
|
||||
char *format_string = NULL;
|
||||
if (node.type == LIN)
|
||||
{
|
||||
format_string = "%s:\n"
|
||||
" cmp byte [r9], 0\n"
|
||||
" je %s\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
format_string = "%s:\n"
|
||||
" cmp byte [r9], 0\n"
|
||||
" jne %s\n";
|
||||
}
|
||||
vec_append_fmt(asm_buffer, format_string, current_label, next_label);
|
||||
}
|
||||
asm_write_exit(asm_buffer);
|
||||
}
|
||||
@@ -151,10 +147,7 @@ void asm_write_init(vec_t *asm_buffer)
|
||||
"global _start\n"
|
||||
"_start:\n"
|
||||
" mov r9, memory\n";
|
||||
char initial_assembly[snprintf(NULL, 0, format_string, MEMORY_DEFAULT) + 1];
|
||||
snprintf(initial_assembly, sizeof(initial_assembly), format_string,
|
||||
MEMORY_DEFAULT);
|
||||
vec_append(asm_buffer, initial_assembly, sizeof(initial_assembly) - 1);
|
||||
vec_append_fmt(asm_buffer, format_string, MEMORY_DEFAULT);
|
||||
}
|
||||
|
||||
// Write the exit code for the assembly file
|
||||
@@ -183,7 +176,7 @@ int asm_assemble(const char *asm_name, const char *objname)
|
||||
#else
|
||||
char *format_str = "yasm -f elf64 -o %s %s";
|
||||
#endif
|
||||
char command[snprintf(NULL, 0, format_str, objname, asm_name) + 1];
|
||||
char command[SIZE_FMT(format_str, objname, asm_name) + 1];
|
||||
sprintf(command, format_str, objname, asm_name);
|
||||
return system(command);
|
||||
}
|
||||
@@ -191,7 +184,7 @@ int asm_assemble(const char *asm_name, const char *objname)
|
||||
int asm_link(const char *objname, const char *outname)
|
||||
{
|
||||
char *format_str = "ld -o %s %s";
|
||||
char command[snprintf(NULL, 0, format_str, outname, objname) + 1];
|
||||
char command[SIZE_FMT(format_str, outname, objname) + 1];
|
||||
sprintf(command, format_str, outname, objname);
|
||||
return system(command);
|
||||
}
|
||||
|
||||
10
lib.h
10
lib.h
@@ -26,6 +26,8 @@ char *fread_all(FILE *fp);
|
||||
void print_error(const char *handle, size_t row, size_t column,
|
||||
const char *reason);
|
||||
|
||||
#define SIZE_FMT(FMT, ...) (snprintf(NULL, 0, (FMT), __VA_ARGS__))
|
||||
|
||||
typedef struct Buffer
|
||||
{
|
||||
const char *name;
|
||||
@@ -46,4 +48,12 @@ void vec_ensure(vec_t *vec, u64 abs_size);
|
||||
void vec_ensure_free(vec_t *vec, u64 rel_size);
|
||||
void vec_free(vec_t *vec);
|
||||
|
||||
#define vec_append_fmt(VEC, FMT, ...) \
|
||||
do \
|
||||
{ \
|
||||
char f[SIZE_FMT(FMT, __VA_ARGS__) + 1]; \
|
||||
snprintf(f, sizeof(f), (FMT), __VA_ARGS__); \
|
||||
vec_append((VEC), f, sizeof(f) - 1); \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user