js-on-sx: obj destructure rename + rest + nested tolerance

Pattern {key: local-name} emits ("rename" key local). Transpile
emits (define local (js-get-prop tmp key)).

Rest in obj pattern stubs (no supported), nested {} and [] treated
as holes.

442/444 unit (+2), 148/148 slice unchanged.
This commit is contained in:
2026-04-23 23:19:31 +00:00
parent c5e2bc2fe1
commit 9f9e4e1e9d
3 changed files with 53 additions and 4 deletions

View File

@@ -862,17 +862,45 @@
(st names) (st names)
(cond (cond
((jp-at? st "punct" "}") nil) ((jp-at? st "punct" "}") nil)
((jp-at? st "punct" "...")
(begin
(jp-advance! st)
(when
(= (get (jp-peek st) :type) "ident")
(append! names (list "rest" (get (jp-peek st) :value)))
(jp-advance! st))))
(else (else
(begin (begin
(let (let
((nm (get (jp-peek st) :value))) ((key (get (jp-peek st) :value)))
(if (if
(or (or
(= (get (jp-peek st) :type) "ident") (= (get (jp-peek st) :type) "ident")
(= (get (jp-peek st) :type) "string")) (= (get (jp-peek st) :type) "string")
(= (get (jp-peek st) :type) "number"))
(jp-advance! st) (jp-advance! st)
(error "expected ident in obj pattern")) (error "expected key in obj pattern"))
(append! names nm)) (if
(jp-at? st "punct" ":")
(begin
(jp-advance! st)
(cond
((= (get (jp-peek st) :type) "ident")
(begin
(append!
names
(list "rename" key (get (jp-peek st) :value)))
(jp-advance! st)))
((jp-at? st "punct" "{")
(begin (jp-skip-balanced st "{" "}") (append! names nil)))
((jp-at? st "punct" "[")
(begin (jp-skip-balanced st "[" "]") (append! names nil)))
(else
(error "expected ident/pattern after : in obj pattern"))))
(append! names key))
(when
(jp-at? st "op" "=")
(begin (jp-advance! st) (jp-parse-assignment st))))
(cond (cond
((jp-at? st "punct" ",") ((jp-at? st "punct" ",")
(begin (jp-advance! st) (jp-parse-obj-pattern-loop st names))) (begin (jp-advance! st) (jp-parse-obj-pattern-loop st names)))

View File

@@ -1135,6 +1135,12 @@ cat > "$TMPFILE" << 'EPOCHS'
(epoch 3101) (epoch 3101)
(eval "(js-eval \"var [h, ...tl] = [1,2,3,4]; tl.join(',')\")") (eval "(js-eval \"var [h, ...tl] = [1,2,3,4]; tl.join(',')\")")
;; ── Phase 11.destruct3: rename in obj pattern ──────────────────
(epoch 3200)
(eval "(js-eval \"var {aa: x1} = {aa: 100}; x1\")")
(epoch 3201)
(eval "(js-eval \"var {aa: x2, bb: y2} = {aa:1, bb:2}; x2+y2\")")
EPOCHS EPOCHS
@@ -1750,6 +1756,10 @@ check 3003 "sort reverse" '"3,2,1"'
check 3100 "rest arr length" '3' check 3100 "rest arr length" '3'
check 3101 "rest arr join" '"2,3,4"' check 3101 "rest arr join" '"2,3,4"'
# ── Phase 11.destruct3 ────────────────────────────────────────
check 3200 "obj rename" '100'
check 3201 "obj multi rename" '3'
TOTAL=$((PASS + FAIL)) TOTAL=$((PASS + FAIL))
if [ $FAIL -eq 0 ]; then if [ $FAIL -eq 0 ]; then
echo "$PASS/$TOTAL JS-on-SX tests passed" echo "$PASS/$TOTAL JS-on-SX tests passed"

View File

@@ -935,6 +935,17 @@
(names tmp-sym tail) (names tmp-sym tail)
(cond (cond
((empty? names) tail) ((empty? names) tail)
((= (first names) nil)
(js-vardecl-obj-forms (rest names) tmp-sym tail))
((and (list? (first names)) (= (first (first names)) "rename"))
(cons
(list
(js-sym "define")
(js-sym (nth (first names) 2))
(list (js-sym "js-get-prop") tmp-sym (nth (first names) 1)))
(js-vardecl-obj-forms (rest names) tmp-sym tail)))
((and (list? (first names)) (= (first (first names)) "rest"))
(js-vardecl-obj-forms (rest names) tmp-sym tail))
(else (else
(cons (cons
(list (list