syntax: accept the empty for () condition (align up to cstage)
cstage parse.c:1027 accepts `for ()` — N_FOR with a nil cond, no
for-else arm, no test emitted (an unconditional loop; a deliberate
Go-flavored ww divergence from Hare, original to the toolchain
import). The wwstage parser had no RPAREN early-out and rejected it.
Selfhost checker and cgen already nil-guard n.cond, so the parser arm
is the whole gap. Graduates the held e2e row (pin 1731/1157/3462).
Adjacent asymmetries left filed, not fixed here (rule 11): the brace
form `for { }`, the empty middle clause of the 3-clause form, and
the REVERSE case (wwstage accepts 2-clause `for (cond; post)` which
cstage rejects).
This commit is contained in:
@@ -1,13 +1,13 @@
|
|||||||
package wwfixture;
|
package wwfixture;
|
||||||
|
|
||||||
def protocolversion: i32 = 1;
|
def protocolversion: i32 = 1;
|
||||||
def corpuscount: i32 = 1730;
|
def corpuscount: i32 = 1731;
|
||||||
def errorcount: i32 = 343;
|
def errorcount: i32 = 343;
|
||||||
def compilecount: i32 = 22;
|
def compilecount: i32 = 22;
|
||||||
def runcount: i32 = 209;
|
def runcount: i32 = 209;
|
||||||
def runexitcount: i32 = 1156;
|
def runexitcount: i32 = 1157;
|
||||||
def nativecount: i32 = 3460;
|
def nativecount: i32 = 3462;
|
||||||
def corpushash: str = "5c20c19b826359fcceb45c8db5cf405f39183a68783582eaaf5f38f0e88f3771";
|
def corpushash: str = "6786916caba20c07c47eaaa0507dd2707fd162b708904b6e72187afb02233bf9";
|
||||||
|
|
||||||
type directive = enum i32 {
|
type directive = enum i32 {
|
||||||
ERROR = 0,
|
ERROR = 0,
|
||||||
|
|||||||
@@ -141,11 +141,22 @@ fn parsefor(p: *parser) *node = {
|
|||||||
advance(p); // past `for`
|
advance(p); // past `for`
|
||||||
expecttok(p, tkind.TK_LPAREN, "expected '(' after for");
|
expecttok(p, tkind.TK_LPAREN, "expected '(' after for");
|
||||||
|
|
||||||
// Four forms (matching C parser):
|
// Five forms (matching C parser):
|
||||||
|
// for () — empty cond, unconditional loop
|
||||||
// for (cond) — only cond
|
// for (cond) — only cond
|
||||||
// for (init; cond; post) — C-style 3-clause
|
// for (init; cond; post) — C-style 3-clause
|
||||||
// for (let x .. expr) — Hare-style range, single binding
|
// for (let x .. expr) — Hare-style range, single binding
|
||||||
// for (let (a, b) .. expr) — range with tuple destructure
|
// for (let (a, b) .. expr) — range with tuple destructure
|
||||||
|
|
||||||
|
// Empty condition: cond stays nil (no test emitted downstream).
|
||||||
|
// Mirrors cmd/wcc/parse.c:1027 — returns WITHOUT the for-else arm,
|
||||||
|
// exactly as the cstage empty form does.
|
||||||
|
if (p.curkind == tkind.TK_RPAREN) {
|
||||||
|
advance(p);
|
||||||
|
let n = newnode(nkind.N_FOR, pf, pl, pc);
|
||||||
|
n.body = parseblock(p);
|
||||||
|
return n;
|
||||||
|
};
|
||||||
// Range and 3-clause both lead with `let`, so we commit to consuming
|
// Range and 3-clause both lead with `let`, so we commit to consuming
|
||||||
// `let` then disambiguate by looking at what follows.
|
// `let` then disambiguate by looking at what follows.
|
||||||
if (p.curkind == tkind.TK_LET) {
|
if (p.curkind == tkind.TK_LET) {
|
||||||
|
|||||||
11
test/wcc/data/r700_break_loop/case.ww
Normal file
11
test/wcc/data/r700_break_loop/case.ww
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
//ww:run-exit 7
|
||||||
|
// Migrated from 700_e2e row 23.
|
||||||
|
package main;
|
||||||
|
fn main() i32 = {
|
||||||
|
let i: i32 = 0;
|
||||||
|
for () {
|
||||||
|
i += 1;
|
||||||
|
if (i == 7) { break; };
|
||||||
|
};
|
||||||
|
return i;
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user