summaryrefslogtreecommitdiff
path: root/codegen.c
diff options
context:
space:
mode:
authorCarson Fleming <cflems@cflems.net>2026-07-21 14:36:02 -0700
committerCarson Fleming <cflems@cflems.net>2026-07-21 14:36:02 -0700
commit0cabbd2a0853c332c82af621b8716643741d758a (patch)
tree4d1772e07ff1b81e00b563f877c6f1ead3305a8d /codegen.c
parentf87e953223b7d498fc5401247952c08ab1e08f93 (diff)
downloadccc-0cabbd2a0853c332c82af621b8716643741d758a.tar.gz
more faithful grammar
Diffstat (limited to 'codegen.c')
-rw-r--r--codegen.c67
1 files changed, 36 insertions, 31 deletions
diff --git a/codegen.c b/codegen.c
index 955a095..a32046b 100644
--- a/codegen.c
+++ b/codegen.c
@@ -300,42 +300,20 @@ static void emit_var_ref(
static void emit_stmt(FILE* outfile, const struct stmt_node* node);
-static struct var_def* emit_var_decl(
+static void emit_var_decl(
FILE* outfile,
const struct var_decl_node* node
) {
struct lval_def var_dst =
make_stack_lval(outfile, node->def_ref->resolved_type);
+ node->def_ref->loc = var_dst.loc;
fprintf(outfile, "\t; '%s' lives in: ", node->def_ref->name);
emit_storage_loc(outfile, &var_dst.loc, var_dst.type->sz);
fprintf(outfile, "\n");
- struct var_def* var_def = node->def_ref;
- var_def->loc = var_dst.loc;
- return var_def;
-}
-
-static struct lval_def emit_lval(
- FILE* outfile,
- const struct lval_node* node
-) {
- struct var_def* var_def;
- switch (node->type) {
- case LVAL_VAR_DECL:
- var_def = emit_var_decl(outfile, &node->inner.var_decl);
- return (struct lval_def) {
- .loc = var_def->loc,
- .type = var_def->resolved_type,
- };
- case LVAL_VAR_REF:
- var_def = node->inner.var_ref.def_ref;
- return (struct lval_def) {
- .loc = var_def->loc,
- .type = var_def->resolved_type,
- };
- }
- CGEN_PANIC("unknown lval type: %d", node->type);
+ if (node->initial_value != NULL)
+ emit_expr(outfile, node->initial_value, &var_dst);
}
static void emit_assignment(
@@ -343,7 +321,18 @@ static void emit_assignment(
const struct assign_node* node,
const struct lval_def* dst
) {
- const struct lval_def lval_def = emit_lval(outfile, &node->lval);
+ struct lval_def lval_def;
+ switch (node->lval->type) {
+ case EXPR_VAR_REF:
+ struct var_ref_node* var_ref = &node->lval->inner.var_ref;
+ lval_def = (struct lval_def) {
+ .type = var_ref->def_ref->resolved_type,
+ .loc = var_ref->def_ref->loc,
+ };
+ break;
+ default:
+ CGEN_PANIC("expression is not assignable");
+ }
emit_expr(outfile, node->rval, &lval_def);
if (dst != NULL) emit_mov(outfile, dst, &lval_def.loc);
}
@@ -356,8 +345,8 @@ static void emit_call(
unsigned long long orig_bp_offset = scope->bp_offset;
unsigned long long arg_bp_offset = orig_bp_offset;
- struct args_decl_node* arg_decl = node->called_fn_ref->args;
- struct args_eval_node* arg_eval = node->args;
+ struct decl_list_node* arg_decl = node->called_fn_ref->args;
+ struct expr_list_node* arg_eval = node->args;
while (arg_decl != NULL && arg_eval != NULL) {
struct lval_def arg_dst =
make_stack_lval(outfile, arg_decl->decl->def_ref->resolved_type);
@@ -601,10 +590,26 @@ static void emit_if(FILE* outfile, const struct if_node* node) {
exit_scope(node->scope, true);
}
+static void emit_expr_list(FILE* outfile, const struct expr_list_node* node) {
+ for (; node != NULL; node = node->next)
+ emit_expr(outfile, node->expr, NULL);
+}
+
+static void emit_loop_init(FILE* outfile, const struct loop_init_node* node) {
+ switch (node->type) {
+ case INIT_EXPR_LIST:
+ emit_expr_list(outfile, node->expr_list);
+ break;
+ case INIT_DECL:
+ emit_var_decl(outfile, node->decl);
+ break;
+ }
+}
+
static void emit_loop(FILE* outfile, const struct loop_node* node) {
enter_scope(node->scope, scope->bp_offset);
- if (node->init != NULL) emit_expr(outfile, node->init, NULL);
+ if (node->init != NULL) emit_loop_init(outfile, node->init);
unsigned long long loop_num = ++loop_counter;
if (node->cond != NULL) {
@@ -671,7 +676,7 @@ static void emit_fn_decl(FILE* outfile, const struct fn_decl_node* node) {
long long spilled_bp_ofs = -16; // return address + old bp
unsigned char arg_regnum = 0;
- struct args_decl_node* arg_decl = node->args;
+ struct decl_list_node* arg_decl = node->args;
for (; arg_decl != NULL; arg_decl = arg_decl->next) {
struct var_def* arg_def = arg_decl->decl->def_ref;
struct lval_def arg_dst =