js-on-sx: rest in array pattern + nested pattern tolerance
Array destructure now supports [a, ...rest]. Rest entry is transpiled to (define name (js-list-slice tmp i (len tmp))). Nested patterns like [[a,b], c] now parse (as holes) instead of erroring. jp-skip-balanced skips nested groups. 440/442 unit (+2), 148/148 slice unchanged.
This commit is contained in:
@@ -900,6 +900,29 @@
|
|||||||
(append! names nil)
|
(append! names nil)
|
||||||
(jp-advance! st)
|
(jp-advance! st)
|
||||||
(jp-parse-arr-pattern-loop st names)))
|
(jp-parse-arr-pattern-loop st names)))
|
||||||
|
((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))))
|
||||||
|
((jp-at? st "punct" "[")
|
||||||
|
(begin
|
||||||
|
(jp-skip-balanced st "[" "]")
|
||||||
|
(append! names nil)
|
||||||
|
(cond
|
||||||
|
((jp-at? st "punct" ",")
|
||||||
|
(begin (jp-advance! st) (jp-parse-arr-pattern-loop st names)))
|
||||||
|
(else nil))))
|
||||||
|
((jp-at? st "punct" "{")
|
||||||
|
(begin
|
||||||
|
(jp-skip-balanced st "{" "}")
|
||||||
|
(append! names nil)
|
||||||
|
(cond
|
||||||
|
((jp-at? st "punct" ",")
|
||||||
|
(begin (jp-advance! st) (jp-parse-arr-pattern-loop st names)))
|
||||||
|
(else nil))))
|
||||||
(else
|
(else
|
||||||
(begin
|
(begin
|
||||||
(let
|
(let
|
||||||
@@ -909,11 +932,39 @@
|
|||||||
(jp-advance! st)
|
(jp-advance! st)
|
||||||
(error "expected ident in arr pattern"))
|
(error "expected ident in arr pattern"))
|
||||||
(append! names nm))
|
(append! names nm))
|
||||||
|
(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-arr-pattern-loop st names)))
|
(begin (jp-advance! st) (jp-parse-arr-pattern-loop st names)))
|
||||||
(else nil)))))))
|
(else nil)))))))
|
||||||
|
|
||||||
|
(define
|
||||||
|
jp-skip-balanced
|
||||||
|
(fn
|
||||||
|
(st open close)
|
||||||
|
(jp-expect! st "punct" open)
|
||||||
|
(let ((depth 1)) (jp-skip-balanced-loop st open close depth))))
|
||||||
|
|
||||||
|
(define
|
||||||
|
jp-skip-balanced-loop
|
||||||
|
(fn
|
||||||
|
(st open close depth)
|
||||||
|
(cond
|
||||||
|
((<= depth 0) nil)
|
||||||
|
((>= (get st :idx) (len (get st :tokens))) nil)
|
||||||
|
((jp-at? st "punct" open)
|
||||||
|
(begin
|
||||||
|
(jp-advance! st)
|
||||||
|
(jp-skip-balanced-loop st open close (+ depth 1))))
|
||||||
|
((jp-at? st "punct" close)
|
||||||
|
(begin
|
||||||
|
(jp-advance! st)
|
||||||
|
(jp-skip-balanced-loop st open close (- depth 1))))
|
||||||
|
(else
|
||||||
|
(begin (jp-advance! st) (jp-skip-balanced-loop st open close depth))))))
|
||||||
|
|
||||||
(define
|
(define
|
||||||
jp-parse-var-stmt
|
jp-parse-var-stmt
|
||||||
(fn
|
(fn
|
||||||
|
|||||||
@@ -1129,6 +1129,12 @@ cat > "$TMPFILE" << 'EPOCHS'
|
|||||||
(epoch 3003)
|
(epoch 3003)
|
||||||
(eval "(js-eval \"[3,1,2].sort((a,b)=>b-a).join(',')\")")
|
(eval "(js-eval \"[3,1,2].sort((a,b)=>b-a).join(',')\")")
|
||||||
|
|
||||||
|
;; ── Phase 11.destruct2: rest in arr pattern, nested tolerance ──
|
||||||
|
(epoch 3100)
|
||||||
|
(eval "(js-eval \"var [h, ...tl] = [1,2,3,4]; tl.length\")")
|
||||||
|
(epoch 3101)
|
||||||
|
(eval "(js-eval \"var [h, ...tl] = [1,2,3,4]; tl.join(',')\")")
|
||||||
|
|
||||||
EPOCHS
|
EPOCHS
|
||||||
|
|
||||||
|
|
||||||
@@ -1740,6 +1746,10 @@ check 3001 "sort lex (10<5)" '"10,20,5"'
|
|||||||
check 3002 "sort numeric" '"1,2,3"'
|
check 3002 "sort numeric" '"1,2,3"'
|
||||||
check 3003 "sort reverse" '"3,2,1"'
|
check 3003 "sort reverse" '"3,2,1"'
|
||||||
|
|
||||||
|
# ── Phase 11.destruct2 ────────────────────────────────────────
|
||||||
|
check 3100 "rest arr length" '3'
|
||||||
|
check 3101 "rest arr join" '"2,3,4"'
|
||||||
|
|
||||||
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"
|
||||||
|
|||||||
@@ -951,6 +951,17 @@
|
|||||||
((empty? names) tail)
|
((empty? names) tail)
|
||||||
((= (first names) nil)
|
((= (first names) nil)
|
||||||
(js-vardecl-arr-forms (rest names) tmp-sym (+ i 1) tail))
|
(js-vardecl-arr-forms (rest names) tmp-sym (+ i 1) tail))
|
||||||
|
((and (list? (first names)) (= (first (first names)) "rest"))
|
||||||
|
(cons
|
||||||
|
(list
|
||||||
|
(js-sym "define")
|
||||||
|
(js-sym (nth (first names) 1))
|
||||||
|
(list
|
||||||
|
(js-sym "js-list-slice")
|
||||||
|
tmp-sym
|
||||||
|
i
|
||||||
|
(list (js-sym "len") tmp-sym)))
|
||||||
|
tail))
|
||||||
(else
|
(else
|
||||||
(cons
|
(cons
|
||||||
(list
|
(list
|
||||||
|
|||||||
Reference in New Issue
Block a user