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;
|
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;
|
return nil;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1706,6 +1706,64 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = {
|
|||||||
m = m.next;
|
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;
|
return nil;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8638,6 +8638,64 @@ fn exprtype(c: *checker, e: *node, hint: *node) *node = {
|
|||||||
m = m.next;
|
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;
|
return nil;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user