stage2 更多的工具库 stage1 修复问题
This commit is contained in:
1 parent
16a1f030d4
commit
b3e38ba7e4
28 files changed
+2274
-523
No files matched your search
+76
-3
@@ -691,6 +691,69 @@ static spl_ir_node_ref_t emit_cast(spl_ast2ir_t *a, spl_ast_node_t *n) {
|
||||
return ast2ir_emit_cast_builtin(a, n, in, ft, tt, v);
|
||||
}
|
||||
|
||||
/* 字段访问的基对象是 rvalue(如函数调用结果)时的回退路径:
|
||||
* 先求值整个聚合值,再用 agg.extract 取出字段值(无需左值/临时槽)。 */
|
||||
static spl_ir_node_ref_t ast2ir_field_from_value(spl_ast2ir_t *a, spl_ast_node_t *n) {
|
||||
spl_ast_node_t *obj = spl_ast_node(a->ast, n->field.obj);
|
||||
if (!obj)
|
||||
return 0;
|
||||
spl_lang_type_id_t obj_lang = node_lang(a, obj);
|
||||
spl_lang_type_node_t *obj_ln = spl_lang_type_node(a->sema->type, obj_lang);
|
||||
if (!obj_ln)
|
||||
return 0;
|
||||
|
||||
spl_type_id_t agg_ir = to_ir_type(a, obj_lang);
|
||||
if (!agg_ir)
|
||||
return 0;
|
||||
usize idx = 0;
|
||||
if (!spl_type_agg_member_idx(&a->sema->type->ir, agg_ir, n->field.field, &idx))
|
||||
return 0;
|
||||
|
||||
usize field_idx = idx;
|
||||
if (obj_ln->kind == SPL_LANG_TYPE_ENUM)
|
||||
field_idx = idx + 1; /* enum: field 0 是 tag */
|
||||
|
||||
spl_type_id_t field_ir = 0;
|
||||
spl_type_node_t *agg_tn = spl_type_node(&a->sema->type->ir, agg_ir);
|
||||
if (agg_tn && field_idx < vec_size(agg_tn->agg_type.variants))
|
||||
field_ir = vec_at(agg_tn->agg_type.variants, field_idx).type_id;
|
||||
|
||||
spl_ir_node_ref_t val = emit_expr(a, n->field.obj);
|
||||
if (!val)
|
||||
return 0;
|
||||
return spl_ir_builder_agg_extract(a->ir, agg_ir, field_ir, field_idx, val);
|
||||
}
|
||||
|
||||
/* 限定枚举变体 Type.Variant:产出枚举常量(tag=变体下标;无载荷变体不带 payload)。 */
|
||||
static spl_ir_node_ref_t ast2ir_enum_variant(spl_ast2ir_t *a, spl_ast_node_t *n) {
|
||||
spl_type_id_t t = node_ir(a, n);
|
||||
if (!t)
|
||||
return 0;
|
||||
spl_type_node_t *tn = spl_type_node(&a->sema->type->ir, t);
|
||||
if (!tn)
|
||||
return 0;
|
||||
|
||||
usize vidx = 0;
|
||||
if (!spl_type_agg_member_idx(&a->sema->type->ir, t, n->field.field, &vidx))
|
||||
return 0;
|
||||
|
||||
spl_type_id_t tag_ir = tn->agg_type.tag_type;
|
||||
spl_ir_node_ref_t eptr = spl_ir_builder_mem_alloca(a->ir, t, const_usize(a, 1));
|
||||
spl_ir_node_ref_t tptr = spl_ir_builder_mem_field(a->ir, t, eptr, SPL_ENUM_TAG_FIELD_IDX);
|
||||
spl_ir_node_ref_t tag_val = spl_ir_builder_type_const_int(a->ir, tag_ir, vidx);
|
||||
spl_ir_builder_mem_store(a->ir, tag_ir, tptr, tag_val);
|
||||
|
||||
if (vidx < vec_size(tn->agg_type.variants)) {
|
||||
spl_type_id_t payload_ir = vec_at(tn->agg_type.variants, vidx).type_id;
|
||||
if (payload_ir) {
|
||||
spl_ir_node_ref_t pptr = spl_ir_builder_mem_field(a->ir, t, eptr, vidx + 1);
|
||||
spl_ir_node_ref_t zero = emit_zero_value(a, payload_ir);
|
||||
spl_ir_builder_mem_store(a->ir, payload_ir, pptr, zero);
|
||||
}
|
||||
}
|
||||
return eptr;
|
||||
}
|
||||
|
||||
static spl_ir_node_ref_t emit_expr(spl_ast2ir_t *a, spl_ast_node_ref_t ref) {
|
||||
spl_ir_node_ref_t val = emit_expr_raw(a, ref);
|
||||
if (!val)
|
||||
@@ -1022,10 +1085,20 @@ static spl_ir_node_ref_t emit_expr_raw(spl_ast2ir_t *a, spl_ast_node_ref_t ref)
|
||||
}
|
||||
}
|
||||
|
||||
/* 限定枚举变体 Type.Variant:基对象是聚合类型名且为 enum。 */
|
||||
spl_ast_node_t *objn = spl_ast_node(a->ast, n->field.obj);
|
||||
if (objn && objn->kind == SPL_AST_EXPR_IDENT) {
|
||||
spl_def_node_t *od = spl_def_node(a->sema->type, objn->resolved_def_id);
|
||||
spl_lang_type_id_t et = node_lang(a, objn);
|
||||
spl_lang_type_node_t *etn = spl_lang_type_node(a->sema->type, et);
|
||||
if (od && od->kind == SPL_DEF_AGG && etn && etn->kind == SPL_LANG_TYPE_ENUM)
|
||||
return ast2ir_enum_variant(a, n);
|
||||
}
|
||||
|
||||
spl_ir_node_ref_t ptr = emit_lvalue(a, ref);
|
||||
if (!ptr)
|
||||
return 0;
|
||||
return spl_ir_builder_mem_load(a->ir, node_ir(a, n), ptr);
|
||||
if (ptr)
|
||||
return spl_ir_builder_mem_load(a->ir, node_ir(a, n), ptr);
|
||||
return ast2ir_field_from_value(a, n);
|
||||
}
|
||||
case SPL_AST_EXPR_INDEX: {
|
||||
spl_ir_node_ref_t ptr = emit_lvalue(a, ref);
|
||||
|
||||
+1
-2
@@ -411,7 +411,7 @@ spl_tok_vec_t spl_lex(const char *source, const char *fname) {
|
||||
}
|
||||
|
||||
/* Three-char operators first */
|
||||
TRY_OP3('<', '-', '>', TOK_ARROW_BOTH, TOK_RIGHT_ARROW, TOK_LT)
|
||||
TRY_OP3('<', '-', '>', TOK_ARROW_BOTH, TOK_LEFT_ARROW, TOK_LT)
|
||||
TRY_OP3('<', '=', '>', TOK_FAT_ARROW_BOTH, TOK_LE, TOK_LT)
|
||||
TRY_OP3('<', '<', '=', TOK_ASSIGN_L_SH, TOK_L_SH, TOK_LT)
|
||||
TRY_OP3('>', '>', '=', TOK_ASSIGN_R_SH, TOK_R_SH, TOK_GT)
|
||||
@@ -433,7 +433,6 @@ spl_tok_vec_t spl_lex(const char *source, const char *fname) {
|
||||
TRY_OP2('&', '=', TOK_ASSIGN_AND, TOK_AND)
|
||||
TRY_OP2('|', '=', TOK_ASSIGN_OR, TOK_OR)
|
||||
TRY_OP2('^', '=', TOK_ASSIGN_XOR, TOK_XOR)
|
||||
TRY_OP2('<', '-', TOK_LEFT_ARROW, TOK_LT)
|
||||
TRY_OP2('-', '>', TOK_RIGHT_ARROW, TOK_SUB)
|
||||
TRY_OP2(':', '=', TOK_COLON_ASSIGN, TOK_COLON)
|
||||
|
||||
|
||||
@@ -2024,6 +2024,20 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
||||
if (!obj)
|
||||
return 0;
|
||||
|
||||
/* 限定枚举变体 Type.Variant:基对象是聚合类型名且类型为 enum。 */
|
||||
spl_ast_node_t *objn = spl_ast_node(sema->ast, n->field.obj);
|
||||
if (objn && objn->kind == SPL_AST_EXPR_IDENT) {
|
||||
spl_def_node_t *od = spl_def_node(sema->type, objn->resolved_def_id);
|
||||
if (od && od->kind == SPL_DEF_AGG && obj->kind == SPL_LANG_TYPE_ENUM) {
|
||||
spl_type_id_t eir = spl_lang_type_get_ir_type(sema->type, obj_tid);
|
||||
usize vidx = 0;
|
||||
if (eir && spl_type_agg_member_idx(&sema->type->ir, eir, n->field.field, &vidx)) {
|
||||
n->resolved_lang_tid = obj_tid;
|
||||
return obj_tid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
spl_intrin_t in = spl_intrin_lookup_field(obj->kind, n->field.field);
|
||||
if (in != SPL_INTRIN_NONE) {
|
||||
spl_lang_type_id_t t = sema_intrin_field(sema, n, in);
|
||||
|
||||
Reference in new issue
Block a user