diff --git a/lib/js/parser.sx b/lib/js/parser.sx index 9c90db85..3f593dd3 100644 --- a/lib/js/parser.sx +++ b/lib/js/parser.sx @@ -862,17 +862,45 @@ (st names) (cond ((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 (begin (let - ((nm (get (jp-peek st) :value))) + ((key (get (jp-peek st) :value))) (if (or (= (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) - (error "expected ident in obj pattern")) - (append! names nm)) + (error "expected key in obj pattern")) + (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 ((jp-at? st "punct" ",") (begin (jp-advance! st) (jp-parse-obj-pattern-loop st names))) diff --git a/lib/js/test.sh b/lib/js/test.sh index a07ce1f0..97491cd1 100755 --- a/lib/js/test.sh +++ b/lib/js/test.sh @@ -1135,6 +1135,12 @@ cat > "$TMPFILE" << 'EPOCHS' (epoch 3101) (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 @@ -1750,6 +1756,10 @@ check 3003 "sort reverse" '"3,2,1"' check 3100 "rest arr length" '3' 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)) if [ $FAIL -eq 0 ]; then echo "✓ $PASS/$TOTAL JS-on-SX tests passed" diff --git a/lib/js/transpile.sx b/lib/js/transpile.sx index ea7ebe6e..90aa57d8 100644 --- a/lib/js/transpile.sx +++ b/lib/js/transpile.sx @@ -935,6 +935,17 @@ (names tmp-sym tail) (cond ((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 (cons (list