Parent: #899
Problem
The parser's remaining statement/control-flow early errors return bare UnexpectedToken from 16 grammar sites. The JS boundary therefore falls back to the token where parsing stopped, producing an internal tag and frequently an end-of-statement coordinate.
A current-main differential against raw JavaScriptCore 625.1.22 confirms separate messages for these grammar decisions:
| source | zig-js | JavaScriptCore |
|---|---|---|
\\u0069f (true) {} | UnexpectedToken at 1:1 | Unexpected escaped characters in keyword token: '\\u0069f' |
if (true) let [a] = []; | UnexpectedToken at 1:11 | Unexpected token '['. Cannot use lexical declaration in single-statement context. |
if (true) const x = 1; | UnexpectedToken at 1:23 | Unexpected keyword 'const' |
"use strict"; with ({}) {} | UnexpectedToken at 1:15 | 'with' statements are not valid in strict mode. |
break; | UnexpectedToken at 1:7 | 'break' is only valid inside a switch or loop statement. |
break missing; | UnexpectedToken at 1:15 | Cannot use the undeclared label 'missing'. |
continue; | UnexpectedToken at 1:10 | 'continue' is only valid inside a loop statement. |
outer: { continue outer; } | UnexpectedToken at 1:26 | Cannot continue to the label 'outer' as it is not targeting a loop. |
label: label: ; | UnexpectedToken at 1:15 | Unexpected token ';'. Attempted to redeclare the label 'label'. |
| strict / generator / async / loop-body function declarations | UnexpectedToken at the following token or EOF | distinct placement-specific prose |
Valid labeled break, labeled iteration continue, Annex B if functions, and Annex B labeled functions remain accepted in both engines.
JavaScriptCore 625.1.22 does not implement explicit resource management and therefore cannot supply proposal-aware wording for the two using placement checks. Those sites should still enter the structured path with exact declaration-token coordinates and truthful zig-js prose.
Implementation
- Add dedicated
DiagnosticReasonvalues for statement placement, strictwith, control-flow target, label, and function-declaration placement failures. - Retain the exact token already present at each grammar decision; do not rescan source or infer from the final parser cursor.
- Preserve the compact public
ParseError.UnexpectedTokencategory. - Keep formatting and allocation on the failure path. Successful parsing must not allocate or build diagnostic strings.
- Convert all 16 bare returns in
parseStatementInner/parseSubStatementso this cluster has no generic fallbacks.
Verification
- Pin exact reason, message, and byte offset in parser module tests, including valid neighboring grammar forms.
- Compare eval-visible messages with raw JavaScriptCore for supported syntax.
- Run the focused frontend/runtime cases.
- Compare affected
test262statement subtrees with an exact-parent binary and report denominator plus gains/regressions.