@@ -317,6 +317,22 @@ fn emit_expr(toks: read List<Tok>, start: read Int, end: read Int, d: read Int)
317317 emit_expr(toks: read toks, start: read (s + 1), end: read e, d: read (d + 1))
318318 return Unit
319319 }
320+ // Prefix expression forms `manage X` / `spawn X` / `await X` (value child).
321+ if is_kw_text(toks: read toks, i: read s, word: read "manage") {
322+ emit(depth: read d, s: read "manage")
323+ emit_expr(toks: read toks, start: read (s + 1), end: read e, d: read (d + 1))
324+ return Unit
325+ }
326+ if is_kw_text(toks: read toks, i: read s, word: read "spawn") {
327+ emit(depth: read d, s: read "spawn")
328+ emit_expr(toks: read toks, start: read (s + 1), end: read e, d: read (d + 1))
329+ return Unit
330+ }
331+ if is_kw_text(toks: read toks, i: read s, word: read "await") {
332+ emit(depth: read d, s: read "await")
333+ emit_expr(toks: read toks, start: read (s + 1), end: read e, d: read (d + 1))
334+ return Unit
335+ }
320336 emit_postfix(toks: read toks, start: read s, end: read e, d: read d)
321337 return Unit
322338}
@@ -1090,6 +1106,18 @@ fn emit_stmt(toks: read List<Tok>, start: read Int, limit: read Int, d: read Int
10901106 if is_kw_text(toks: read toks, i: read start, word: read "await") && is_kw_text(toks: read toks, i: read (start + 1), word: read "for") {
10911107 return emit_for(toks: read toks, forPos: read (start + 1), limit: read limit, d: read d, isAsync: read true)
10921108 }
1109+ // with <resource > as <binding > { body }
1110+ if is_kw_text(toks: read toks, i: read start, word: read "with") {
1111+ return emit_with(toks: read toks, start: read start, limit: read limit, d: read d)
1112+ }
1113+ // task_group { body }
1114+ if is_kw_text(toks: read toks, i: read start, word: read "task_group") {
1115+ return emit_task_group(toks: read toks, start: read start, limit: read limit, d: read d)
1116+ }
1117+ // select { arms }
1118+ if is_kw_text(toks: read toks, i: read start, word: read "select") {
1119+ return emit_select(toks: read toks, start: read start, limit: read limit, d: read d)
1120+ }
10931121 // break / continue
10941122 if is_kw_text(toks: read toks, i: read start, word: read "break") {
10951123 emit(depth: read d, s: read "break")
@@ -1204,6 +1232,98 @@ fn emit_for(toks: read List<Tok>, forPos: read Int, limit: read Int, d: read Int
12041232 return close + 1
12051233}
12061234
1235+ // with <resource > as <binding > { body }. Mirrors parse_with_stmt: the FIRST `as`
1236+ // (not depth-aware) splits resource from binding; `as` must be immediately before
1237+ // the body brace.
1238+ fn emit_with(toks: read List<Tok >, start: read Int, limit: read Int, d: read Int) -> Int {
1239+ let mut asIdx = -1
1240+ let mut i = start + 1
1241+ while i < limit && asIdx < 0 {
1242+ if is_kw_text(toks: read toks, i: read i, word: read "as") { asIdx = i }
1243+ i = i + 1
1244+ }
1245+ if asIdx < 0 {
1246+ emit(depth: read d, s: read "malformed-with")
1247+ return stmt_end(toks: read toks, start: read start, limit: read limit)
1248+ }
1249+ let open = find_block_open(toks: read toks, start: read (asIdx + 1), limit: read limit)
1250+ if open < 0 {
1251+ emit(depth: read d, s: read "malformed-with")
1252+ return stmt_end(toks: read toks, start: read start, limit: read limit)
1253+ }
1254+ let close = find_matching(toks: read toks, open: read open, openSym: read SYM_LBRACE, closeSym: read SYM_RBRACE)
1255+ let binding = tk_text(toks: read toks, i: read (asIdx + 1))
1256+ emit(depth: read d, s: read String.concat(left: read "with binding=", right: read binding))
1257+ emit(depth: read (d + 1), s: read "resource")
1258+ emit_expr(toks: read toks, start: read (start + 1), end: read asIdx, d: read (d + 2))
1259+ emit_block(toks: read toks, open: read open, close: read close, d: read (d + 1))
1260+ return close + 1
1261+ }
1262+
1263+ // task_group { body }
1264+ fn emit_task_group(toks: read List<Tok >, start: read Int, limit: read Int, d: read Int) -> Int {
1265+ let open = start + 1
1266+ if at_symbol(toks: read toks, i: read open, code: read SYM_LBRACE) == false {
1267+ emit(depth: read d, s: read "unknown-stmt")
1268+ return stmt_end(toks: read toks, start: read start, limit: read limit)
1269+ }
1270+ let close = find_matching(toks: read toks, open: read open, openSym: read SYM_LBRACE, closeSym: read SYM_RBRACE)
1271+ emit(depth: read d, s: read "task-group")
1272+ emit_block(toks: read toks, open: read open, close: read close, d: read (d + 1))
1273+ return close + 1
1274+ }
1275+
1276+ // select { <binding > = <operation > => { body } ... }
1277+ fn emit_select(toks: read List<Tok >, start: read Int, limit: read Int, d: read Int) -> Int {
1278+ let open = start + 1
1279+ if at_symbol(toks: read toks, i: read open, code: read SYM_LBRACE) == false {
1280+ emit(depth: read d, s: read "unknown-stmt")
1281+ return stmt_end(toks: read toks, start: read start, limit: read limit)
1282+ }
1283+ let close = find_matching(toks: read toks, open: read open, openSym: read SYM_LBRACE, closeSym: read SYM_RBRACE)
1284+ emit(depth: read d, s: read "select")
1285+ emit_select_arms(toks: read toks, start: read (open + 1), end: read close, d: read (d + 1))
1286+ return close + 1
1287+ }
1288+
1289+ fn emit_select_arms(toks: read List<Tok >, start: read Int, end: read Int, d: read Int) -> Unit {
1290+ let mut i = start
1291+ while i < end {
1292+ if at_symbol(toks: read toks, i: read i, code: read SYM_SEMI) {
1293+ i = i + 1
1294+ } else {
1295+ let lineEnd = next_line_or_block_end(toks: read toks, start: read i, end: read end)
1296+ let arrow = find_top_sym(toks: read toks, start: read i, end: read lineEnd, code: read SYM_FATARROW)
1297+ if arrow < 0 {
1298+ if lineEnd > i { i = lineEnd } else { i = i + 1 }
1299+ } else {
1300+ let eq = find_top_sym(toks: read toks, start: read i, end: read arrow, code: read SYM_EQ)
1301+ if eq < 0 {
1302+ i = arrow + 1
1303+ } else {
1304+ let mut binding = "_"
1305+ if is_ident_tok(toks: read toks, i: read i) { binding = tk_text(toks: read toks, i: read i) }
1306+ emit(depth: read d, s: read String.concat(left: read "select-arm binding=", right: read binding))
1307+ emit(depth: read (d + 1), s: read "operation")
1308+ emit_expr(toks: read toks, start: read (eq + 1), end: read arrow, d: read (d + 2))
1309+ let bodyStart = arrow + 1
1310+ if at_symbol(toks: read toks, i: read bodyStart, code: read SYM_LBRACE) {
1311+ let bclose = find_matching(toks: read toks, open: read bodyStart, openSym: read SYM_LBRACE, closeSym: read SYM_RBRACE)
1312+ emit_block(toks: read toks, open: read bodyStart, close: read bclose, d: read (d + 1))
1313+ i = bclose + 1
1314+ } else {
1315+ let bEnd = next_line_or_block_end(toks: read toks, start: read bodyStart, end: read end)
1316+ emit(depth: read (d + 1), s: read "block")
1317+ emit_stmt(toks: read toks, start: read bodyStart, limit: read bEnd, d: read (d + 2))
1318+ if bEnd > i { i = bEnd } else { i = i + 1 }
1319+ }
1320+ }
1321+ }
1322+ }
1323+ }
1324+ return Unit
1325+ }
1326+
12071327fn emit_loop(toks: read List<Tok >, start: read Int, limit: read Int, d: read Int) -> Int {
12081328 let isWhile = is_kw_text(toks: read toks, i: read start, word: read "while")
12091329 let openb = find_block_open(toks: read toks, start: read (start + 1), limit: read limit)
0 commit comments