aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2025-08-15 19:55:28 +0900
committernsfisis <nsfisis@gmail.com>2025-08-15 19:55:28 +0900
commite2064554b6d653439fbbb2bcde00e6f1a1079cb4 (patch)
tree56e44f19a516169b094087902e8b5d4c1188a6f8
parent70f3db84bb3e2f4d85da7392a112f6f82ce97152 (diff)
downloadducc-e2064554b6d653439fbbb2bcde00e6f1a1079cb4.tar.gz
ducc-e2064554b6d653439fbbb2bcde00e6f1a1079cb4.tar.zst
ducc-e2064554b6d653439fbbb2bcde00e6f1a1079cb4.zip
feat: support global variables with initializer
-rw-r--r--codegen.c15
-rw-r--r--parse.c6
-rw-r--r--tests/092.sh17
3 files changed, 36 insertions, 2 deletions
diff --git a/codegen.c b/codegen.c
index d6f320a..f71d74a 100644
--- a/codegen.c
+++ b/codegen.c
@@ -564,10 +564,21 @@ void codegen(Program* prog) {
printf(" .string \"%s\"\n\n", prog->str_literals[i]);
}
- printf(".bss\n\n");
+ printf(".data\n\n");
for (int i = 0; i < prog->vars->node_len; ++i) {
AstNode* var = prog->vars->node_items + i;
- printf(" .lcomm %.*s, %d\n", var->name.len, var->name.data, type_sizeof(var->ty));
+ if (var->node_expr) {
+ if (var->ty->kind == TypeKind_char)
+ printf(" %.*s: .byte %d\n", var->name.len, var->name.data, var->node_expr->node_int_value);
+ else if (var->ty->kind == TypeKind_short)
+ printf(" %.*s: .word %d\n", var->name.len, var->name.data, var->node_expr->node_int_value);
+ else if (var->ty->kind == TypeKind_int)
+ printf(" %.*s: .int %d\n", var->name.len, var->name.data, var->node_expr->node_int_value);
+ else
+ unimplemented();
+ } else {
+ printf(" %.*s: .zero %d\n", var->name.len, var->name.data, type_sizeof(var->ty));
+ }
}
printf(".globl main\n\n");
diff --git a/parse.c b/parse.c
index a185241..09d962d 100644
--- a/parse.c
+++ b/parse.c
@@ -1058,6 +1058,11 @@ AstNode* parse_global_var_decl(Parser* p, Type* ty, String* name) {
ty = type_new_array(ty, size);
}
+ AstNode* init = NULL;
+ if (peek_token(p)->kind == TokenKind_assign) {
+ next_token(p);
+ init = parse_assignment_expr(p);
+ }
expect(p, TokenKind_semicolon);
if (find_gvar(p, name) != -1) {
@@ -1071,6 +1076,7 @@ AstNode* parse_global_var_decl(Parser* p, Type* ty, String* name) {
AstNode* ret = ast_new(AstNodeKind_gvar_decl);
ret->name = *name;
ret->ty = ty;
+ ret->node_expr = init;
return ret;
}
diff --git a/tests/092.sh b/tests/092.sh
new file mode 100644
index 0000000..00dcb44
--- /dev/null
+++ b/tests/092.sh
@@ -0,0 +1,17 @@
+set -e
+
+cat <<'EOF' > expected
+42 123 999
+EOF
+
+bash ../../test_diff.sh <<'EOF'
+int printf();
+
+char a = 42;
+short b = 123;
+int c = 999;
+
+int main() {
+ printf("%d %d %d\n", a, b, c);
+}
+EOF