Surfaced by
hyperpolymath/standards#284.
Behaviour
`BREAK` and `CONTINUE` are reserved tokens in `lib/parser.mly` but no production rule consumes them. Any use in source produces a syntax error.
```affine
while x < n {
if done { break } // syntax error: BREAK
...
}
```
Why this hurts
Early-exit control flow is idiomatic in TS / JS / Rust. Ports of stream-processing code (line-by-line scans, find-first-match) have to restructure into:
- Combined-guard `while` (`while running && i < n`)
- Sentinel-boolean (`mut done := false; while !done && i < n { ... done := true; ... }`)
- Early `return` from a helper function
All three were used in standards#284 (`s_trim` inner loops, `strip_leading_dot_slash`). Every loop-heavy TS port hits this.
Proposed fix
Add minimal `break` / `continue` to the parser + AST + lowerer:
- `Ast.expr` gains `Break` / `Continue` constructors (or use the existing exception-style `Throw` infrastructure if that's the chosen lowering).
- `Parser.mly` adds `BREAK` and `CONTINUE` as expression productions allowed inside `while` / `for` bodies.
- `Typecheck` checks the construct is lexically inside a loop.
- Lowering emits the matching JS/Deno construct (or compiles to a flag-and-test if the backend forbids early exits).
Acceptance
Refs
Surfaced by
hyperpolymath/standards#284.
Behaviour
`BREAK` and `CONTINUE` are reserved tokens in `lib/parser.mly` but no production rule consumes them. Any use in source produces a syntax error.
```affine
while x < n {
if done { break } // syntax error: BREAK
...
}
```
Why this hurts
Early-exit control flow is idiomatic in TS / JS / Rust. Ports of stream-processing code (line-by-line scans, find-first-match) have to restructure into:
All three were used in standards#284 (`s_trim` inner loops, `strip_leading_dot_slash`). Every loop-heavy TS port hits this.
Proposed fix
Add minimal `break` / `continue` to the parser + AST + lowerer:
Acceptance
Refs