diff options
| author | nsfisis <nsfisis@gmail.com> | 2025-09-28 11:35:01 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2025-09-28 11:35:04 +0900 |
| commit | 235969b792bf11e8b7927318cf01b5ef5705177b (patch) | |
| tree | 40726f12cafb44f2d4d2cbd6125d4162203f679a | |
| parent | 74dbe1fc92a6bb3f03f5582280f4e02b9158a523 (diff) | |
| download | ducc-235969b792bf11e8b7927318cf01b5ef5705177b.tar.gz ducc-235969b792bf11e8b7927318cf01b5ef5705177b.tar.zst ducc-235969b792bf11e8b7927318cf01b5ef5705177b.zip | |
feat: allow global variable initializer to reference another global variable addresses
| -rw-r--r-- | src/codegen.c | 26 | ||||
| -rw-r--r-- | tests/test_global_variables.sh | 23 |
2 files changed, 45 insertions, 4 deletions
diff --git a/src/codegen.c b/src/codegen.c index 91f8cc6..36f854d 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -736,14 +736,32 @@ void codegen(Program* prog, FILE* out) { for (int i = 0; i < prog->vars->node_len; ++i) { AstNode* var = prog->vars->node_items + i; if (var->node_expr) { - if (type_sizeof(var->ty) == 1) + if (type_sizeof(var->ty) == 1) { + if (var->node_expr->kind != AstNodeKind_int_expr) + unimplemented(); fprintf(g->out, " %s: .byte %d\n", var->name, var->node_expr->node_int_value); - else if (type_sizeof(var->ty) == 2) + } else if (type_sizeof(var->ty) == 2) { + if (var->node_expr->kind != AstNodeKind_int_expr) + unimplemented(); fprintf(g->out, " %s: .word %d\n", var->name, var->node_expr->node_int_value); - else if (type_sizeof(var->ty) == 4) + } else if (type_sizeof(var->ty) == 4) { + if (var->node_expr->kind != AstNodeKind_int_expr) + unimplemented(); fprintf(g->out, " %s: .int %d\n", var->name, var->node_expr->node_int_value); - else + } else if (var->ty->kind == TypeKind_ptr) { + if (var->node_expr->kind == AstNodeKind_ref_expr) { + if (var->node_expr->node_operand->kind != AstNodeKind_gvar) { + unimplemented(); + } + fprintf(g->out, " %s: .quad %s\n", var->name, var->node_expr->node_operand->name); + } else if (var->node_expr->kind == AstNodeKind_gvar) { + fprintf(g->out, " %s: .quad %s\n", var->name, var->node_expr->name); + } else { + unimplemented(); + } + } else { unimplemented(); + } } else { fprintf(g->out, " %s: .zero %d\n", var->name, type_sizeof(var->ty)); } diff --git a/tests/test_global_variables.sh b/tests/test_global_variables.sh index b4eef09..8de1483 100644 --- a/tests/test_global_variables.sh +++ b/tests/test_global_variables.sh @@ -14,3 +14,26 @@ int main() { } EOF +test_exit_code 0 <<'EOF' +#include "../../helpers.h" + +int a; +int* b = &a; +int c[10]; +int* d = c; +int e, *f = e, g[10], *h = g; + +int main() { + *b = 123; + ASSERT_EQ(123, a); + + d[2] = 42; + ASSERT_EQ(42, c[2]); + + *f = 456; + ASSERT_EQ(456, e); + + h[5] = 789; + ASSERT_EQ(789, g[5]); +} +EOF |
