js-on-sx: var hoisting — hoist var names as undefined before funcdecls
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled

This commit is contained in:
2026-04-25 12:18:42 +00:00
parent f16e1b69c0
commit 11315d91cc
2 changed files with 62 additions and 3 deletions

View File

@@ -1333,6 +1333,15 @@ cat > "$TMPFILE" << 'EPOCHS'
(epoch 4203)
(eval "(let ((toks (js-tokenize \"a b\"))) (get (nth toks 1) :nl))")
(epoch 4300)
(eval "(js-eval \"var x = 5; x\")")
(epoch 4301)
(eval "(js-eval \"function f() { return x; var x = 42; } f()\")")
(epoch 4302)
(eval "(js-eval \"function f() { var y = 7; return y; } f()\")")
(epoch 4303)
(eval "(js-eval \"function f() { var z; z = 3; return z; } f()\")")
EPOCHS
@@ -2058,6 +2067,11 @@ check 4201 "return+space+val → val" '42'
check 4202 "nl-before flag set after newline" 'true'
check 4203 "nl-before flag false on same line" 'false'
check 4300 "var decl program-level" '5'
check 4301 "var hoisted before use → undef" '"js-undefined"'
check 4302 "var in function body" '7'
check 4303 "var then set in function" '3'
TOTAL=$((PASS + FAIL))
if [ $FAIL -eq 0 ]; then
echo "$PASS/$TOTAL JS-on-SX tests passed"

View File

@@ -486,6 +486,51 @@
(append inits (list (js-transpile body))))))))
(list (js-sym "fn") param-syms body-tr))))
(define
js-collect-var-decl-names
(fn
(decls)
(cond
((empty? decls) (list))
((js-tag? (first decls) "js-vardecl")
(cons
(nth (first decls) 1)
(js-collect-var-decl-names (rest decls))))
(else (js-collect-var-decl-names (rest decls))))))
(define
js-collect-var-names
(fn
(stmts)
(cond
((empty? stmts) (list))
((and (list? (first stmts)) (js-tag? (first stmts) "js-var") (= (nth (first stmts) 1) "var"))
(append
(js-collect-var-decl-names (nth (first stmts) 2))
(js-collect-var-names (rest stmts))))
(else (js-collect-var-names (rest stmts))))))
(define
js-dedup-names
(fn
(names seen)
(cond
((empty? names) (list))
((some (fn (s) (= s (first names))) seen)
(js-dedup-names (rest names) seen))
(else
(cons
(first names)
(js-dedup-names (rest names) (cons (first names) seen)))))))
(define
js-var-hoist-forms
(fn
(names)
(map
(fn (name) (list (js-sym "define") (js-sym name) :js-undefined))
names)))
(define
js-transpile-tpl
(fn
@@ -876,7 +921,7 @@
(fn
(stmts)
(let
((hoisted (js-collect-funcdecls stmts)))
((hoisted (append (js-var-hoist-forms (js-dedup-names (js-collect-var-names stmts) (list))) (js-collect-funcdecls stmts))))
(let
((rest-stmts (js-transpile-stmt-list stmts)))
(cons (js-sym "begin") (append hoisted rest-stmts))))))
@@ -1297,7 +1342,7 @@
(if
(and (list? body) (js-tag? body "js-block"))
(let
((hoisted (js-collect-funcdecls (nth body 1))))
((hoisted (append (js-var-hoist-forms (js-dedup-names (js-collect-var-names (nth body 1)) (list))) (js-collect-funcdecls (nth body 1)))))
(append hoisted (js-transpile-stmt-list (nth body 1))))
(list (js-transpile body)))))
(list
@@ -1333,7 +1378,7 @@
(if
(and (list? body) (js-tag? body "js-block"))
(let
((hoisted (js-collect-funcdecls (nth body 1))))
((hoisted (append (js-var-hoist-forms (js-dedup-names (js-collect-var-names (nth body 1)) (list))) (js-collect-funcdecls (nth body 1)))))
(append hoisted (js-transpile-stmt-list (nth body 1))))
(list (js-transpile body)))))
(list