stage1 支持结构体初始化
This commit is contained in:
1 parent
72ae6d6994
commit
9bdb7f892e
4 files changed
+72
-15
No files matched your search
+62
-6
@@ -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_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 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) {
|
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)
|
if (!ir_ref || !n || vec_size(n->attrs) == 0)
|
||||||
return;
|
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;
|
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);
|
spl_ir_node_ref_t node = spl_ir_builder_agg_construct(a->ir, t);
|
||||||
if (!node)
|
if (!node)
|
||||||
Panic("agg_construct failed for aggregate literal");
|
Panic("agg_construct failed for aggregate literal");
|
||||||
|
|
||||||
/* 顺序非常关键:agg_construct_field 是 vec_push,
|
|
||||||
必须严格按字段 index 0..n-1 顺序 push */
|
|
||||||
for (usize i = 0; i < nfields; ++i) {
|
for (usize i = 0; i < nfields; ++i) {
|
||||||
spl_ir_node_ref_t f = vec_at(fields, i);
|
spl_ir_builder_agg_construct_field(a->ir, node, 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vec_free(fields);
|
vec_free(fields);
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ const char *spl_ir_kind_name(spl_ir_kind_t kind) {
|
|||||||
return "?";
|
return "?";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define SPL_ENUM_TAG_FIELD_IDX 0
|
||||||
|
|
||||||
void spl_ir_init(spl_ir_t *ir) {
|
void spl_ir_init(spl_ir_t *ir) {
|
||||||
vec_init(ir->funcs);
|
vec_init(ir->funcs);
|
||||||
vec_push(ir->funcs, (spl_ir_func_t){0});
|
vec_push(ir->funcs, (spl_ir_func_t){0});
|
||||||
|
|||||||
+2
-2
@@ -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);
|
spl_type_node_t *tn = spl_type_node(cg->ctx->type, n->arith.tid);
|
||||||
if (tn && tn->kind == SPL_TYPE_BOOL) {
|
if (tn && tn->kind == SPL_TYPE_BOOL) {
|
||||||
cg_load_slot(cg, n->arith.left, SPL_BOOL);
|
cg_load_slot(cg, n->arith.left, SPL_BOOL);
|
||||||
CG_PUSH(cg, SPL_U8, 0);
|
CG_PUSH(cg, SPL_BOOL, 0);
|
||||||
CG_OP(cg, SPL_EQ, SPL_U8);
|
CG_OP(cg, SPL_EQ, SPL_BOOL);
|
||||||
cg_store_slot(cg, ref, SPL_BOOL);
|
cg_store_slot(cg, ref, SPL_BOOL);
|
||||||
} else {
|
} else {
|
||||||
cg_unop(cg, ref, n, SPL_NOT);
|
cg_unop(cg, ref, n, SPL_NOT);
|
||||||
|
|||||||
+6
-7
@@ -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_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,
|
static spl_lang_type_id_t sema_check(spl_sema_t *sema, spl_ast_node_ref_t ref,
|
||||||
spl_lang_type_id_t expected);
|
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);
|
sema_check(sema, item->struct_init_item.expr, ft);
|
||||||
}
|
}
|
||||||
for (usize i = 0; i < nfields; ++i) {
|
// for (usize i = 0; i < nfields; ++i) {
|
||||||
if (!seen[i]) {
|
// if (!seen[i]) {
|
||||||
SPL_ERROR(&n->dbg, "missing field `%s`", vec_at(irn->agg_type.variants, i).name);
|
// SPL_ERROR(&n->dbg, "missing field `%s`", vec_at(irn->agg_type.variants, i).name);
|
||||||
sema->error_count++;
|
// sema->error_count++;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
free(seen);
|
free(seen);
|
||||||
n->resolved_lang_tid = expected;
|
n->resolved_lang_tid = expected;
|
||||||
n->expected_lang_tid = 0;
|
n->expected_lang_tid = 0;
|
||||||
|
|||||||
Reference in new issue
Block a user