diff options
author | Carlos Maniero <carlos@maniero.me> | 2023-05-10 13:53:53 -0300 |
---|---|---|
committer | Carlos Maniero <carlos@maniero.me> | 2023-05-10 14:06:38 -0300 |
commit | f1b1c191975581d5ef13bd04f33b6965235d00b4 (patch) | |
tree | 456b8d787f97d214814e0c8b209b4d039c6baa0b | |
parent | a96a0cac034e16dcd7455a3b2fabf2b5b3e716bd (diff) |
gas: Abstract refs with helper functions
This commit abstract the complexity of an entry so then, the users of
the ref map does not need to understand how is it implemented.
Signed-off-by: Carlos Maniero <carlos@maniero.me>
-rw-r--r-- | src/gas_assembly_generator.c | 60 |
1 files changed, 34 insertions, 26 deletions
diff --git a/src/gas_assembly_generator.c b/src/gas_assembly_generator.c index 44467db..97ba9ce 100644 --- a/src/gas_assembly_generator.c +++ b/src/gas_assembly_generator.c @@ -105,16 +105,29 @@ ref_entry_new(void) return entry; } -static ref_entry_t * -find_ref_entry(vector_t *refs, ast_identifier_t *identifier) +static int +ref_find_variable_reference_stack_offset(vector_t *refs, ast_identifier_t *identifier) { for (int i = refs->size - 1; i >= 0; --i) { ref_entry_t *entry = (ref_entry_t *)vector_at(refs, i); if (entry->id == identifier) { - return entry; + return entry->stack_offset; } } - return NULL; + assert(false); +} + +static void +ref_set_variable_reference_stack_offset(vector_t *refs, ast_identifier_t *identifier, int stack_offset) +{ + ref_entry_t *ref_entry = ref_entry_new(); + + *ref_entry = (ref_entry_t){ + .id = identifier, + .stack_offset = stack_offset, + }; + + vector_push_back(refs, ref_entry); } void @@ -218,13 +231,13 @@ gas_assembly_generator_compile_return_stmt(gas_assembly_generator_t *gen, ast_re static void gas_assembly_generator_compile_variable_assign_value(gas_assembly_generator_t *gen, ast_node_t *expression, - ref_entry_t *entry) + int stack_offset) { if (expression->result_type == TYPE_BOOL) { if (expression->kind == AST_LITERAL) { assert(expression->data.literal.kind == AST_LITERAL_BOOL); - fprintf(gen->stream, " movq $%d, %d(%%rbp)\n", expression->data.literal.value.boolean, entry->stack_offset); + fprintf(gen->stream, " movq $%d, %d(%%rbp)\n", expression->data.literal.value.boolean, stack_offset); return; } @@ -235,11 +248,11 @@ gas_assembly_generator_compile_variable_assign_value(gas_assembly_generator_t *g gas_assembly_generator_compile_condition(gen, expression, true_label_index, false, false_label_index, true); fprintf(gen->stream, ".L_%ld:\n", true_label_index); - fprintf(gen->stream, " movq $1, %d(%%rbp)\n", entry->stack_offset); + fprintf(gen->stream, " movq $1, %d(%%rbp)\n", stack_offset); fprintf(gen->stream, " jmp .L_%ld\n", after_assign_label_index); fprintf(gen->stream, ".L_%ld:\n", false_label_index); - fprintf(gen->stream, " movq $0, %d(%%rbp)\n", entry->stack_offset); + fprintf(gen->stream, " movq $0, %d(%%rbp)\n", stack_offset); fprintf(gen->stream, ".L_%ld:\n", after_assign_label_index); return; @@ -249,14 +262,14 @@ gas_assembly_generator_compile_variable_assign_value(gas_assembly_generator_t *g switch (gen->latest_evaluation.kind) { case EVALUATION_RESULT_AS_LITERAL_INTEGER: - fprintf(gen->stream, " movq $%ld, %d(%%rbp)\n", gen->latest_evaluation.data.literal_int, entry->stack_offset); + fprintf(gen->stream, " movq $%ld, %d(%%rbp)\n", gen->latest_evaluation.data.literal_int, stack_offset); break; case EVALUATION_RESULT_ON_RAX: - fprintf(gen->stream, " mov %%rax, %d(%%rbp)\n", entry->stack_offset); + fprintf(gen->stream, " mov %%rax, %d(%%rbp)\n", stack_offset); break; case EVALUATION_RESULT_ON_STACK: fprintf(gen->stream, " movq %d(%%rbp), %%rax\n", gen->latest_evaluation.data.stack_offset); - fprintf(gen->stream, " movq %%rax, %d(%%rbp)\n", entry->stack_offset); + fprintf(gen->stream, " movq %%rax, %d(%%rbp)\n", stack_offset); break; case EVALUATION_RESULT_AS_LITERAL_BOOL: case EVALUATION_RESULT_VOID: @@ -270,30 +283,25 @@ gas_assembly_generator_compile_variable_declaration(gas_assembly_generator_t *ge ast_variable_declaration_t *variable_declaration) { gen->stack_offset -= 8; - - ref_entry_t *entry = ref_entry_new(); - *entry = (ref_entry_t){ .id = &variable_declaration->identifier, .stack_offset = gen->stack_offset }; - vector_push_back(gen->refs, entry); - - gas_assembly_generator_compile_variable_assign_value(gen, variable_declaration->value, entry); + ref_set_variable_reference_stack_offset(gen->refs, &variable_declaration->identifier, gen->stack_offset); + gas_assembly_generator_compile_variable_assign_value(gen, variable_declaration->value, gen->stack_offset); } static void gas_assembly_generator_compile_variable_assignment(gas_assembly_generator_t *gen, ast_variable_assignment_t *variable_assignment) { - ref_entry_t *entry = find_ref_entry(gen->refs, variable_assignment->identifier); - assert(entry && "reference not found"); + int stack_offset = ref_find_variable_reference_stack_offset(gen->refs, variable_assignment->identifier); - gas_assembly_generator_compile_variable_assign_value(gen, variable_assignment->expression, entry); + gas_assembly_generator_compile_variable_assign_value(gen, variable_assignment->expression, stack_offset); } static void gas_assembly_generator_compile_variable(gas_assembly_generator_t *gen, ast_variable_t *variable) { - ref_entry_t *entry = find_ref_entry(gen->refs, variable->identifier); - assert(entry && "reference not found"); - gas_assembly_generator_set_latest_evaluation_on_stack(gen, entry->stack_offset); + int stack_offset = ref_find_variable_reference_stack_offset(gen->refs, variable->identifier); + + gas_assembly_generator_set_latest_evaluation_on_stack(gen, stack_offset); } static void @@ -503,16 +511,16 @@ gas_assembly_generator_compile_if_stmt(gas_assembly_generator_t *gen, ast_if_stm } case AST_VARIABLE: { uint64_t false_label_index = gen->cur_label_index++; - ref_entry_t *entry = find_ref_entry(gen->refs, if_stmt->condition->data.variable.identifier); + int stack_offset = + ref_find_variable_reference_stack_offset(gen->refs, if_stmt->condition->data.variable.identifier); - fprintf(gen->stream, " movq %d(%%rbp), %%rax\n", entry->stack_offset); + fprintf(gen->stream, " movq %d(%%rbp), %%rax\n", stack_offset); fprintf(gen->stream, " cmpq $1, %%rax\n"); fprintf(gen->stream, " jne .L_%ld\n", false_label_index); gas_assembly_generator_compile(gen, if_stmt->body); fprintf(gen->stream, ".L_%ld:\n", false_label_index); - assert(entry); break; } default: |