diff --git a/stage1/spl_ast2ir.c b/stage1/spl_ast2ir.c index 0a787ee..17663ec 100644 --- a/stage1/spl_ast2ir.c +++ b/stage1/spl_ast2ir.c @@ -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; } diff --git a/stage1/spl_ir.c b/stage1/spl_ir.c index 95f95f7..555e00a 100644 --- a/stage1/spl_ir.c +++ b/stage1/spl_ir.c @@ -11,6 +11,8 @@ const char *spl_ir_kind_name(spl_ir_kind_t kind) { return "?"; } +#define SPL_ENUM_TAG_FIELD_IDX 0 + void spl_ir_init(spl_ir_t *ir) { vec_init(ir->funcs); vec_push(ir->funcs, (spl_ir_func_t){0}); diff --git a/stage1/spl_ir2vm.c b/stage1/spl_ir2vm.c index 4c02854..bd6ed83 100644 --- a/stage1/spl_ir2vm.c +++ b/stage1/spl_ir2vm.c @@ -858,8 +858,8 @@ static void cg_node(cgen_t *cg, usize ref, const spl_ir_node_t *n) { spl_type_node_t *tn = spl_type_node(cg->ctx->type, n->arith.tid); if (tn && tn->kind == SPL_TYPE_BOOL) { cg_load_slot(cg, n->arith.left, SPL_BOOL); - CG_PUSH(cg, SPL_U8, 0); - CG_OP(cg, SPL_EQ, SPL_U8); + CG_PUSH(cg, SPL_BOOL, 0); + CG_OP(cg, SPL_EQ, SPL_BOOL); cg_store_slot(cg, ref, SPL_BOOL); } else { cg_unop(cg, ref, n, SPL_NOT); diff --git a/stage1/spl_sema.c b/stage1/spl_sema.c index dc0d29b..83a5578 100644 --- a/stage1/spl_sema.c +++ b/stage1/spl_sema.c @@ -139,7 +139,6 @@ static void sema_resolve_attrs(spl_sema_t *sema, spl_ast_node_ref_vec_t *raw, } } -static spl_lang_type_id_t sema_parse(spl_sema_t *sema, spl_ast_node_ref_t ref); static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref); static spl_lang_type_id_t sema_check(spl_sema_t *sema, spl_ast_node_ref_t ref, spl_lang_type_id_t expected); @@ -493,12 +492,12 @@ static spl_lang_type_id_t sema_check(spl_sema_t *sema, spl_ast_node_ref_t ref, } sema_check(sema, item->struct_init_item.expr, ft); } - for (usize i = 0; i < nfields; ++i) { - if (!seen[i]) { - SPL_ERROR(&n->dbg, "missing field `%s`", vec_at(irn->agg_type.variants, i).name); - sema->error_count++; - } - } + // for (usize i = 0; i < nfields; ++i) { + // if (!seen[i]) { + // SPL_ERROR(&n->dbg, "missing field `%s`", vec_at(irn->agg_type.variants, i).name); + // sema->error_count++; + // } + // } free(seen); n->resolved_lang_tid = expected; n->expected_lang_tid = 0;