stage2 修复大量AI生成的风格问题 stage1 修复对于vm abi的错误生成

This commit is contained in:
zzy committed 2026-10-03 15:05:55 +08:00
1 parent 0e38858785
commit 76f980654c
40 files changed
+619 -938

No files matched your search

+111 -144
View File
@@ -1,11 +1,7 @@
// Expect retcode = 0
// 语义分析(移植自 stage1/spl_sema.c)。持有语言类型表 / 作用域树 / 属性表 /
// comptime 接口;AST 与诊断是借用。阶段:collect_names -> collect_type_unpacks
// -> 模块根聚合 -> collect_types -> collect_signatures -> infer。
//
// 与 stage1 的差异:诊断消息从简(不逐字复刻);类型系统/def/scope/attr/intrin
// 全部走 stage2 模块;comptime 只走 eval seam(本轮不求值,返回 NotConst)。
// 语义分析:名字/类型/def 解析与推断。持有类型表、作用域树、属性表;AST 与诊断
// 为借用。comptime 求值经 eval seam 注入。
type .{ .Error, .Status } = @import("utils/error.spl");
type .{ .Vec } = @import("utils/vec.spl");
@@ -34,7 +30,7 @@ type .{ .Lexer } = @import("./lexer.spl");
type .{ .Parser } = @import("./parser.spl");
type .{ .set_new, .set_add, .set_drop } = @import("utils/source.spl");
// 模块加载接口(seam):驱动提供;本轮可为 null。
// 模块加载接口(seam):由驱动提供;可为 null。
type LoadResult = enum {
Ok: *Ast,
Missing,
@@ -66,7 +62,6 @@ type SemaResult = enum {
Err: Error,
}
// ---- 小工具 ----
fn list_at(v: Vec, i: usize): usize {
if i >= v.len { ret 0; }
@@ -74,17 +69,11 @@ fn list_at(v: Vec, i: usize): usize {
}
fn push_u(v: *Vec, x: usize) {
match Vec.push(v, &x as *u8) {
.Ok => {},
.Err(error) => {},
}
Vec.push(v, &x as *u8);
}
fn push_view(v: *Vec, x: ByteView) {
match Vec.push(v, &x as *u8) {
.Ok => {},
.Err(error) => {},
}
Vec.push(v, &x as *u8);
}
fn ref_vec(): Vec {
@@ -138,7 +127,7 @@ fn lang_from_ir(self: *Sema, ir: usize): usize {
while i < self.types.lang_table.len {
var e = LangType.lang_node(&self.types, i);
if e != null && e.ir_type_id == ir {
match Map.put(&self.ir_to_lang, &ir as *u8, &i as *u8) { .Ok => {}, .Err(error) => {} }
Map.put(&self.ir_to_lang, &ir as *u8, &i as *u8);
ret i;
}
i = i + 1;
@@ -163,7 +152,6 @@ fn def_state_is(d: *DefNode, want: DeclState): bool {
ret @enum2int(d.state) == @enum2int(want);
}
// ---- 诊断(消息从简;类型名走 dump 到缓冲)----
fn diag(self: *Sema, span: Span, code: Code, msg: []u8) {
Diag.err(self.diag, span, code, msg);
@@ -172,15 +160,15 @@ fn diag(self: *Sema, span: Span, code: Code, msg: []u8) {
fn diag_name(self: *Sema, span: Span, code: Code, prefix: []u8, name: ByteView) {
var b = ByteBuffer.new();
defer { ByteBuffer.drop(&b); }
match ByteBuffer.append(&b, prefix) { .Ok => {}, .Err(e) => {} }
match ByteBuffer.append(&b, ByteView.as_slice(name)) { .Ok => {}, .Err(e) => {} }
ByteBuffer.append(&b, prefix);
ByteBuffer.append(&b, ByteView.as_slice(name));
Diag.err(self.diag, span, code, ByteBuffer.as_slice(b));
}
fn diag_ty(self: *Sema, span: Span, code: Code, prefix: []u8, tid: usize) {
var b = ByteBuffer.new();
defer { ByteBuffer.drop(&b); }
match ByteBuffer.append(&b, prefix) { .Ok => {}, .Err(e) => {} }
ByteBuffer.append(&b, prefix);
LangType.dump(&self.types, tid, &b);
Diag.err(self.diag, span, code, ByteBuffer.as_slice(b));
}
@@ -188,14 +176,13 @@ fn diag_ty(self: *Sema, span: Span, code: Code, prefix: []u8, tid: usize) {
fn diag_ty2(self: *Sema, span: Span, code: Code, prefix: []u8, a: usize, b: usize) {
var buf = ByteBuffer.new();
defer { ByteBuffer.drop(&buf); }
match ByteBuffer.append(&buf, prefix) { .Ok => {}, .Err(e) => {} }
ByteBuffer.append(&buf, prefix);
LangType.dump(&self.types, a, &buf);
match ByteBuffer.append(&buf, " vs ") { .Ok => {}, .Err(e) => {} }
ByteBuffer.append(&buf, " vs ");
LangType.dump(&self.types, b, &buf);
Diag.err(self.diag, span, code, ByteBuffer.as_slice(buf));
}
// ---- 生命周期 ----
fn new(ast: *Ast, diag: *Diag): SemaResult {
var types: LangType = undefined;
@@ -244,7 +231,6 @@ fn drop(self: *Sema) {
LangType.drop(&self.types);
}
// ---- 作用域 ----
fn push_scope(self: *Sema) {
var id = Scope.alloc(&self.scope);
@@ -258,7 +244,6 @@ fn pop_scope(self: *Sema) {
}
}
// ---- 属性 ----
fn node_attr_raw(self: *Sema, n: *Node, raw: Vec) {
var i: usize = 0;
@@ -312,17 +297,17 @@ fn resolve_attr_item(self: *Sema, a: *Node): usize {
match arg.body {
.ExprIdent(e) => {
var av: AttrArg = .Str(e.name);
match Vec.push(&args, &av as *u8) { .Ok => {}, .Err(er) => {} }
Vec.push(&args, &av as *u8);
},
.ExprStringLit(sl) => {
var av: AttrArg = .Str(sl.data);
match Vec.push(&args, &av as *u8) { .Ok => {}, .Err(er) => {} }
Vec.push(&args, &av as *u8);
},
.ExprIntLit(iv) => {
var num: i64 = 0;
match BigInt.to_i64(&num, iv.value) { .Ok => {}, .Err(er) => {} }
BigInt.to_i64(&num, iv.value);
var av: AttrArg = .Int(num);
match Vec.push(&args, &av as *u8) { .Ok => {}, .Err(er) => {} }
Vec.push(&args, &av as *u8);
},
_ => {
diag(self, arg.span, .UnknownAttr, "unsupported attribute arg");
@@ -348,7 +333,6 @@ fn resolve_attrs(self: *Sema, n: *Node) {
}
}
// ---- 聚合构建 ----
fn build_aggregate(self: *Sema, te: *Node, owner_def_id: usize): usize {
var kind_name = ByteView.empty();
@@ -403,7 +387,7 @@ fn build_aggregate(self: *Sema, te: *Node, owner_def_id: usize): usize {
if md.type_expr != 0 { mtid = infer(self, md.type_expr); }
var mm = Member { .name = md.name, .type_id = ir_of(self, mtid),
.ast_node_ref = mref };
match Vec.push(&members, &mm as *u8) { .Ok => {}, .Err(er) => {} }
Vec.push(&members, &mm as *u8);
},
.FnDecl(fd) => {
var fn_def = mn.resolved_def_id;
@@ -415,7 +399,7 @@ fn build_aggregate(self: *Sema, te: *Node, owner_def_id: usize): usize {
var fn_d = def_node(self, fn_def);
if fn_d != null { fn_d.owner_def = owner_def_id; }
var meth = LangMethod { .name = fd.name, .def_id = fn_def };
match Vec.push(&methods, &meth as *u8) { .Ok => {}, .Err(er) => {} }
Vec.push(&methods, &meth as *u8);
},
.TypeDecl(td) => {
var tpat = node(self, td.pattern);
@@ -431,7 +415,7 @@ fn build_aggregate(self: *Sema, te: *Node, owner_def_id: usize): usize {
mn.resolved_def_id = tdef;
}
var meth = LangMethod { .name = tname, .def_id = tdef };
match Vec.push(&methods, &meth as *u8) { .Ok => {}, .Err(er) => {} }
Vec.push(&methods, &meth as *u8);
}
},
_ => {},
@@ -443,16 +427,21 @@ fn build_aggregate(self: *Sema, te: *Node, owner_def_id: usize): usize {
self.current_aggregate_lang = saved;
// IR 节点
if @enum2int(lk) == @enum2int(LangKind.Enum) {
var tag_ir = TypeTable.make_int(&self.types.ir, 32, true);
tk = .Enum(.{ .mode = .Auto, .fixed_align_bits = 0, .tag_type = tag_ir,
.variants = members });
} else if @enum2int(lk) == @enum2int(LangKind.Union) {
tk = .Union(.{ .mode = .Auto, .fixed_align_bits = 0, .tag_type = 0, .variants = members });
} else if @enum2int(lk) == @enum2int(LangKind.Shape) {
tk = .Shape(.{ .mode = .Auto, .fixed_align_bits = 0, .tag_type = 0, .variants = members });
} else {
tk = .Struct(.{ .mode = .Auto, .fixed_align_bits = 0, .tag_type = 0, .variants = members });
match lk {
.Enum => {
var tag_ir = TypeTable.make_int(&self.types.ir, 32, true);
tk = .Enum(.{ .mode = .Auto, .fixed_align_bits = 0, .tag_type = tag_ir,
.variants = members });
},
.Union => {
tk = .Union(.{ .mode = .Auto, .fixed_align_bits = 0, .tag_type = 0, .variants = members });
},
.Shape => {
tk = .Shape(.{ .mode = .Auto, .fixed_align_bits = 0, .tag_type = 0, .variants = members });
},
_ => {
tk = .Struct(.{ .mode = .Auto, .fixed_align_bits = 0, .tag_type = 0, .variants = members });
},
}
TypeTable.define(&self.types.ir, agg_ir, &tk);
@@ -501,7 +490,7 @@ fn build_container_aggregate(self: *Sema, n: *Node, owner_def_id: usize): usize
if md.type_expr != 0 { mtid = infer(self, md.type_expr); }
var mm = Member { .name = md.name, .type_id = ir_of(self, mtid),
.ast_node_ref = dref };
match Vec.push(&members, &mm as *u8) { .Ok => {}, .Err(er) => {} }
Vec.push(&members, &mm as *u8);
},
.FnDecl(fd) => {
var fn_def = d.resolved_def_id;
@@ -509,7 +498,7 @@ fn build_container_aggregate(self: *Sema, n: *Node, owner_def_id: usize): usize
var fn_d = def_node(self, fn_def);
if fn_d != null { fn_d.owner_def = owner_def_id; }
var meth = LangMethod { .name = fd.name, .def_id = fn_def };
match Vec.push(&methods, &meth as *u8) { .Ok => {}, .Err(er) => {} }
Vec.push(&methods, &meth as *u8);
}
},
.TypeDecl(td) => {
@@ -518,7 +507,7 @@ fn build_container_aggregate(self: *Sema, n: *Node, owner_def_id: usize): usize
var tpat = node(self, td.pattern);
if tpat != null && is_pattern_ident(tpat) {
var meth = LangMethod { .name = pattern_name(tpat), .def_id = tdef };
match Vec.push(&methods, &meth as *u8) { .Ok => {}, .Err(er) => {} }
Vec.push(&methods, &meth as *u8);
}
}
},
@@ -550,7 +539,7 @@ fn container_var_method(self: *Sema, pat_ref: usize, methods: *Vec) {
var vdef = pat.resolved_def_id;
if vdef == 0 { ret; }
var meth = LangMethod { .name = pattern_name(pat), .def_id = vdef };
match Vec.push(methods, &meth as *u8) { .Ok => {}, .Err(er) => {} }
Vec.push(methods, &meth as *u8);
}
fn is_pattern_ident(n: *Node): bool {
@@ -593,7 +582,6 @@ fn pattern_name(pat: *Node): ByteView {
}
}
// ---- @import ----
fn sema_import(self: *Sema, n: *Node, args: Vec): usize {
if self.loader == null {
@@ -666,7 +654,6 @@ fn sema_import(self: *Sema, n: *Node, args: Vec): usize {
ret t;
}
// ---- 声明求值 ----
fn eval_decl(self: *Sema, def_id: usize): usize {
var d = def_node(self, def_id);
@@ -809,7 +796,7 @@ fn collect_names(self: *Sema, ref: usize) {
n.resolved_def_id = file_def;
var file_sym = Symbol { .name = ByteView.from_slice("$file"), .kind = .Type,
.node = file_def };
ignore_bool(Scope.insert(&self.scope, mod_scope, file_sym));
Scope.insert(&self.scope, mod_scope, file_sym);
var i: usize = 0;
while i < cm.declarations.len {
@@ -887,7 +874,7 @@ fn collect_types(self: *Sema, ref: usize) {
var pat = node(self, td.pattern);
if pat != null && is_pattern_ident(pat) &&
d.resolved_def_id != 0 {
ignore_usize(eval_decl(self, d.resolved_def_id));
eval_decl(self, d.resolved_def_id);
}
},
_ => {},
@@ -910,7 +897,7 @@ fn collect_signatures(self: *Sema) {
if d != null && d.owner == (self.ast as *any) &&
@enum2int(d.kind) == @enum2int(DefKind.Fn) &&
def_state_is(d, .Unresolved) {
ignore_usize(eval_decl(self, i));
eval_decl(self, i);
}
i = i + 1;
}
@@ -945,7 +932,6 @@ fn collect_type_unpacks(self: *Sema, ref: usize) {
}
}
// ---- 类型上下文(intrinsic 参数)----
fn infer_type_context(self: *Sema, ref: usize): usize {
var n = node(self, ref);
@@ -1024,7 +1010,6 @@ fn infer_type_context(self: *Sema, ref: usize): usize {
ret 0;
}
// ---- intrinsic 调用 ----
fn punct_is(op: Punct, want: Punct): bool {
ret @enum2int(op) == @enum2int(want);
@@ -1091,8 +1076,8 @@ fn intrin_call(self: *Sema, n: *Node, in: Intrin, args: Vec): usize {
}
if intrin_is(in, .Assert) {
var bt = make_bool(self);
ignore_usize(coerce(self, list_at(args, 0), bt));
if nargs == 2 { ignore_usize(infer(self, list_at(args, 1))); }
coerce(self, list_at(args, 0), bt);
if nargs == 2 { infer(self, list_at(args, 1)); }
ret make_unit(self);
}
if intrin_is(in, .IntCast) || intrin_is(in, .Truncate) || intrin_is(in, .BitCast) ||
@@ -1113,7 +1098,7 @@ fn intrin_call(self: *Sema, n: *Node, in: Intrin, args: Vec): usize {
ret dst;
}
if intrin_is(in, .Bool2Int) || intrin_is(in, .Ptr2Int) {
ignore_usize(infer(self, list_at(args, 0)));
infer(self, list_at(args, 0));
if nargs >= 2 {
var dst = infer(self, list_at(args, 1));
if dst == 0 { ret 0; }
@@ -1185,7 +1170,6 @@ fn intrin_field(self: *Sema, n: *Node, in: Intrin): usize {
ret 0;
}
// ---- 块 / 模式 / 解包 ----
fn block_body(self: *Sema, n: *Node, expected: usize): usize {
var stmts = ref_vec();
@@ -1200,7 +1184,7 @@ fn block_body(self: *Sema, n: *Node, expected: usize): usize {
push_scope(self);
var i: usize = 0;
while i < stmts.len {
ignore_usize(infer(self, list_at(stmts, i)));
infer(self, list_at(stmts, i));
i = i + 1;
}
var r: usize = 0;
@@ -1243,7 +1227,7 @@ fn bind_pattern(self: *Sema, pat_ref: usize, matched_tid: usize) {
if pattern_is_literal(pat) {
var lt = infer(self, pat_ref);
if lt != 0 && matched_tid != 0 {
ignore_usize(coerce(self, pat_ref, matched_tid));
coerce(self, pat_ref, matched_tid);
}
ret;
}
@@ -1404,14 +1388,10 @@ fn type_unpack_one(self: *Sema, pat: *Node, name: ByteView, src_lang: usize) {
var d = def_node(self, m.def_id);
var k: SymbolKind = .Var;
if d != null {
if @enum2int(d.kind) == @enum2int(DefKind.Fn) {
k = .Fn;
} else if @enum2int(d.kind) == @enum2int(DefKind.Agg) ||
@enum2int(d.kind) == @enum2int(DefKind.Scalar) ||
@enum2int(d.kind) == @enum2int(DefKind.Distinct) ||
@enum2int(d.kind) == @enum2int(DefKind.Alias) ||
@enum2int(d.kind) == @enum2int(DefKind.Builtin) {
k = .Type;
match d.kind {
.Fn => { k = .Fn; },
.Agg, .Scalar, .Distinct, .Alias, .Builtin => { k = .Type; },
_ => {},
}
}
var sym = Symbol { .name = name, .kind = k, .node = m.def_id };
@@ -1485,7 +1465,6 @@ fn do_type_unpack(self: *Sema, decl: *Node, pat: *Node, type_expr_ref: usize) {
type_unpack_walk(self, pat, src_lang);
}
// ---- var/const 推断 ----
fn var_body(self: *Sema, n: *Node): usize {
var decl_tid: usize = 0;
@@ -1531,7 +1510,6 @@ fn for_elem_type(self: *Sema, lang_tid: usize): usize {
ret elem_of_lang(e.*);
}
// ---- 驱动 ----
fn run_module(self: *Sema, module_ref: usize) {
if self.ast == null || module_ref == 0 { ret; }
@@ -1556,7 +1534,7 @@ fn run_module(self: *Sema, module_ref: usize) {
collect_types(self, module_ref);
collect_signatures(self);
ignore_usize(infer(self, module_ref));
infer(self, module_ref);
self.current_aggregate_lang = saved_agg;
self.scope.current_scope = saved_scope;
@@ -1582,8 +1560,6 @@ fn method_at(v: *Vec, i: usize): *LangMethod {
ret null;
}
fn ignore_usize(x: usize) {}
fn ignore_bool(x: bool) {}
// ============================================================
// infer / coerce:下面两块是主体(step 2 填入)。
@@ -1652,7 +1628,13 @@ fn agg_variants_copy(self: *Sema, agg_ir: usize): Vec {
ret out;
}
// ---- coerce ----
// 二元运算两侧都 coerce 到 expected;成功返回 expected,失败返回 0。
fn coerce_binop_same(self: *Sema, left: usize, right: usize, expected: usize): usize {
if coerce(self, left, expected) == 0 { ret 0; }
if coerce(self, right, expected) == 0 { ret 0; }
ret expected;
}
fn coerce(self: *Sema, ref: usize, expected: usize): usize {
if ref == 0 || expected == 0 { ret 0; }
@@ -1709,8 +1691,8 @@ fn coerce(self: *Sema, ref: usize, expected: usize): usize {
diag_ty2(self, n.span, .TypeMismatch, "comparison mismatch: ", lt2, rt2);
ret 0;
}
ignore_usize(coerce(self, x.left, common));
ignore_usize(coerce(self, x.right, common));
coerce(self, x.left, common);
coerce(self, x.right, common);
result = make_bool(self);
} else if is_addsub(op) {
var en = lang_of(self, expected);
@@ -1729,19 +1711,13 @@ fn coerce(self: *Sema, ref: usize, expected: usize): usize {
}
result = expected;
} else {
if coerce(self, x.left, expected) == 0 { ret 0; }
if coerce(self, x.right, expected) == 0 { ret 0; }
result = expected;
result = coerce_binop_same(self, x.left, x.right, expected);
}
} else {
if coerce(self, x.left, expected) == 0 { ret 0; }
if coerce(self, x.right, expected) == 0 { ret 0; }
result = expected;
result = coerce_binop_same(self, x.left, x.right, expected);
}
} else {
if coerce(self, x.left, expected) == 0 { ret 0; }
if coerce(self, x.right, expected) == 0 { ret 0; }
result = expected;
result = coerce_binop_same(self, x.left, x.right, expected);
}
},
.ExprArrayLit(&x) => {
@@ -1848,16 +1824,16 @@ fn coerce(self: *Sema, ref: usize, expected: usize): usize {
.ExprIf(&x) => {
handled = true;
var bt = make_bool(self);
ignore_usize(coerce(self, x.cond, bt));
if x.then_block != 0 { ignore_usize(coerce(self, x.then_block, expected)); }
if x.else_branch != 0 { ignore_usize(coerce(self, x.else_branch, expected)); }
coerce(self, x.cond, bt);
if x.then_block != 0 { coerce(self, x.then_block, expected); }
if x.else_branch != 0 { coerce(self, x.else_branch, expected); }
result = expected;
},
.ExprLoop(&x) => {
handled = true;
var saved = self.current_loop_break_tid;
self.current_loop_break_tid = expected;
ignore_usize(infer(self, ref));
infer(self, ref);
self.current_loop_break_tid = saved;
result = expected;
},
@@ -1920,7 +1896,6 @@ fn kind_is_body_struct_init(n: *Node): bool {
ret false;
}
// ---- infer ----
fn infer(self: *Sema, ref: usize): usize {
if ref == 0 { ret 0; }
@@ -2004,7 +1979,7 @@ fn infer(self: *Sema, ref: usize): usize {
}
if punct_is(x.op, .Not) {
var bt = make_bool(self);
ignore_usize(coerce(self, x.operand, bt));
coerce(self, x.operand, bt);
n.resolved_lang_tid = bt;
ret bt;
}
@@ -2095,7 +2070,7 @@ fn infer(self: *Sema, ref: usize): usize {
},
.ExprIf(&x) => {
var bt = make_bool(self);
ignore_usize(coerce(self, x.cond, bt));
coerce(self, x.cond, bt);
var then_t = if x.then_block != 0 { infer(self, x.then_block) } else { 0 };
var else_t = if x.else_branch != 0 { infer(self, x.else_branch) } else { 0 };
var result: usize = 0;
@@ -2114,24 +2089,24 @@ fn infer(self: *Sema, ref: usize): usize {
var vd = node(self, x.var_decl);
if vd == null { ret 0; }
push_scope(self);
ignore_usize(var_body(self, vd));
if x.then_block != 0 { ignore_usize(infer(self, x.then_block)); }
var_body(self, vd);
if x.then_block != 0 { infer(self, x.then_block); }
pop_scope(self);
if x.else_branch != 0 { ignore_usize(infer(self, x.else_branch)); }
if x.else_branch != 0 { infer(self, x.else_branch); }
ret 0;
},
.ExprWhile(&x) => {
push_view(&self.label_stack, label_name(self, x.label));
var bt = make_bool(self);
ignore_usize(coerce(self, x.cond, bt));
if x.body != 0 { ignore_usize(infer(self, x.body)); }
if x.else_branch != 0 { ignore_usize(infer(self, x.else_branch)); }
coerce(self, x.cond, bt);
if x.body != 0 { infer(self, x.body); }
if x.else_branch != 0 { infer(self, x.else_branch); }
pop_label(self);
ret 0;
},
.ExprLoop(&x) => {
push_view(&self.label_stack, label_name(self, x.label));
if x.body != 0 { ignore_usize(infer(self, x.body)); }
if x.body != 0 { infer(self, x.body); }
pop_label(self);
ret 0;
},
@@ -2155,7 +2130,7 @@ fn infer(self: *Sema, ref: usize): usize {
}
push_scope(self);
bind_pattern(self, pat, matched);
if body != 0 { ignore_usize(infer(self, body)); }
if body != 0 { infer(self, body); }
pop_scope(self);
}
i = i + 1;
@@ -2264,7 +2239,7 @@ fn infer(self: *Sema, ref: usize): usize {
.ContainerMembers(&x) => {
var i: usize = 0;
while i < x.declarations.len {
ignore_usize(infer(self, list_at(x.declarations, i)));
infer(self, list_at(x.declarations, i));
i = i + 1;
}
ret 0;
@@ -2295,23 +2270,23 @@ fn infer(self: *Sema, ref: usize): usize {
ret infer_continue(self, n, x.label);
},
.StatementDefer(&x) => {
if x.body != 0 { ignore_usize(infer(self, x.body)); }
if x.body != 0 { infer(self, x.body); }
ret 0;
},
.StatementComptime(&x) => {
if x.body != 0 { ignore_usize(infer(self, x.body)); }
if x.body != 0 { infer(self, x.body); }
ret 0;
},
.StatementDecl(&x) => {
if x.decl != 0 { ignore_usize(infer(self, x.decl)); }
if x.decl != 0 { infer(self, x.decl); }
ret 0;
},
.StatementExpr(&x) => {
if x.expr != 0 { ignore_usize(infer(self, x.expr)); }
if x.expr != 0 { infer(self, x.expr); }
ret 0;
},
.TopLevelBlock(&x) => {
if x.block != 0 { ignore_usize(infer(self, x.block)); }
if x.block != 0 { infer(self, x.block); }
ret 0;
},
_ => { ret 0; },
@@ -2326,24 +2301,21 @@ fn kind_is_body_ident(n: *Node): bool {
fn pop_label(self: *Sema) {
var out = ByteView.empty();
match Vec.pop(&self.label_stack, &out as *u8) {
.Ok => {},
.Err(error) => {},
}
Vec.pop(&self.label_stack, &out as *u8);
}
fn infer_binary(self: *Sema, n: *Node, op: Punct, left: usize, right: usize): usize {
if punct_is(op, .Assign) || is_assign_arith(op) {
var lt = infer(self, left);
if lt == 0 { ret 0; }
ignore_usize(coerce(self, right, lt));
coerce(self, right, lt);
n.resolved_lang_tid = lt;
ret lt;
}
if punct_is(op, .OrOr) || punct_is(op, .AndAnd) {
var bt = make_bool(self);
ignore_usize(coerce(self, left, bt));
ignore_usize(coerce(self, right, bt));
coerce(self, left, bt);
coerce(self, right, bt);
n.resolved_lang_tid = bt;
ret bt;
}
@@ -2356,15 +2328,15 @@ fn infer_binary(self: *Sema, n: *Node, op: Punct, left: usize, right: usize): us
diag_ty2(self, n.span, .TypeMismatch, "comparison mismatch: ", lt, rt);
ret 0;
}
ignore_usize(coerce(self, left, common));
ignore_usize(coerce(self, right, common));
coerce(self, left, common);
coerce(self, right, common);
var b = make_bool(self);
n.resolved_lang_tid = b;
ret b;
}
if punct_is(op, .Range) {
ignore_usize(infer(self, left));
ignore_usize(infer(self, right));
infer(self, left);
infer(self, right);
var i64t = LangType.make_int(&self.types, 64, true);
var r = LangType.make_range(&self.types, i64t);
n.resolved_lang_tid = r;
@@ -2377,7 +2349,7 @@ fn infer_binary(self: *Sema, n: *Node, op: Punct, left: usize, right: usize): us
diag(self, n.span, .TypeMismatch, "shift requires integer operands");
ret 0;
}
ignore_usize(infer(self, right));
infer(self, right);
n.resolved_lang_tid = lt;
ret lt;
}
@@ -2387,7 +2359,7 @@ fn infer_binary(self: *Sema, n: *Node, op: Punct, left: usize, right: usize): us
if kind_is(self, lt2, .Ptr) && kind_is(self, rt2, .Int) && is_addsub(op) {
if int_bits(self, rt2) == 0 {
var it = make_isize(self);
ignore_usize(coerce(self, right, it));
coerce(self, right, it);
}
n.resolved_lang_tid = lt2;
ret lt2;
@@ -2397,8 +2369,8 @@ fn infer_binary(self: *Sema, n: *Node, op: Punct, left: usize, right: usize): us
diag_ty2(self, n.span, .TypeMismatch, "operand types cannot be joined: ", lt2, rt2);
ret 0;
}
ignore_usize(coerce(self, left, common2));
ignore_usize(coerce(self, right, common2));
coerce(self, left, common2);
coerce(self, right, common2);
n.resolved_lang_tid = common2;
ret common2;
}
@@ -2530,7 +2502,7 @@ fn infer_field(self: *Sema, n: *Node, obj_ref: usize, field_name: ByteView): usi
fn infer_index(self: *Sema, n: *Node, obj_ref: usize, index_ref: usize): usize {
var obj_tid = infer(self, obj_ref);
ignore_usize(infer(self, index_ref));
infer(self, index_ref);
var obj = lang_of(self, obj_tid);
if obj == null { ret 0; }
var elem: usize = 0;
@@ -2546,7 +2518,7 @@ fn infer_index(self: *Sema, n: *Node, obj_ref: usize, index_ref: usize): usize {
var iv: i64 = -1;
match idx_node.body {
.ExprIntLit(lit) => {
match BigInt.to_i64(&iv, lit.value) { .Ok => {}, .Err(e) => {} }
BigInt.to_i64(&iv, lit.value);
},
_ => {},
}
@@ -2567,8 +2539,8 @@ fn infer_index(self: *Sema, n: *Node, obj_ref: usize, index_ref: usize): usize {
fn infer_slice(self: *Sema, n: *Node, obj_ref: usize, begin_ref: usize, end_ref: usize): usize {
var obj_tid = infer(self, obj_ref);
if begin_ref != 0 { ignore_usize(infer(self, begin_ref)); }
if end_ref != 0 { ignore_usize(infer(self, end_ref)); }
if begin_ref != 0 { infer(self, begin_ref); }
if end_ref != 0 { infer(self, end_ref); }
var obj = lang_of(self, obj_tid);
if obj == null { ret 0; }
if !(kind_is(self, obj_tid, .Array) || kind_is(self, obj_tid, .Ptr) ||
@@ -2685,7 +2657,7 @@ fn infer_aggregate(self: *Sema, n: *Node, type_name: ByteView, fields: Vec): usi
}
if idx < field_irs.len {
var ft = lang_from_ir(self, list_at(field_irs, idx));
if ft != 0 && iexpr != 0 { ignore_usize(coerce(self, iexpr, ft)); }
if ft != 0 && iexpr != 0 { coerce(self, iexpr, ft); }
}
}
i = i + 1;
@@ -2726,8 +2698,8 @@ fn infer_for(self: *Sema, n: *Node, label_ref: usize, iter_exprs: Vec, pattern_r
}
}
if body_ref != 0 { ignore_usize(infer(self, body_ref)); }
if else_ref != 0 { ignore_usize(infer(self, else_ref)); }
if body_ref != 0 { infer(self, body_ref); }
if else_ref != 0 { infer(self, else_ref); }
pop_scope(self);
pop_label(self);
@@ -2786,7 +2758,7 @@ fn infer_fn_decl(self: *Sema, n: *Node, params_ref: Vec, ret_ref: usize, body_re
}
var old_ret = self.current_fn_ret_tid;
self.current_fn_ret_tid = ret_tid;
ignore_usize(infer(self, body_ref));
infer(self, body_ref);
self.current_fn_ret_tid = old_ret;
pop_scope(self);
self.current_aggregate_lang = saved_agg;
@@ -2811,7 +2783,7 @@ fn infer_type_decl(self: *Sema, n: *Node, pattern_ref: usize, type_ref: usize):
while i < members.len {
var mref = list_at(members, i);
var mn = node(self, mref);
if mn != null && kind_is_body_fn_decl(mn) { ignore_usize(infer(self, mref)); }
if mn != null && kind_is_body_fn_decl(mn) { infer(self, mref); }
i = i + 1;
}
}
@@ -2826,9 +2798,9 @@ fn kind_is_body_fn_decl(n: *Node): bool {
fn infer_ret(self: *Sema, n: *Node, expr_ref: usize): usize {
if expr_ref != 0 {
if self.current_fn_ret_tid != 0 {
ignore_usize(coerce(self, expr_ref, self.current_fn_ret_tid));
coerce(self, expr_ref, self.current_fn_ret_tid);
} else {
ignore_usize(infer(self, expr_ref));
infer(self, expr_ref);
}
} else if self.current_fn_ret_tid != 0 {
var u = make_unit(self);
@@ -2850,9 +2822,9 @@ fn infer_break(self: *Sema, n: *Node, label_ref: usize, expr_ref: usize): usize
}
if expr_ref != 0 {
if self.current_loop_break_tid != 0 {
ignore_usize(coerce(self, expr_ref, self.current_loop_break_tid));
coerce(self, expr_ref, self.current_loop_break_tid);
} else {
ignore_usize(infer(self, expr_ref));
infer(self, expr_ref);
}
}
ret 0;
@@ -2884,7 +2856,6 @@ fn label_in_stack(self: *Sema, lbl: ByteView): bool {
ret false;
}
// ---- dump(镜像 stage1 spl_sema_dump;供 splc1 --dump sema 人读)----
type SymPrint = struct {
key: ByteView,
@@ -2928,7 +2899,7 @@ fn dump(self: *Sema, out: *ByteBuffer): bool {
if !out_u(out, sn.parent) { ret false; }
if !out_str(out, "\n") { ret false; }
// 收集后按符号名排序输出(与 stage1 一致,顺序与哈希布局解耦)。
// 收集后按符号名排序输出(顺序与哈希布局解耦)。
var entries = Vec.blank(@sizeof(SymPrint), @alignof(SymPrint));
var sc = Map.slot_count(sn.symbols);
var j: usize = 0;
@@ -2942,10 +2913,7 @@ fn dump(self: *Sema, out: *ByteBuffer): bool {
.name = sym.name,
.node = sym.node,
};
match Vec.push(&entries, &sp as *u8) {
.Ok => {},
.Err(error) => {},
}
Vec.push(&entries, &sp as *u8);
}
j = j + 1;
}
@@ -2959,11 +2927,11 @@ fn dump(self: *Sema, out: *ByteBuffer): bool {
var prev = sym_at(&entries, b - 1).*;
if ByteView.cmp(prev.key, cur.key) <= 0 { break; }
var pv = prev;
match Vec.set(&entries, b, &pv as *u8) { .Ok => {}, .Err(error) => {} }
Vec.set(&entries, b, &pv as *u8);
b = b - 1;
}
var cv = cur;
match Vec.set(&entries, b, &cv as *u8) { .Ok => {}, .Err(error) => {} }
Vec.set(&entries, b, &cv as *u8);
a = a + 1;
}
@@ -3019,7 +2987,6 @@ fn dump(self: *Sema, out: *ByteBuffer): bool {
ret Attr.dump(&self.attr, out);
}
// ---- 测试 ----
// 走完整前端:lex -> parse -> sema;返回 0 表示无(新)诊断。
fn sema_source(text: []u8): i32 {