diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-02-01 12:56:38 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-02-01 12:56:38 +0900 |
| commit | 0dcaa7de7208bbcd56624011a43bac66f5dee44b (patch) | |
| tree | f93385ab8e7e7f562bada428543a5e8066563899 | |
| parent | 385d2e3722c22e788230c1cfba679356fbdd2d0a (diff) | |
| download | ducc-0dcaa7de7208bbcd56624011a43bac66f5dee44b.tar.gz ducc-0dcaa7de7208bbcd56624011a43bac66f5dee44b.tar.zst ducc-0dcaa7de7208bbcd56624011a43bac66f5dee44b.zip | |
feat: implement array global variables
| -rw-r--r-- | src/codegen.c | 47 | ||||
| -rw-r--r-- | tests/variables.c | 16 |
2 files changed, 48 insertions, 15 deletions
diff --git a/src/codegen.c b/src/codegen.c index 6aac6c6..2247c6c 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -834,45 +834,62 @@ void codegen(Program* prog, FILE* out) { fprintf(g->out, ".data\n\n"); for (int i = 0; i < prog->vars->as.list->len; ++i) { AstNode* var = prog->vars->as.list->items + i; + fprintf(g->out, " %s:\n", var->as.gvar_decl->name); if (var->as.gvar_decl->expr) { if (type_sizeof(var->ty) == 1) { if (var->as.gvar_decl->expr->kind != AstNodeKind_int_expr) unimplemented(); - fprintf(g->out, " %s: .byte %d\n", var->as.gvar_decl->name, - var->as.gvar_decl->expr->as.int_expr->value); + fprintf(g->out, " .byte %d\n", var->as.gvar_decl->expr->as.int_expr->value); } else if (type_sizeof(var->ty) == 2) { if (var->as.gvar_decl->expr->kind != AstNodeKind_int_expr) unimplemented(); - fprintf(g->out, " %s: .word %d\n", var->as.gvar_decl->name, - var->as.gvar_decl->expr->as.int_expr->value); + fprintf(g->out, " .word %d\n", var->as.gvar_decl->expr->as.int_expr->value); } else if (type_sizeof(var->ty) == 4) { if (var->as.gvar_decl->expr->kind != AstNodeKind_int_expr) unimplemented(); - fprintf(g->out, " %s: .int %d\n", var->as.gvar_decl->name, - var->as.gvar_decl->expr->as.int_expr->value); + fprintf(g->out, " .long %d\n", var->as.gvar_decl->expr->as.int_expr->value); } else if (var->ty->kind == TypeKind_ptr) { if (var->as.gvar_decl->expr->kind == AstNodeKind_ref_expr) { if (var->as.gvar_decl->expr->as.ref_expr->operand->kind != AstNodeKind_gvar) { unimplemented(); } - fprintf(g->out, " %s: .quad %s\n", var->as.gvar_decl->name, - var->as.gvar_decl->expr->as.ref_expr->operand->as.gvar->name); + fprintf(g->out, " .quad %s\n", var->as.gvar_decl->expr->as.ref_expr->operand->as.gvar->name); } else if (var->as.gvar_decl->expr->kind == AstNodeKind_gvar) { - fprintf(g->out, " %s: .quad %s\n", var->as.gvar_decl->name, - var->as.gvar_decl->expr->as.gvar->name); + fprintf(g->out, " .quad %s\n", var->as.gvar_decl->expr->as.gvar->name); } else { unimplemented(); } - } else if (var->ty->kind == TypeKind_array && var->ty->base->kind == TypeKind_char) { - if (var->as.gvar_decl->expr->kind != AstNodeKind_str_expr) + } else if (var->ty->kind == TypeKind_array) { + if (var->as.gvar_decl->expr->kind == AstNodeKind_str_expr) { + const char* str = prog->str_literals[var->as.gvar_decl->expr->as.str_expr->idx - 1]; + fprintf(g->out, " .string \"%s\"\n", str); + } else if (var->as.gvar_decl->expr->kind == AstNodeKind_array_initializer) { + AstNode* init = var->as.gvar_decl->expr->as.array_initializer->list; + int elem_size = type_sizeof(var->ty->base); + const char* directive; + if (elem_size == 1) { + directive = ".byte"; + } else if (elem_size == 2) { + directive = ".word"; + } else if (elem_size == 4) { + directive = ".long"; + } else { + unimplemented(); + } + for (int j = 0; j < init->as.list->len; ++j) { + AstNode* elem = &init->as.list->items[j]; + if (elem->kind != AstNodeKind_int_expr) + unimplemented(); + fprintf(g->out, " %s %d\n", directive, elem->as.int_expr->value); + } + } else { unimplemented(); - const char* str = prog->str_literals[var->as.gvar_decl->expr->as.str_expr->idx - 1]; - fprintf(g->out, " %s: .string \"%s\"\n", var->as.gvar_decl->name, str); + } } else { unimplemented(); } } else { - fprintf(g->out, " %s: .zero %d\n", var->as.gvar_decl->name, type_sizeof(var->ty)); + fprintf(g->out, " .zero %d\n", type_sizeof(var->ty)); } } diff --git a/tests/variables.c b/tests/variables.c index 228a625..0be59a3 100644 --- a/tests/variables.c +++ b/tests/variables.c @@ -16,6 +16,10 @@ int g_k = 999; char g_l[6] = "hello"; +char arr1[3] = {65, 66, 67}; +short arr2[3] = {10, 20, 30}; +int arr3[3] = {1, 2, 3}; + int main() { // global variables *g_b = 123; @@ -36,6 +40,18 @@ int main() { ASSERT_EQ(0, strcmp("hello", g_l)); + ASSERT_EQ(65, arr1[0]); + ASSERT_EQ(66, arr1[1]); + ASSERT_EQ(67, arr1[2]); + + ASSERT_EQ(10, arr2[0]); + ASSERT_EQ(20, arr2[1]); + ASSERT_EQ(30, arr2[2]); + + ASSERT_EQ(1, arr3[0]); + ASSERT_EQ(2, arr3[1]); + ASSERT_EQ(3, arr3[2]); + // local variables int foo; foo = 42; |
