stage1 指针计算类型的错误修复 as运算符优先级的修改 ir2vm的bug修复

This commit is contained in:
zzy committed 2026-09-15 21:24:58 +08:00
1 parent 06f3884c30
commit 09d05e3a34
10 files changed
+191 -60

No files matched your search

+18 -8
View File
@@ -148,6 +148,7 @@ static spl_ast_node_ref_t parse_param_decl_impl(parser_t *p);
static spl_ast_node_ref_t parse_var_pattern(parser_t *p);
static spl_ast_node_ref_t parse_match_pattern(parser_t *p);
static spl_ast_node_ref_t parse_cast(parser_t *p);
static spl_ast_node_ref_t parse_prefix(parser_t *p);
static spl_ast_node_ref_t parse_postfix(parser_t *p);
static spl_ast_node_ref_t parse_primary(parser_t *p);
@@ -1215,7 +1216,7 @@ static spl_binary_op_t token_to_binary_op(spl_tok_type_t tt) {
}
static spl_ast_node_ref_t parse_expr_prec(parser_t *p, int min_prec) {
spl_ast_node_ref_t left = parse_prefix(p);
spl_ast_node_ref_t left = parse_cast(p);
if (p->failed)
return left;
@@ -1259,6 +1260,22 @@ static spl_ast_node_ref_t parse_expr(parser_t *p) {
return parse_expr_prec(p, 1); // 最低优先级
}
static spl_ast_node_ref_t parse_cast(parser_t *p) {
spl_ast_node_ref_t expr = parse_prefix(p);
while (!p->failed) {
const spl_tok_t *t = peek(p);
if (!t || t->type != KW_AS || p->stop_as)
break;
advance(p);
spl_ast_node_ref_t type = parse_type_expr(p);
spl_ast_node_ref_t ref = new_node(p, SPL_AST_EXPR_CAST, t);
node_at(p->ast, ref)->cast.expr = expr;
node_at(p->ast, ref)->cast.type = type;
expr = ref;
}
return expr;
}
static spl_ast_node_ref_t parse_prefix(parser_t *p) {
const spl_tok_t *t = peek(p);
if (!t)
@@ -1393,13 +1410,6 @@ static spl_ast_node_ref_t parse_postfix(parser_t *p) {
node_at(p->ast, ref)->index.index = begin;
expr = ref;
}
} else if (t->type == KW_AS && !p->stop_as) {
advance(p);
spl_ast_node_ref_t type = parse_type_expr(p);
spl_ast_node_ref_t ref = new_node(p, SPL_AST_EXPR_CAST, t);
node_at(p->ast, ref)->cast.expr = expr;
node_at(p->ast, ref)->cast.type = type;
expr = ref;
} else {
break;
}
+15 -7
View File
@@ -152,7 +152,12 @@ static uint8_t vm_kind_of(spl_ir2vm_t *ctx, spl_type_id_t tid) {
}
}
static spl_type_id_t ir_result_tid(const spl_ir_node_t *n) {
/* 计算 IR 节点的"值类型"。
* 语义区分:
* mem.offset(elem_t, ptr, off) → 结果类型 *elem_t
* mem.field(agg_t, base, idx) → 结果类型 *field_t
* 这两个 builder 的 .tid 存的是 pointee / aggregate,不能直接当结果类型用。 */
static spl_type_id_t ir_result_tid(spl_ir2vm_t *ctx, const spl_ir_node_t *n) {
switch (n->kind) {
case SPL_IR_ARITH_ADD:
case SPL_IR_ARITH_SUB:
@@ -194,9 +199,12 @@ static spl_type_id_t ir_result_tid(const spl_ir_node_t *n) {
case SPL_IR_MEM_LOAD:
return n->mem_load.tid;
case SPL_IR_MEM_OFFSET:
return n->mem_offset.tid;
case SPL_IR_MEM_FIELD_PTR:
return n->mem_field_ptr.tid;
return spl_type_builder_ptr((spl_type_t *)ctx->type, n->mem_offset.tid);
case SPL_IR_MEM_FIELD_PTR: {
spl_type_id_t field =
ir_agg_field_tid(ctx, n->mem_field_ptr.tid, n->mem_field_ptr.field_idx);
return spl_type_builder_ptr((spl_type_t *)ctx->type, field);
}
case SPL_IR_TYPE_CONST:
return n->type_const.tid;
case SPL_IR_TYPE_BITSIZEOF:
@@ -304,7 +312,7 @@ static void frame_build(frame_layout_t *fl, spl_ir2vm_t *ctx, spl_ir_func_ref_t
for (usize i = 1; i < n; ++i) {
const spl_ir_node_t *node = &vec_at(f->nodes, i);
if (ir_result_tid(node)) {
if (ir_result_tid(ctx, node)) {
vec_at(fl->slots, i).result_off = off;
off += sizeof(spl_vm_val_t);
}
@@ -786,7 +794,7 @@ static void cg_control(cgen_t *cg, usize ref, const spl_ir_node_t *n) {
for (usize i = 0; i < nargs; ++i) {
spl_ir_node_ref_t pref = vec_at(n->control_call.params, i);
const spl_ir_node_t *pn = &vec_at(cg->irf->nodes, pref);
spl_type_id_t ptid = ir_result_tid(pn);
spl_type_id_t ptid = ir_result_tid(ctx, pn);
uint8_t pk = vm_kind_of(ctx, ptid);
cg_load_slot(cg, pref, pk);
}
@@ -802,7 +810,7 @@ static void cg_control(cgen_t *cg, usize ref, const spl_ir_node_t *n) {
for (usize i = 0; i < nargs; ++i) {
spl_ir_node_ref_t pref = vec_at(n->control_call.params, i);
const spl_ir_node_t *pn = &vec_at(cg->irf->nodes, pref);
spl_type_id_t ptid = ir_result_tid(pn);
spl_type_id_t ptid = ir_result_tid(ctx, pn);
uint8_t pk = vm_kind_of(ctx, ptid);
cg_load_slot(cg, pref, pk);
}
+6 -3
View File
@@ -651,9 +651,11 @@ static spl_lang_type_id_t sema_coerce(spl_sema_t *sema, spl_ast_node_ref_t ref,
switch (n->kind) {
case SPL_AST_EXPR_UNARY: {
/* & 与 .* 的结果类型由操作数决定,不能靠 expected 反向定型 */
/* ADDRESS / DEREF 的结果类型由操作数决定,不能用 expected 反向定型。
* 但不能直接 return ——— 那会绕过 expected 兼容性检查。
* 走 break 落到兜底:infer 后做 is_subtype / comptime 判定。 */
if (n->unary.op == SPL_UNARY_OP_ADDRESS || n->unary.op == SPL_UNARY_OP_DEREF)
return sema_infer(sema, ref);
break;
if (!sema_coerce(sema, n->unary.operand, expected))
return 0;
n->resolved_lang_tid = expected;
@@ -1213,7 +1215,8 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
for (usize i = 0; i < nargs && i < fixed; ++i) {
spl_lang_type_id_t pt =
vec_at(spl_lang_type_node(sema->type, callee_tid)->extra.fn.params, i);
sema_coerce(sema, vec_at(n->call.args, i), pt);
if (!sema_coerce(sema, vec_at(n->call.args, i), pt))
return 0;
}
/* varargs:默认提升到 isize */
if (has_varargs) {