summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Maniero <carlos@maniero.me>2023-05-10 13:53:53 -0300
committerCarlos Maniero <carlos@maniero.me>2023-05-10 14:06:38 -0300
commitf1b1c191975581d5ef13bd04f33b6965235d00b4 (patch)
tree456b8d787f97d214814e0c8b209b4d039c6baa0b
parenta96a0cac034e16dcd7455a3b2fabf2b5b3e716bd (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.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: