stage1 支持结构体初始化

This commit is contained in:
zzy committed 2026-09-14 10:09:32 +08:00
1 parent 72ae6d6994
commit 9bdb7f892e
4 files changed
+72 -15

No files matched your search

+62 -6
View File
@@ -38,6 +38,56 @@ static spl_ir_node_ref_t ast2ir_intrin_call(spl_ast2ir_t *a, spl_ast_node_t *n,
static spl_ir_node_ref_t ast2ir_intrin_field(spl_ast2ir_t *a, spl_ast_node_t *n, spl_intrin_t in);
static spl_ir_node_ref_t ast2ir_intrin_len(spl_ast2ir_t *a, spl_ast_node_t *n);
static spl_ir_node_ref_t emit_zero_value(spl_ast2ir_t *a, spl_type_id_t tid) {
spl_type_node_t *tn = spl_type_node(a->sema->type, tid);
if (!tn)
return 0;
switch (tn->kind) {
case SPL_TYPE_BOOL:
return spl_ir_builder_type_const_bool(a->ir, tid, false);
case SPL_TYPE_INT:
return spl_ir_builder_type_const_int(a->ir, tid, 0);
case SPL_TYPE_FLOAT:
return spl_ir_builder_type_const_float(a->ir, tid, 0.0);
case SPL_TYPE_PTR:
case SPL_TYPE_FN:
return spl_ir_builder_type_const_ptr(a->ir, tid, NULL);
case SPL_TYPE_ARRAY: {
spl_ir_node_ref_t node = spl_ir_builder_agg_construct(a->ir, tid);
for (usize i = 0; i < tn->array_type.len; ++i) {
spl_ir_node_ref_t f = emit_zero_value(a, tn->array_type.element);
if (!f)
return 0;
spl_ir_builder_agg_construct_field(a->ir, node, f);
}
return node;
}
case SPL_TYPE_STRUCT:
case SPL_TYPE_SHAPE: {
spl_ir_node_ref_t node = spl_ir_builder_agg_construct(a->ir, tid);
for (usize i = 0; i < vec_size(tn->agg_type.variants); ++i) {
spl_ir_node_ref_t f = emit_zero_value(a, vec_at(tn->agg_type.variants, i).type_id);
if (!f)
return 0;
spl_ir_builder_agg_construct_field(a->ir, node, f);
}
return node;
}
case SPL_TYPE_UNION: {
spl_ir_node_ref_t node = spl_ir_builder_agg_construct(a->ir, tid);
if (vec_size(tn->agg_type.variants) == 0)
return node;
spl_ir_node_ref_t f = emit_zero_value(a, vec_at(tn->agg_type.variants, 0).type_id);
if (!f)
return 0;
spl_ir_builder_agg_construct_field(a->ir, node, f);
return node;
}
default:
return 0;
}
}
static void copy_attrs_to_ir_node(spl_ast2ir_t *a, spl_ast_node_t *n, spl_ir_node_ref_t ir_ref) {
if (!ir_ref || !n || vec_size(n->attrs) == 0)
return;
@@ -629,18 +679,24 @@ static spl_ir_node_ref_t emit_expr_raw(spl_ast2ir_t *a, spl_ast_node_ref_t ref)
vec_at(fields, idx) = f;
}
for (usize i = 0; i < nfields; ++i) {
if (!vec_at(fields, i)) {
spl_type_id_t ftid = vec_at(tn->agg_type.variants, i).type_id;
spl_ir_node_ref_t f = emit_zero_value(a, ftid);
if (!f)
Panic("cannot zero-init aggregate field #%zu", i);
vec_at(fields, i) = f;
}
}
spl_ir_node_ref_t node = spl_ir_builder_agg_construct(a->ir, t);
if (!node)
Panic("agg_construct failed for aggregate literal");
/* 顺序非常关键:agg_construct_field 是 vec_push,
必须严格按字段 index 0..n-1 顺序 push */
for (usize i = 0; i < nfields; ++i) {
spl_ir_node_ref_t f = vec_at(fields, i);
if (!f)
Panic("aggregate field #%zu missing (sema should have caught this)", i);
spl_ir_builder_agg_construct_field(a->ir, node, f);
spl_ir_builder_agg_construct_field(a->ir, node, vec_at(fields, i));
}
vec_free(fields);
return node;
}