diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-02-05 23:51:26 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-02-06 00:01:34 +0900 |
| commit | 3633f9a1f4f7638355beba85c53a2bb2ab0e3976 (patch) | |
| tree | 58dd3231c5580d770defc2268ffe75dd87c11dec /src/parse.c | |
| parent | 0dcaa7de7208bbcd56624011a43bac66f5dee44b (diff) | |
| download | ducc-3633f9a1f4f7638355beba85c53a2bb2ab0e3976.tar.gz ducc-3633f9a1f4f7638355beba85c53a2bb2ab0e3976.tar.zst ducc-3633f9a1f4f7638355beba85c53a2bb2ab0e3976.zip | |
feat: implement more complex initializer
Diffstat (limited to 'src/parse.c')
| -rw-r--r-- | src/parse.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/src/parse.c b/src/parse.c index 629a39f..4a36d6d 100644 --- a/src/parse.c +++ b/src/parse.c @@ -1346,6 +1346,12 @@ static void declare_func_or_var(Parser* p, AstNode* decl) { decl->ty->storage_class = base_ty->storage_class; base_ty->storage_class = StorageClass_unspecified; + // TODO: refactor + if (decl->ty->kind == TypeKind_array && decl->ty->array_size == -1 && decl->as.declarator && + decl->as.declarator->init && decl->as.declarator->init->kind == AstNodeKind_array_initializer) { + decl->ty->array_size = decl->as.declarator->init->as.array_initializer->list->as.list->len; + } + GlobalVar* gvar = gvars_push_new(&p->gvars); gvar->name = name; gvar->ty = decl->ty; @@ -2689,3 +2695,41 @@ bool pp_eval_constant_expr(TokenArray* pp_tokens) { AstNode* e = parse_constant_expr(p); return eval(e) != 0; } + +void eval_init_expr(StrBuilder* buf, AstNode* expr, Type* ty) { + if (expr->kind == AstNodeKind_array_initializer) { + AstNode* list = expr->as.array_initializer->list; + if (ty->kind == TypeKind_array) { + for (int i = 0; i < list->as.list->len; ++i) { + eval_init_expr(buf, &list->as.list->items[i], ty->base); + } + } else if (ty->kind == TypeKind_struct) { + AstNode* def = &ty->ref.defs->as.list->items[ty->ref.index]; + AstNode* members = def->as.struct_def->members; + int offset = 0; + for (int i = 0; i < list->as.list->len; ++i) { + AstNode* member = &members->as.list->items[i]; + int align = type_alignof(member->ty); + int aligned_offset = to_aligned(offset, align); + for (int p = offset; p < aligned_offset; ++p) { + strbuilder_append_char(buf, 0); + } + offset = aligned_offset; + eval_init_expr(buf, &list->as.list->items[i], member->ty); + offset += type_sizeof(member->ty); + } + int total = type_sizeof(ty); + for (int p = offset; p < total; ++p) { + strbuilder_append_char(buf, 0); + } + } else { + unimplemented(); + } + } else { + int value = eval(expr); + int size = type_sizeof(ty); + for (int i = 0; i < size; ++i) { + strbuilder_append_char(buf, (value >> (i * 8)) & 0xff); + } + } +} |
