diff options
Diffstat (limited to 'codegen.c')
| -rw-r--r-- | codegen.c | 47 |
1 files changed, 36 insertions, 11 deletions
@@ -50,6 +50,24 @@ static void emit_int_lit( } } +static void emit_var_ref( + FILE* outfile, + const struct var_ref_node* node, + const struct storage_location* storage +) { + if (storage != NULL) { + struct var_def var_def; + if (!scope_get_var(scope, &var_def, node->ident)) + CGEN_PANIC("reference to undefined variable %s", node->ident); + + fprintf(outfile, "\tmov "); + emit_storage_loc(outfile, &var_def.loc); + fprintf(outfile, ", "); + emit_storage_loc(outfile, storage); + fprintf(outfile, "\n"); + } +} + static void emit_expr( FILE* outfile, const struct expr_node* node, @@ -61,22 +79,28 @@ static void emit_expr( case EXPR_INT_LIT: emit_int_lit(outfile, &node->as._int_lit, storage); break; + case EXPR_VAR_REF: + emit_var_ref(outfile, &node->as._var_ref, storage); } } static void emit_stmt(FILE* outfile, const struct stmt_node* node); -static struct type_def get_type_def(const char* type_name) { +static unsigned long long get_type_size(const struct type_node* type) { + if (type->ptr_level > 0) return 8; + struct type_def type_def; - if (!scope_get_type(scope, &type_def, type_name)) - CGEN_PANIC("size of type %s is not known", type_name); - return type_def; + if (!scope_get_type(scope, &type_def, type->name)) + CGEN_PANIC("size of type %s is not known", type->name); + + return type_def.size; } static void emit_var_decl(FILE* outfile, const struct var_decl_node* node) { - struct type_def type_def = get_type_def(node->type.type); - fprintf(outfile, "\tsub rsp, %llu\n", type_def.size); - scope->bp_offset += type_def.size; + unsigned long long type_sz = get_type_size(&node->type); + + fprintf(outfile, "\tsub rsp, %llu\n", type_sz); + scope->bp_offset += type_sz; scope_define_var(scope, (struct var_def) { .name = node->ident, .loc = { @@ -148,7 +172,8 @@ static void emit_fn_decl(FILE* outfile, const struct fn_decl_node* node) { struct var_decl_node* args_node = node->args_head; long long arg_bp_offset = -8; while (args_node != NULL) { - struct type_def type_def = get_type_def(args_node->type.type); + unsigned long long type_sz = get_type_size(&args_node->type); + scope_define_var(scope, (struct var_def) { .name = args_node->ident, .loc = { @@ -156,7 +181,8 @@ static void emit_fn_decl(FILE* outfile, const struct fn_decl_node* node) { .offset = arg_bp_offset, }, }); - arg_bp_offset -= type_def.size; + + arg_bp_offset -= type_sz; args_node = args_node->next; } @@ -183,8 +209,7 @@ void emit_code(const struct root_node* ast, const char* path) { fprintf(outfile, "section .text\n"); scope_push(&scope); - - /* TODO: register all basic types */ + scope_install_default_types(scope); /* output all non-static function declarations as globals */ const struct root_node* node = ast; |
