summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gas_assembly_generator.c60
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: