stage2 修复大量AI生成的风格问题 stage1 修复对于vm abi的错误生成
This commit is contained in:
1 parent
0e38858785
commit
76f980654c
40 files changed
+619
-938
No files matched your search
+111
-144
@@ -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 {
|
||||
|
||||
Reference in new issue
Block a user