selfhost/cmd/wcc: stamp N_DOT struct/pseudo/tuple in exprtype (A.6.1.5b)
Port cstage cmd/wcc/check.c:833-866 stamp cases to exprtype's
N_DOT arm. Three sub-cases append to the A.6.1.5a basetn-walk
block, all pure type_ annotations — none mutate e.kind:
- Pseudo-fields .len / .cap / .ptr on slice / str / array
(cstage L833-842). `len` and `cap` stamp i32; `ptr` synthesises
an N_TPTR over the element (u8 for str, bu.lhs else).
- Struct field walk on N_TSTRUCT (cstage L843-849) — match
N_TFIELD by name, return f.lhs and stamp.
- Tuple positional access `t.0`, `t.1`, … on N_TTUPLE
(cstage L850-866). fldnumidx (cgenutil SSoT for decimal-only
parsing) yields the index; walk bu.list .next idx times.
Two divergences from cstage, documented inline:
- Wwstage carries str as N_TNAME("str") (no dedicated N_TSTR);
the pseudo-field guard tests the trio shape directly.
- Wwstage falls through to nil on struct/tuple miss instead
of erroring (lenient policy per scruttype L656).
Cumulative N_DOT arm now ~162 LOC, under Rob's 250-LOC tripwire.
No new helpers; fldnumidx reused. #56 mod.fn() parser-rep stays
parked.
Phase 1 A.6 step 5b of ~8 — closes Hare's access_field surface
(ref/hare/hare/ast/expr.ha:7-38). Cgenutil's paired walker still
derives the same shapes; A.6.3 collapses those onto these stamps.
Verified 132/132 incl. 995_self_rebuild byte-identity.
This commit is contained in:
@@ -8638,6 +8638,64 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = {
|
||||
m = m.next;
|
||||
};
|
||||
}; };
|
||||
// A.6.1.5b stamp cases — mirror cstage check.c:833-866. Pure
|
||||
// type-AST stamps; never rewrite e.kind. Lenient on misses
|
||||
// (cstage errors); falls through to nil under scruttype L656.
|
||||
//
|
||||
// Pseudo-fields .len/.cap/.ptr on slice/str/array. Cstage
|
||||
// L833-842. `str` lives as N_TNAME("str") in wwstage — no
|
||||
// dedicated N_TSTR kind — so test the trio shape here.
|
||||
if (bu != nil) {
|
||||
let isstr: bool = (bu.kind == nkind.N_TNAME) && streq(bu.str, "str");
|
||||
if (bu.kind == nkind.N_TSLICE || bu.kind == nkind.N_TARRAY || isstr) {
|
||||
if (streq(e.str, "len")) {
|
||||
let tn: *node = mktname(c, "i32");
|
||||
e.type_ = tinfofornode(c, tn): *void;
|
||||
return tn;
|
||||
};
|
||||
if (streq(e.str, "cap")) {
|
||||
let tn: *node = mktname(c, "i32");
|
||||
e.type_ = tinfofornode(c, tn): *void;
|
||||
return tn;
|
||||
};
|
||||
if (streq(e.str, "ptr")) {
|
||||
let elem: *node = bu.lhs;
|
||||
if (isstr) { elem = mktname(c, "u8"); };
|
||||
let pp: *node = newnode(nkind.N_TPTR, "", 0, 0);
|
||||
pp.lhs = elem;
|
||||
e.type_ = tinfofornode(c, pp): *void;
|
||||
return pp;
|
||||
};
|
||||
};
|
||||
};
|
||||
// Struct field walk. Cstage L843-849 errors on missing field.
|
||||
if (bu != nil) { if (bu.kind == nkind.N_TSTRUCT) {
|
||||
let f: *node = bu.list;
|
||||
for (f != nil) {
|
||||
if (f.kind == nkind.N_TFIELD) { if (streq(f.str, e.str)) {
|
||||
e.type_ = tinfofornode(c, f.lhs): *void;
|
||||
return f.lhs;
|
||||
}; };
|
||||
f = f.next;
|
||||
};
|
||||
}; };
|
||||
// Tuple positional access `t.0`, `t.1`, …. Cstage L850-866
|
||||
// errors on non-numeric / out-of-range; wwstage falls
|
||||
// through. fldnumidx (cgenutil) returns -1 on non-digit.
|
||||
if (bu != nil) { if (bu.kind == nkind.N_TTUPLE) {
|
||||
let idx: i32 = fldnumidx(e.str);
|
||||
if (idx >= 0) {
|
||||
let p: *node = bu.list;
|
||||
for (idx > 0 && p != nil) {
|
||||
p = p.next;
|
||||
idx -= 1;
|
||||
};
|
||||
if (p != nil) {
|
||||
e.type_ = tinfofornode(c, p): *void;
|
||||
return p;
|
||||
};
|
||||
};
|
||||
}; };
|
||||
};
|
||||
return nil;
|
||||
};
|
||||
|
||||
@@ -1706,6 +1706,64 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = {
|
||||
m = m.next;
|
||||
};
|
||||
}; };
|
||||
// A.6.1.5b stamp cases — mirror cstage check.c:833-866. Pure
|
||||
// type-AST stamps; never rewrite e.kind. Lenient on misses
|
||||
// (cstage errors); falls through to nil under scruttype L656.
|
||||
//
|
||||
// Pseudo-fields .len/.cap/.ptr on slice/str/array. Cstage
|
||||
// L833-842. `str` lives as N_TNAME("str") in wwstage — no
|
||||
// dedicated N_TSTR kind — so test the trio shape here.
|
||||
if (bu != nil) {
|
||||
let isstr: bool = (bu.kind == nkind.N_TNAME) && streq(bu.str, "str");
|
||||
if (bu.kind == nkind.N_TSLICE || bu.kind == nkind.N_TARRAY || isstr) {
|
||||
if (streq(e.str, "len")) {
|
||||
let tn: *node = mktname(c, "i32");
|
||||
e.type_ = tinfofornode(c, tn): *void;
|
||||
return tn;
|
||||
};
|
||||
if (streq(e.str, "cap")) {
|
||||
let tn: *node = mktname(c, "i32");
|
||||
e.type_ = tinfofornode(c, tn): *void;
|
||||
return tn;
|
||||
};
|
||||
if (streq(e.str, "ptr")) {
|
||||
let elem: *node = bu.lhs;
|
||||
if (isstr) { elem = mktname(c, "u8"); };
|
||||
let pp: *node = newnode(nkind.N_TPTR, "", 0, 0);
|
||||
pp.lhs = elem;
|
||||
e.type_ = tinfofornode(c, pp): *void;
|
||||
return pp;
|
||||
};
|
||||
};
|
||||
};
|
||||
// Struct field walk. Cstage L843-849 errors on missing field.
|
||||
if (bu != nil) { if (bu.kind == nkind.N_TSTRUCT) {
|
||||
let f: *node = bu.list;
|
||||
for (f != nil) {
|
||||
if (f.kind == nkind.N_TFIELD) { if (streq(f.str, e.str)) {
|
||||
e.type_ = tinfofornode(c, f.lhs): *void;
|
||||
return f.lhs;
|
||||
}; };
|
||||
f = f.next;
|
||||
};
|
||||
}; };
|
||||
// Tuple positional access `t.0`, `t.1`, …. Cstage L850-866
|
||||
// errors on non-numeric / out-of-range; wwstage falls
|
||||
// through. fldnumidx (cgenutil) returns -1 on non-digit.
|
||||
if (bu != nil) { if (bu.kind == nkind.N_TTUPLE) {
|
||||
let idx: i32 = fldnumidx(e.str);
|
||||
if (idx >= 0) {
|
||||
let p: *node = bu.list;
|
||||
for (idx > 0 && p != nil) {
|
||||
p = p.next;
|
||||
idx -= 1;
|
||||
};
|
||||
if (p != nil) {
|
||||
e.type_ = tinfofornode(c, p): *void;
|
||||
return p;
|
||||
};
|
||||
};
|
||||
}; };
|
||||
};
|
||||
return nil;
|
||||
};
|
||||
|
||||
@@ -8638,6 +8638,64 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = {
|
||||
m = m.next;
|
||||
};
|
||||
}; };
|
||||
// A.6.1.5b stamp cases — mirror cstage check.c:833-866. Pure
|
||||
// type-AST stamps; never rewrite e.kind. Lenient on misses
|
||||
// (cstage errors); falls through to nil under scruttype L656.
|
||||
//
|
||||
// Pseudo-fields .len/.cap/.ptr on slice/str/array. Cstage
|
||||
// L833-842. `str` lives as N_TNAME("str") in wwstage — no
|
||||
// dedicated N_TSTR kind — so test the trio shape here.
|
||||
if (bu != nil) {
|
||||
let isstr: bool = (bu.kind == nkind.N_TNAME) && streq(bu.str, "str");
|
||||
if (bu.kind == nkind.N_TSLICE || bu.kind == nkind.N_TARRAY || isstr) {
|
||||
if (streq(e.str, "len")) {
|
||||
let tn: *node = mktname(c, "i32");
|
||||
e.type_ = tinfofornode(c, tn): *void;
|
||||
return tn;
|
||||
};
|
||||
if (streq(e.str, "cap")) {
|
||||
let tn: *node = mktname(c, "i32");
|
||||
e.type_ = tinfofornode(c, tn): *void;
|
||||
return tn;
|
||||
};
|
||||
if (streq(e.str, "ptr")) {
|
||||
let elem: *node = bu.lhs;
|
||||
if (isstr) { elem = mktname(c, "u8"); };
|
||||
let pp: *node = newnode(nkind.N_TPTR, "", 0, 0);
|
||||
pp.lhs = elem;
|
||||
e.type_ = tinfofornode(c, pp): *void;
|
||||
return pp;
|
||||
};
|
||||
};
|
||||
};
|
||||
// Struct field walk. Cstage L843-849 errors on missing field.
|
||||
if (bu != nil) { if (bu.kind == nkind.N_TSTRUCT) {
|
||||
let f: *node = bu.list;
|
||||
for (f != nil) {
|
||||
if (f.kind == nkind.N_TFIELD) { if (streq(f.str, e.str)) {
|
||||
e.type_ = tinfofornode(c, f.lhs): *void;
|
||||
return f.lhs;
|
||||
}; };
|
||||
f = f.next;
|
||||
};
|
||||
}; };
|
||||
// Tuple positional access `t.0`, `t.1`, …. Cstage L850-866
|
||||
// errors on non-numeric / out-of-range; wwstage falls
|
||||
// through. fldnumidx (cgenutil) returns -1 on non-digit.
|
||||
if (bu != nil) { if (bu.kind == nkind.N_TTUPLE) {
|
||||
let idx: i32 = fldnumidx(e.str);
|
||||
if (idx >= 0) {
|
||||
let p: *node = bu.list;
|
||||
for (idx > 0 && p != nil) {
|
||||
p = p.next;
|
||||
idx -= 1;
|
||||
};
|
||||
if (p != nil) {
|
||||
e.type_ = tinfofornode(c, p): *void;
|
||||
return p;
|
||||
};
|
||||
};
|
||||
}; };
|
||||
};
|
||||
return nil;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user