js-on-sx: object + array destructuring
Parser: jp-parse-vardecl handles {a, b} obj pattern and [a, , c]
arr pattern (with hole support) in addition to plain idents.
Emits (js-vardecl-obj names rhs) and (js-vardecl-arr names rhs).
Transpile: js-vardecl-forms dispatches on tag. Destructures emit
(define __destruct__ rhs) then (define name (js-get-prop __destruct__
key-or-index)) for each pattern element. Array holes (nil) are skipped.
418/420 unit (+4), 148/148 slice unchanged.
This commit is contained in:
108
lib/js/parser.sx
108
lib/js/parser.sx
@@ -781,20 +781,102 @@
|
||||
jp-parse-vardecl
|
||||
(fn
|
||||
(st)
|
||||
(let
|
||||
((nm (get (jp-peek st) :value)))
|
||||
(do
|
||||
(if
|
||||
(= (get (jp-peek st) :type) "ident")
|
||||
(jp-advance! st)
|
||||
(error
|
||||
(str "Expected ident in var decl, got " (get (jp-peek st) :type))))
|
||||
(if
|
||||
(jp-at? st "op" "=")
|
||||
(do
|
||||
(cond
|
||||
((jp-at? st "punct" "{")
|
||||
(let
|
||||
((pattern (jp-parse-obj-pattern st)))
|
||||
(jp-expect! st "op" "=")
|
||||
(list (quote js-vardecl-obj) pattern (jp-parse-assignment st))))
|
||||
((jp-at? st "punct" "[")
|
||||
(let
|
||||
((pattern (jp-parse-arr-pattern st)))
|
||||
(jp-expect! st "op" "=")
|
||||
(list (quote js-vardecl-arr) pattern (jp-parse-assignment st))))
|
||||
(else
|
||||
(let
|
||||
((nm (get (jp-peek st) :value)))
|
||||
(if
|
||||
(= (get (jp-peek st) :type) "ident")
|
||||
(jp-advance! st)
|
||||
(list (quote js-vardecl) nm (jp-parse-assignment st)))
|
||||
(list (quote js-vardecl) nm (list (quote js-undef))))))))
|
||||
(error
|
||||
(str
|
||||
"Expected ident in var decl, got "
|
||||
(get (jp-peek st) :type))))
|
||||
(if
|
||||
(jp-at? st "op" "=")
|
||||
(begin
|
||||
(jp-advance! st)
|
||||
(list (quote js-vardecl) nm (jp-parse-assignment st)))
|
||||
(list (quote js-vardecl) nm (list (quote js-undef)))))))))
|
||||
|
||||
(define
|
||||
jp-parse-obj-pattern
|
||||
(fn
|
||||
(st)
|
||||
(jp-advance! st)
|
||||
(let
|
||||
((names (list)))
|
||||
(jp-parse-obj-pattern-loop st names)
|
||||
(jp-expect! st "punct" "}")
|
||||
names)))
|
||||
|
||||
(define
|
||||
jp-parse-obj-pattern-loop
|
||||
(fn
|
||||
(st names)
|
||||
(cond
|
||||
((jp-at? st "punct" "}") nil)
|
||||
(else
|
||||
(begin
|
||||
(let
|
||||
((nm (get (jp-peek st) :value)))
|
||||
(if
|
||||
(or
|
||||
(= (get (jp-peek st) :type) "ident")
|
||||
(= (get (jp-peek st) :type) "string"))
|
||||
(jp-advance! st)
|
||||
(error "expected ident in obj pattern"))
|
||||
(append! names nm))
|
||||
(cond
|
||||
((jp-at? st "punct" ",")
|
||||
(begin (jp-advance! st) (jp-parse-obj-pattern-loop st names)))
|
||||
(else nil)))))))
|
||||
|
||||
(define
|
||||
jp-parse-arr-pattern
|
||||
(fn
|
||||
(st)
|
||||
(jp-advance! st)
|
||||
(let
|
||||
((names (list)))
|
||||
(jp-parse-arr-pattern-loop st names)
|
||||
(jp-expect! st "punct" "]")
|
||||
names)))
|
||||
|
||||
(define
|
||||
jp-parse-arr-pattern-loop
|
||||
(fn
|
||||
(st names)
|
||||
(cond
|
||||
((jp-at? st "punct" "]") nil)
|
||||
((jp-at? st "punct" ",")
|
||||
(begin
|
||||
(append! names nil)
|
||||
(jp-advance! st)
|
||||
(jp-parse-arr-pattern-loop st names)))
|
||||
(else
|
||||
(begin
|
||||
(let
|
||||
((nm (get (jp-peek st) :value)))
|
||||
(if
|
||||
(= (get (jp-peek st) :type) "ident")
|
||||
(jp-advance! st)
|
||||
(error "expected ident in arr pattern"))
|
||||
(append! names nm))
|
||||
(cond
|
||||
((jp-at? st "punct" ",")
|
||||
(begin (jp-advance! st) (jp-parse-arr-pattern-loop st names)))
|
||||
(else nil)))))))
|
||||
|
||||
(define
|
||||
jp-parse-var-stmt
|
||||
|
||||
Reference in New Issue
Block a user