diff options
-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: |