diff options
| author | nsfisis <nsfisis@gmail.com> | 2025-08-19 00:26:29 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2025-08-19 00:26:29 +0900 |
| commit | 2aacd7a4b67bd6f9c11e005c72c4e52e6b644212 (patch) | |
| tree | 7396430bf8f204e1bd2dadca429408359ef14a09 | |
| parent | 79796388b3c040bda25ce330af72ca514b30f60c (diff) | |
| download | ducc-2aacd7a4b67bd6f9c11e005c72c4e52e6b644212.tar.gz ducc-2aacd7a4b67bd6f9c11e005c72c4e52e6b644212.tar.zst ducc-2aacd7a4b67bd6f9c11e005c72c4e52e6b644212.zip | |
feat: support global variable declaration with multiple variables
| -rw-r--r-- | parse.c | 56 | ||||
| -rw-r--r-- | tests/095.sh | 3 |
2 files changed, 29 insertions, 30 deletions
@@ -1110,50 +1110,42 @@ AstNode* parse_param_list(Parser* p) { return list; } -AstNode* parse_global_var_decl(Parser* p, Type* ty, const char* name) { - if (type_is_unsized(ty)) { +AstNode* parse_global_var_decl(Parser* p) { + Type* base_ty = parse_type(p); + if (type_is_unsized(base_ty)) { fatal_error("parse_global_var_decl: invalid type for variable"); } - if (peek_token(p)->kind == TokenKind_bracket_l) { - next_token(p); - AstNode* size_expr = parse_expr(p); - if (size_expr->kind != AstNodeKind_int_expr) { - fatal_error("parse_global_var_decl: invalid array size"); - } - int size = size_expr->node_int_value; - expect(p, TokenKind_bracket_r); - ty = type_new_array(ty, size); - } - - AstNode* init = NULL; - if (peek_token(p)->kind == TokenKind_assign) { - next_token(p); - init = parse_assignment_expr(p); - } + AstNode* decls = parse_init_declarator_list(p, base_ty); expect(p, TokenKind_semicolon); - if (find_gvar(p, name) != -1) { - fatal_error("parse_global_var_decl: %s redeclared", name); - } + for (int i = 0; i < decls->node_len; ++i) { + AstNode* decl = &decls->node_items[i]; - p->gvars[p->n_gvars].name = name; - p->gvars[p->n_gvars].ty = ty; - ++p->n_gvars; + if (find_gvar(p, decl->name) != -1) { + fatal_error("parse_global_var_decl: %s redeclared", decl->name); + } + p->gvars[p->n_gvars].name = decl->name; + p->gvars[p->n_gvars].ty = decl->ty; + ++p->n_gvars; - AstNode* ret = ast_new(AstNodeKind_gvar_decl); - ret->name = name; - ret->ty = ty; - ret->node_expr = init; - return ret; + decl->kind = AstNodeKind_gvar_decl; + decl->node_expr = decl->node_init; + } + return decls; } AstNode* parse_func_decl_or_def(Parser* p) { + // TODO: remove it. + int start_pos = p->pos; + Type* ty = parse_type(p); const char* name = parse_ident(p); if (peek_token(p)->kind != TokenKind_paren_l) { - return parse_global_var_decl(p, ty, name); + // TODO: avoid backtracking + p->pos = start_pos; + return parse_global_var_decl(p); } expect(p, TokenKind_paren_l); @@ -1390,6 +1382,10 @@ Program* parse(TokenArray* tokens) { ast_append(funcs, n); } else if (n->kind == AstNodeKind_gvar_decl && n->ty) { ast_append(vars, n); + } else if (n->kind == AstNodeKind_list) { + for (int i = 0; i < n->node_len; ++i) { + ast_append(vars, &n->node_items[i]); + } } } Program* prog = calloc(1, sizeof(Program)); diff --git a/tests/095.sh b/tests/095.sh index 58ee35f..65cd31a 100644 --- a/tests/095.sh +++ b/tests/095.sh @@ -2,14 +2,17 @@ set -e cat <<'EOF' > expected 1 2 3 4 +0 0 5 EOF bash ../../test_diff.sh <<'EOF' int printf(); +int x, y, z = 5; int main() { int a, b; a = 1, b = 2; int c = 3, d = 4; printf("%d %d %d %d\n", a, b, c, d); + printf("%d %d %d\n", x, y, z); } EOF |
