|
1 | 1 | // Loops: while, do-while, for, for await, break, continue, return |
2 | | -import { expr, skip, space, parse, word, parens, cur, idx, operator, compile } from '../parse.js'; |
| 2 | +import { expr, skip, space, parse, word, parens, cur, idx, operator, compile, next, seek } from '../parse.js'; |
3 | 3 | import { body, keyword } from './block.js'; |
4 | 4 | import { destructure } from './destruct.js'; |
5 | 5 | import { BREAK, CONTINUE, RETURN } from './control.js'; |
@@ -34,8 +34,36 @@ keyword('for', STATEMENT + 1, () => { |
34 | 34 | return ['for', parens(), body()]; |
35 | 35 | }); |
36 | 36 |
|
37 | | -keyword('break', STATEMENT + 1, () => ['break']); |
38 | | -keyword('continue', STATEMENT + 1, () => ['continue']); |
| 37 | +keyword('break', STATEMENT + 1, () => { |
| 38 | + parse.asi && (parse.newline = false); |
| 39 | + const from = idx; |
| 40 | + space(); |
| 41 | + const c = cur.charCodeAt(idx); |
| 42 | + if (!c || c === CBRACE || c === SEMI || parse.newline) return ['break']; |
| 43 | + const label = next(parse.id); |
| 44 | + if (!label) return ['break']; |
| 45 | + // Label must be followed by end/semicolon/newline, not another token |
| 46 | + space(); |
| 47 | + const cc = cur.charCodeAt(idx); |
| 48 | + if (!cc || cc === CBRACE || cc === SEMI || parse.newline) return ['break', label]; |
| 49 | + // Not a valid label - backtrack |
| 50 | + seek(from); |
| 51 | + return ['break']; |
| 52 | +}); |
| 53 | +keyword('continue', STATEMENT + 1, () => { |
| 54 | + parse.asi && (parse.newline = false); |
| 55 | + const from = idx; |
| 56 | + space(); |
| 57 | + const c = cur.charCodeAt(idx); |
| 58 | + if (!c || c === CBRACE || c === SEMI || parse.newline) return ['continue']; |
| 59 | + const label = next(parse.id); |
| 60 | + if (!label) return ['continue']; |
| 61 | + space(); |
| 62 | + const cc = cur.charCodeAt(idx); |
| 63 | + if (!cc || cc === CBRACE || cc === SEMI || parse.newline) return ['continue', label]; |
| 64 | + seek(from); |
| 65 | + return ['continue']; |
| 66 | +}); |
39 | 67 | keyword('return', STATEMENT + 1, () => { |
40 | 68 | parse.asi && (parse.newline = false); |
41 | 69 | space(); |
|
0 commit comments