summaryrefslogtreecommitdiff
path: root/src/gas_assembly_generator.c
diff options
context:
space:
mode:
authorCarlos Maniero <carlosmaniero@gmail.com>2023-04-20 13:42:10 -0300
committerJohnny Richard <johnny@johnnyrichard.com>2023-04-20 18:57:43 +0200
commit219dfdfdc98529ce173f894b79d88919a65c2808 (patch)
tree8792c686d05b107875d43f570ed6666f91dda19e /src/gas_assembly_generator.c
parent58da5195ef7d517f851ebfabfe79cfa27c0b2dde (diff)
parser: Create the literal node type
Since we want to extend our code to support multiple kind of expression it does not make sense that the return statement always return a number. For now on, return statement has an ast_node_t as argument, meaning that it could be anything. The literal_node_t was also implemented in order to keep the application behavior. Following the C's calling convention the literal values are stored at %eax and the return takes this argument to do anything it is needed. Signed-off-by: Carlos Maniero <carlosmaniero@gmail.com> Reviewed-by: Johnny Richard <johnny@johnnyrichard.com>
Diffstat (limited to 'src/gas_assembly_generator.c')
-rw-r--r--src/gas_assembly_generator.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/src/gas_assembly_generator.c b/src/gas_assembly_generator.c
index afbfebd..755b0be 100644
--- a/src/gas_assembly_generator.c
+++ b/src/gas_assembly_generator.c
@@ -22,6 +22,7 @@
static void gas_assembly_generator_visit_function(ast_visitor_t *visitor, ast_function_declaration_t *func);
static void gas_assembly_generator_visit_return_stmt(ast_visitor_t *visitor, ast_return_stmt_t *return_stmt);
+static void gas_assembly_generator_visit_literal(ast_visitor_t *visitor, ast_literal_t *return_stmt);
void
gas_assembly_generator_init(gas_assembly_generator_t *gen, FILE *out)
@@ -29,6 +30,7 @@ gas_assembly_generator_init(gas_assembly_generator_t *gen, FILE *out)
assert(gen && out);
gen->super = (ast_visitor_t) {
.visit_function = &gas_assembly_generator_visit_function,
+ .visit_literal = &gas_assembly_generator_visit_literal,
.visit_return_stmt = &gas_assembly_generator_visit_return_stmt
};
gen->out = out;
@@ -59,8 +61,23 @@ gas_assembly_generator_visit_return_stmt(ast_visitor_t *visitor, ast_return_stmt
assert(visitor && return_stmt);
gas_assembly_generator_t *gen = (gas_assembly_generator_t *) visitor;
+ ast_visitor_visit(visitor, return_stmt->argument);
+
+ fprintf(gen->out, " mov %%eax, %%ebx\n");
+ fprintf(gen->out, " mov $1, %%al\n");
fprintf(gen->out, " mov $1, %%al\n");
- fprintf(gen->out, " mov $%d, %%ebx\n", return_stmt->number);
fprintf(gen->out, " int $0x80\n");
}
+static void
+gas_assembly_generator_visit_literal(ast_visitor_t *visitor, ast_literal_t *literal)
+{
+ gas_assembly_generator_t *gen = (gas_assembly_generator_t *) visitor;
+ switch (literal->kind) {
+ case AST_LITERAL_INTEGER:
+ fprintf(gen->out, " mov $%d, %%eax\n", literal->value.integer);
+ return;
+ default:
+ assert(false && "No code generation strategy.");
+ }
+}