js-on-sx: for..of / for..in + more Array methods

Parser: jp-parse-for-stmt does 2-token lookahead for (var? ident
(of|in) expr), emits (js-for-of-in kind ident iter body) else
classic (js-for init cond step body).

Transpile: wraps body in (call/cc (__break__) (let items
(for-each (fn (ident) (call/cc (__continue__) body)) items))).

Runtime: js-iterable-to-list normalizes list/string/dict for of
iteration; js-string-to-list expands string to char list.

399/401 unit (+8), 148/148 slice unchanged.
This commit is contained in:
2026-04-23 21:41:52 +00:00
parent ee16e358f3
commit f113b45d48
5 changed files with 120 additions and 14 deletions

View File

@@ -92,6 +92,12 @@
(nth ast 2)
(nth ast 3)
(nth ast 4)))
((js-tag? ast "js-for-of-in")
(js-transpile-for-of-in
(nth ast 1)
(nth ast 2)
(nth ast 3)
(nth ast 4)))
((js-tag? ast "js-return") (js-transpile-return (nth ast 1)))
((js-tag? ast "js-break") (js-transpile-break))
((js-tag? ast "js-continue") (js-transpile-continue))
@@ -643,6 +649,42 @@
(for-each (fn (stmt) (append! forms (js-transpile stmt))) body)
(cons (js-sym "begin") forms))))
(define
js-transpile-for-of-in
(fn
(iter-kind ident iter-ast body-ast)
(let
((ident-sym (js-sym ident))
(iter-sx (js-transpile iter-ast))
(body-sx (js-transpile body-ast))
(items-sym (js-sym "__js_items__")))
(list
(js-sym "call/cc")
(list
(js-sym "fn")
(list (js-sym "__break__"))
(list
(js-sym "let")
(list
(list
items-sym
(if
(= iter-kind "of")
(list (js-sym "js-iterable-to-list") iter-sx)
(list (js-sym "js-object-keys") iter-sx))))
(list
(js-sym "for-each")
(list
(js-sym "fn")
(list ident-sym)
(list
(js-sym "call/cc")
(list
(js-sym "fn")
(list (js-sym "__continue__"))
body-sx)))
items-sym)))))))
(define
js-param-sym
(fn