stage2 支持左值的引用绑定

This commit is contained in:
zzy committed 2026-09-29 23:00:24 +08:00
1 parent 40cffa9cb5
commit 0e38858785
4 files changed
+200 -198

No files matched your search

+89 -89
View File
@@ -337,13 +337,13 @@ fn resolve_attr_item(self: *Sema, a: *Node): usize {
fn resolve_attrs(self: *Sema, n: *Node) {
if n.attrs.len != 0 { ret; }
match n.body {
.FnDecl(x) => { node_attr_raw(self, n, x.tag_list); },
.VarDecl(x) => { node_attr_raw(self, n, x.attr_list); },
.ConstDecl(x) => { node_attr_raw(self, n, x.attr_list); },
.TypeDecl(x) => { node_attr_raw(self, n, x.attr_list); },
.MemberDecl(x) => { node_attr_raw(self, n, x.attr_list); },
.ParamDecl(x) => { node_attr_raw(self, n, x.attr_list); },
.TopLevelBlock(x) => { node_attr_raw(self, n, x.tag_list); },
.FnDecl(&x) => { node_attr_raw(self, n, x.tag_list); },
.VarDecl(&x) => { node_attr_raw(self, n, x.attr_list); },
.ConstDecl(&x) => { node_attr_raw(self, n, x.attr_list); },
.TypeDecl(&x) => { node_attr_raw(self, n, x.attr_list); },
.MemberDecl(&x) => { node_attr_raw(self, n, x.attr_list); },
.ParamDecl(&x) => { node_attr_raw(self, n, x.attr_list); },
.TopLevelBlock(&x) => { node_attr_raw(self, n, x.tag_list); },
_ => {},
}
}
@@ -353,7 +353,7 @@ fn resolve_attrs(self: *Sema, n: *Node) {
fn build_aggregate(self: *Sema, te: *Node, owner_def_id: usize): usize {
var kind_name = ByteView.empty();
match te.body {
.TypeAggregate(x) => { kind_name = x.kind_name; },
.TypeAggregate(&x) => { kind_name = x.kind_name; },
_ => {},
}
var lk: LangKind = .Struct;
@@ -389,7 +389,7 @@ fn build_aggregate(self: *Sema, te: *Node, owner_def_id: usize): usize {
var mlist = ref_vec();
match te.body {
.TypeAggregate(x) => { mlist = x.members; },
.TypeAggregate(&x) => { mlist = x.members; },
_ => {},
}
var i: usize = 0;
@@ -554,41 +554,41 @@ fn container_var_method(self: *Sema, pat_ref: usize, methods: *Vec) {
}
fn is_pattern_ident(n: *Node): bool {
match n.body { .PatternIdent(x) => { ret true; }, _ => { ret false; } }
match n.body { .PatternIdent(&x) => { ret true; }, _ => { ret false; } }
ret false;
}
fn is_type_aggregate(n: *Node): bool {
match n.body { .TypeAggregate(x) => { ret true; }, _ => { ret false; } }
match n.body { .TypeAggregate(&x) => { ret true; }, _ => { ret false; } }
ret false;
}
fn is_param_decl(n: *Node): bool {
match n.body { .ParamDecl(x) => { ret true; }, _ => { ret false; } }
match n.body { .ParamDecl(&x) => { ret true; }, _ => { ret false; } }
ret false;
}
fn is_type_decl(n: *Node): bool {
match n.body { .TypeDecl(x) => { ret true; }, _ => { ret false; } }
match n.body { .TypeDecl(&x) => { ret true; }, _ => { ret false; } }
ret false;
}
fn is_pattern_field(n: *Node): bool {
match n.body { .PatternField(x) => { ret true; }, _ => { ret false; } }
match n.body { .PatternField(&x) => { ret true; }, _ => { ret false; } }
ret false;
}
fn is_expr_string_lit(n: *Node): bool {
match n.body { .ExprStringLit(x) => { ret true; }, _ => { ret false; } }
match n.body { .ExprStringLit(&x) => { ret true; }, _ => { ret false; } }
ret false;
}
fn is_expr_ident(n: *Node): bool {
match n.body { .ExprIdent(x) => { ret true; }, _ => { ret false; } }
match n.body { .ExprIdent(&x) => { ret true; }, _ => { ret false; } }
ret false;
}
fn is_expr_int_lit(n: *Node): bool {
match n.body { .ExprIntLit(x) => { ret true; }, _ => { ret false; } }
match n.body { .ExprIntLit(&x) => { ret true; }, _ => { ret false; } }
ret false;
}
fn pattern_name(pat: *Node): ByteView {
match pat.body {
.PatternIdent(x) => { ret x.name; },
.PatternIdent(&x) => { ret x.name; },
_ => { ret ByteView.empty(); },
}
}
@@ -774,7 +774,7 @@ fn infer_fn_signature(self: *Sema, n: *Node): usize {
var pd = node(self, list_at(params_list, i));
if pd != null && is_param_decl(pd) {
var tref: usize = 0;
match pd.body { .ParamDecl(x) => { tref = x.type_expr; }, _ => {} }
match pd.body { .ParamDecl(&x) => { tref = x.type_expr; }, _ => {} }
if tref != 0 {
push_u(&params, infer(self, tref));
} else {
@@ -951,7 +951,7 @@ fn infer_type_context(self: *Sema, ref: usize): usize {
var n = node(self, ref);
if n == null { ret 0; }
match n.body {
.ExprIdent(x) => {
.ExprIdent(&x) => {
var builtin = LangType.lookup_builtin(&self.types, x.name);
if builtin != 0 {
n.resolved_lang_tid = builtin;
@@ -971,7 +971,7 @@ fn infer_type_context(self: *Sema, ref: usize): usize {
n.resolved_lang_tid = t;
ret t;
},
.ExprField(x) => {
.ExprField(&x) => {
var owner_id = infer_type_context(self, x.obj);
var owner = lang_of(self, owner_id);
if owner == null { ret 0; }
@@ -990,7 +990,7 @@ fn infer_type_context(self: *Sema, ref: usize): usize {
diag_name(self, n.span, .TypeMismatch, "not a type member `", x.name);
ret 0;
},
.ExprUnary(x) => {
.ExprUnary(&x) => {
if punct_is(x.op, .Mul) {
var pointee = infer_type_context(self, x.operand);
if pointee == 0 { ret 0; }
@@ -1000,7 +1000,7 @@ fn infer_type_context(self: *Sema, ref: usize): usize {
}
ret 0;
},
.ExprTuple(x) => {
.ExprTuple(&x) => {
var elems = ref_vec();
var i: usize = 0;
while i < x.items.len {
@@ -1013,7 +1013,7 @@ fn infer_type_context(self: *Sema, ref: usize): usize {
n.resolved_lang_tid = r;
ret r;
},
.ExprComptimeCall(x) => {
.ExprComptimeCall(&x) => {
var r = infer(self, ref);
n.resolved_lang_tid = r;
ret r;
@@ -1160,7 +1160,7 @@ fn intrin_call(self: *Sema, n: *Node, in: Intrin, args: Vec): usize {
if fnode == null { ret 0; }
if is_expr_ident(fnode) {
var fname = ByteView.empty();
match fnode.body { .ExprIdent(x) => { fname = x.name; }, _ => {} }
match fnode.body { .ExprIdent(&x) => { fname = x.name; }, _ => {} }
var idx: usize = 0;
if !TypeTable.agg_member_idx(&self.types.ir, agg_ir, fname, &idx) {
diag_name(self, n.span, .NoField, "no field `", fname);
@@ -1681,13 +1681,13 @@ fn coerce(self: *Sema, ref: usize, expected: usize): usize {
var result: usize = 0;
match n.body {
.ExprUnary(x) => {
.ExprUnary(&x) => {
if !(punct_is(x.op, .And) || punct_is(x.op, .Mul)) {
handled = true;
result = coerce(self, x.operand, expected);
}
},
.ExprBinary(x) => {
.ExprBinary(&x) => {
handled = true;
var op = x.op;
if punct_is(op, .Assign) || is_assign_arith(op) {
@@ -1744,7 +1744,7 @@ fn coerce(self: *Sema, ref: usize, expected: usize): usize {
result = expected;
}
},
.ExprArrayLit(x) => {
.ExprArrayLit(&x) => {
var en = lang_of(self, expected);
if en != null && (kind_is(self, expected, .Array) || kind_is(self, expected, .Slice)) {
handled = true;
@@ -1757,7 +1757,7 @@ fn coerce(self: *Sema, ref: usize, expected: usize): usize {
result = expected;
}
},
.ExprTuple(x) => {
.ExprTuple(&x) => {
var en = lang_of(self, expected);
if en != null && kind_is(self, expected, .Tuple) {
handled = true;
@@ -1775,7 +1775,7 @@ fn coerce(self: *Sema, ref: usize, expected: usize): usize {
result = expected;
}
},
.ExprAggregateLit(x) => {
.ExprAggregateLit(&x) => {
var en = lang_of(self, expected);
if en != null && (kind_is(self, expected, .Struct) || kind_is(self, expected, .Union) ||
kind_is(self, expected, .Enum) || kind_is(self, expected, .Slice)) {
@@ -1806,7 +1806,7 @@ fn coerce(self: *Sema, ref: usize, expected: usize): usize {
}
var iname = ByteView.empty();
var iexpr: usize = 0;
match item.body { .StructInitItem(si) => { iname = si.name; iexpr = si.expr; }, _ => {} }
match item.body { .StructInitItem(&si) => { iname = si.name; iexpr = si.expr; }, _ => {} }
var idx: usize = 0;
if !TypeTable.agg_member_idx(&self.types.ir, agg_ir, iname, &idx) {
diag_name(self, item.span, .NoField, "no variant `", iname);
@@ -1825,7 +1825,7 @@ fn coerce(self: *Sema, ref: usize, expected: usize): usize {
if item != null && kind_is_body_struct_init(item) {
var iname = ByteView.empty();
var iexpr: usize = 0;
match item.body { .StructInitItem(si) => { iname = si.name; iexpr = si.expr; }, _ => {} }
match item.body { .StructInitItem(&si) => { iname = si.name; iexpr = si.expr; }, _ => {} }
var idx: usize = 0;
if !TypeTable.agg_member_idx(&self.types.ir, agg_ir, iname, &idx) {
diag_name(self, item.span, .NoField, "no field `", iname);
@@ -1845,7 +1845,7 @@ fn coerce(self: *Sema, ref: usize, expected: usize): usize {
}
}
},
.ExprIf(x) => {
.ExprIf(&x) => {
handled = true;
var bt = make_bool(self);
ignore_usize(coerce(self, x.cond, bt));
@@ -1853,7 +1853,7 @@ fn coerce(self: *Sema, ref: usize, expected: usize): usize {
if x.else_branch != 0 { ignore_usize(coerce(self, x.else_branch, expected)); }
result = expected;
},
.ExprLoop(x) => {
.ExprLoop(&x) => {
handled = true;
var saved = self.current_loop_break_tid;
self.current_loop_break_tid = expected;
@@ -1861,7 +1861,7 @@ fn coerce(self: *Sema, ref: usize, expected: usize): usize {
self.current_loop_break_tid = saved;
result = expected;
},
.ExprBlock(x) => {
.ExprBlock(&x) => {
ret block_body(self, n, expected);
},
_ => {},
@@ -1881,7 +1881,7 @@ fn coerce(self: *Sema, ref: usize, expected: usize): usize {
if is_expr_int_lit(n) && int_bits(self, expected) != 0 {
var fits = true;
match n.body {
.ExprIntLit(v) => {
.ExprIntLit(&v) => {
if !LangType.int_fits(&self.types, expected, v.value) { fits = false; }
},
_ => {},
@@ -1916,7 +1916,7 @@ fn elem_of_lang(e: LangEntry): usize {
}
fn kind_is_body_struct_init(n: *Node): bool {
match n.body { .StructInitItem(x) => { ret true; }, _ => { ret false; } }
match n.body { .StructInitItem(&x) => { ret true; }, _ => { ret false; } }
ret false;
}
@@ -1929,28 +1929,28 @@ fn infer(self: *Sema, ref: usize): usize {
resolve_attrs(self, n);
match n.body {
.ExprIntLit(x) => {
.ExprIntLit(&x) => {
var t = LangType.make_int(&self.types, 0, true);
n.resolved_lang_tid = t;
ret t;
},
.ExprFloatLit(x) => {
.ExprFloatLit(&x) => {
var t = LangType.make_float(&self.types, 0);
n.resolved_lang_tid = t;
ret t;
},
.ExprCharLit(x) => {
.ExprCharLit(&x) => {
var t = LangType.make_int(&self.types, 8, false);
n.resolved_lang_tid = t;
ret t;
},
.ExprStringLit(x) => {
.ExprStringLit(&x) => {
var u8t = LangType.make_int(&self.types, 8, false);
var s = LangType.make_slice(&self.types, u8t);
n.resolved_lang_tid = s;
ret s;
},
.ExprBoolLit(x) => {
.ExprBoolLit(&x) => {
var t = make_bool(self);
n.resolved_lang_tid = t;
ret t;
@@ -1966,7 +1966,7 @@ fn infer(self: *Sema, ref: usize): usize {
n.resolved_lang_tid = t;
ret t;
},
.ExprIdent(x) => {
.ExprIdent(&x) => {
var sym = Symbol { .name = ByteView.empty(), .kind = .Error, .node = 0 };
if !Scope.find(&self.scope, x.name, &sym) {
diag_name(self, n.span, .UndefinedSymbol, "undefined identifier `", x.name);
@@ -1981,7 +1981,7 @@ fn infer(self: *Sema, ref: usize): usize {
n.resolved_lang_tid = t;
ret t;
},
.ExprUnary(x) => {
.ExprUnary(&x) => {
var op = infer(self, x.operand);
if op == 0 { ret 0; }
var tn = lang_of(self, op);
@@ -2032,25 +2032,25 @@ fn infer(self: *Sema, ref: usize): usize {
}
ret 0;
},
.ExprBinary(x) => {
.ExprBinary(&x) => {
ret infer_binary(self, n, x.op, x.left, x.right);
},
.ExprCall(x) => {
.ExprCall(&x) => {
ret infer_call(self, n, x.callee, x.args);
},
.ExprField(x) => {
.ExprField(&x) => {
ret infer_field(self, n, x.obj, x.name);
},
.ExprIndex(x) => {
.ExprIndex(&x) => {
ret infer_index(self, n, x.obj, x.index);
},
.ExprSlice(x) => {
.ExprSlice(&x) => {
ret infer_slice(self, n, x.obj, x.begin, x.end);
},
.ExprCast(x) => {
.ExprCast(&x) => {
ret infer_cast(self, n, x.expr, x.type_expr);
},
.ExprTuple(x) => {
.ExprTuple(&x) => {
var es = ref_vec();
var i: usize = 0;
while i < x.items.len {
@@ -2061,13 +2061,13 @@ fn infer(self: *Sema, ref: usize): usize {
n.resolved_lang_tid = t;
ret t;
},
.ExprArrayLit(x) => {
.ExprArrayLit(&x) => {
ret infer_array(self, n, x.elem_type, x.has_len, x.len, x.is_underscore_len, x.elems);
},
.ExprAggregateLit(x) => {
.ExprAggregateLit(&x) => {
ret infer_aggregate(self, n, x.name, x.fields);
},
.ExprComptimeCall(x) => {
.ExprComptimeCall(&x) => {
if ByteView.eq(x.name, ByteView.from_slice("import")) {
var t = sema_import(self, n, x.args);
n.resolved_lang_tid = t;
@@ -2090,10 +2090,10 @@ fn infer(self: *Sema, ref: usize): usize {
n.resolved_lang_tid = t;
ret t;
},
.ExprBlock(x) => {
.ExprBlock(&x) => {
ret block_body(self, n, 0);
},
.ExprIf(x) => {
.ExprIf(&x) => {
var bt = make_bool(self);
ignore_usize(coerce(self, x.cond, bt));
var then_t = if x.then_block != 0 { infer(self, x.then_block) } else { 0 };
@@ -2109,7 +2109,7 @@ fn infer(self: *Sema, ref: usize): usize {
n.resolved_lang_tid = result;
ret result;
},
.ExprIfvar(x) => {
.ExprIfvar(&x) => {
if x.var_decl == 0 { ret 0; }
var vd = node(self, x.var_decl);
if vd == null { ret 0; }
@@ -2120,7 +2120,7 @@ fn infer(self: *Sema, ref: usize): usize {
if x.else_branch != 0 { ignore_usize(infer(self, x.else_branch)); }
ret 0;
},
.ExprWhile(x) => {
.ExprWhile(&x) => {
push_view(&self.label_stack, label_name(self, x.label));
var bt = make_bool(self);
ignore_usize(coerce(self, x.cond, bt));
@@ -2129,16 +2129,16 @@ fn infer(self: *Sema, ref: usize): usize {
pop_label(self);
ret 0;
},
.ExprLoop(x) => {
.ExprLoop(&x) => {
push_view(&self.label_stack, label_name(self, x.label));
if x.body != 0 { ignore_usize(infer(self, x.body)); }
pop_label(self);
ret 0;
},
.ExprFor(x) => {
.ExprFor(&x) => {
ret infer_for(self, n, x.label, x.iter_exprs, x.pattern, x.body, x.else_branch);
},
.ExprMatch(x) => {
.ExprMatch(&x) => {
var matched = infer(self, x.matched_expr);
var i: usize = 0;
while i < x.arms.len {
@@ -2162,7 +2162,7 @@ fn infer(self: *Sema, ref: usize): usize {
}
ret 0;
},
.ExprFnType(x) => {
.ExprFnType(&x) => {
var ps = ref_vec();
var i: usize = 0;
while i < x.params.len {
@@ -2174,7 +2174,7 @@ fn infer(self: *Sema, ref: usize): usize {
n.resolved_lang_tid = fn_lang;
ret fn_lang;
},
.TypePath(x) => {
.TypePath(&x) => {
var b = LangType.lookup_builtin(&self.types, x.name);
if b != 0 {
n.resolved_lang_tid = b;
@@ -2189,13 +2189,13 @@ fn infer(self: *Sema, ref: usize): usize {
n.resolved_lang_tid = t;
ret t;
},
.TypePointer(x) => {
.TypePointer(&x) => {
var p = infer(self, x.pointee);
var r = LangType.make_ptr(&self.types, p);
n.resolved_lang_tid = r;
ret r;
},
.TypeArray(x) => {
.TypeArray(&x) => {
var e = infer(self, x.elem_type);
var len: usize = 0;
if x.has_len { len = x.len as usize; }
@@ -2203,13 +2203,13 @@ fn infer(self: *Sema, ref: usize): usize {
n.resolved_lang_tid = r;
ret r;
},
.TypeSlice(x) => {
.TypeSlice(&x) => {
var e = infer(self, x.elem_type);
var r = LangType.make_slice(&self.types, e);
n.resolved_lang_tid = r;
ret r;
},
.TypeFn(x) => {
.TypeFn(&x) => {
var ps = ref_vec();
var i: usize = 0;
while i < x.params.len {
@@ -2221,7 +2221,7 @@ fn infer(self: *Sema, ref: usize): usize {
n.resolved_lang_tid = r;
ret r;
},
.TypeParen(x) => {
.TypeParen(&x) => {
if x.types.len == 0 {
var u = make_unit(self);
n.resolved_lang_tid = u;
@@ -2242,10 +2242,10 @@ fn infer(self: *Sema, ref: usize): usize {
n.resolved_lang_tid = t;
ret t;
},
.TypeAggregate(x) => {
.TypeAggregate(&x) => {
ret build_aggregate(self, n, 0);
},
.TypeComptimeCall(x) => {
.TypeComptimeCall(&x) => {
if ByteView.eq(x.name, ByteView.from_slice("self")) {
if self.current_aggregate_lang == 0 {
diag(self, n.span, .UndefinedSymbol, "`@self` outside of aggregate");
@@ -2261,7 +2261,7 @@ fn infer(self: *Sema, ref: usize): usize {
}
ret 0;
},
.ContainerMembers(x) => {
.ContainerMembers(&x) => {
var i: usize = 0;
while i < x.declarations.len {
ignore_usize(infer(self, list_at(x.declarations, i)));
@@ -2269,48 +2269,48 @@ fn infer(self: *Sema, ref: usize): usize {
}
ret 0;
},
.FnDecl(x) => {
.FnDecl(&x) => {
ret infer_fn_decl(self, n, x.params, x.ret_type, x.body);
},
.TypeDecl(x) => {
.TypeDecl(&x) => {
ret infer_type_decl(self, n, x.pattern, x.type_expr);
},
.VarDecl(x) => { ret var_body(self, n); },
.ConstDecl(x) => { ret var_body(self, n); },
.MemberDecl(x) => {
.VarDecl(&x) => { ret var_body(self, n); },
.ConstDecl(&x) => { ret var_body(self, n); },
.MemberDecl(&x) => {
if x.type_expr != 0 { ret infer(self, x.type_expr); }
ret 0;
},
.ParamDecl(x) => {
.ParamDecl(&x) => {
if x.type_expr != 0 { ret infer(self, x.type_expr); }
ret 0;
},
.StatementRet(x) => {
.StatementRet(&x) => {
ret infer_ret(self, n, x.expr);
},
.StatementBreak(x) => {
.StatementBreak(&x) => {
ret infer_break(self, n, x.label, x.expr);
},
.StatementContinue(x) => {
.StatementContinue(&x) => {
ret infer_continue(self, n, x.label);
},
.StatementDefer(x) => {
.StatementDefer(&x) => {
if x.body != 0 { ignore_usize(infer(self, x.body)); }
ret 0;
},
.StatementComptime(x) => {
.StatementComptime(&x) => {
if x.body != 0 { ignore_usize(infer(self, x.body)); }
ret 0;
},
.StatementDecl(x) => {
.StatementDecl(&x) => {
if x.decl != 0 { ignore_usize(infer(self, x.decl)); }
ret 0;
},
.StatementExpr(x) => {
.StatementExpr(&x) => {
if x.expr != 0 { ignore_usize(infer(self, x.expr)); }
ret 0;
},
.TopLevelBlock(x) => {
.TopLevelBlock(&x) => {
if x.block != 0 { ignore_usize(infer(self, x.block)); }
ret 0;
},
@@ -2320,7 +2320,7 @@ fn infer(self: *Sema, ref: usize): usize {
}
fn kind_is_body_ident(n: *Node): bool {
match n.body { .ExprIdent(x) => { ret true; }, _ => { ret false; } }
match n.body { .ExprIdent(&x) => { ret true; }, _ => { ret false; } }
ret false;
}
@@ -2614,7 +2614,7 @@ fn infer_cast(self: *Sema, n: *Node, expr_ref: usize, type_ref: usize): usize {
}
fn is_expr_float_lit(n: *Node): bool {
match n.body { .ExprFloatLit(x) => { ret true; }, _ => { ret false; } }
match n.body { .ExprFloatLit(&x) => { ret true; }, _ => { ret false; } }
ret false;
}
@@ -2735,7 +2735,7 @@ fn infer_for(self: *Sema, n: *Node, label_ref: usize, iter_exprs: Vec, pattern_r
}
fn kind_is_body_pattern_list(n: *Node): bool {
match n.body { .PatternList(x) => { ret true; }, _ => { ret false; } }
match n.body { .PatternList(&x) => { ret true; }, _ => { ret false; } }
ret false;
}
@@ -2819,7 +2819,7 @@ fn infer_type_decl(self: *Sema, n: *Node, pattern_ref: usize, type_ref: usize):
}
fn kind_is_body_fn_decl(n: *Node): bool {
match n.body { .FnDecl(x) => { ret true; }, _ => { ret false; } }
match n.body { .FnDecl(&x) => { ret true; }, _ => { ret false; } }
ret false;
}