mirror of
https://github.com/janet-lang/janet
synced 2024-11-28 19:19:53 +00:00
add support for & _ to match macro
This commit adds support for using & _ syntax to bind the remaining values in an array in the match macro. The commit also adds a few tests for the new syntax in suite0008
This commit is contained in:
parent
0d31674166
commit
db631097b1
@ -1751,10 +1751,18 @@
|
||||
(break)
|
||||
|
||||
# match data structure template
|
||||
(or isarr (= t :struct) (= t :table))
|
||||
(do
|
||||
(when isarr (get-length-sym s))
|
||||
(or (= t :struct) (= t :table))
|
||||
(eachp [i sub-pattern] pattern
|
||||
(visit-pattern-1 b2g s i sub-pattern))
|
||||
|
||||
isarr
|
||||
(do
|
||||
(get-length-sym s)
|
||||
(eachp [i sub-pattern] pattern
|
||||
(when (= sub-pattern '&)
|
||||
# TODO: check that & is followed by something
|
||||
(put b2g (pattern (inc i)) @[[slice s i]])
|
||||
(break))
|
||||
(visit-pattern-1 b2g s i sub-pattern)))
|
||||
|
||||
# match global unification
|
||||
@ -1774,14 +1782,24 @@
|
||||
(def isarr (or (= t :array) (and (= t :tuple) (= (tuple/type pattern) :brackets))))
|
||||
(when isarr
|
||||
(array/push anda (get-length-sym s))
|
||||
(array/push anda [<= (length pattern) (get-length-sym s)]))
|
||||
(def pattern-len
|
||||
(if-let [ rest-idx (find-index (fn [x] (= x '&)) pattern) ]
|
||||
rest-idx
|
||||
(length pattern)))
|
||||
(array/push anda [<= pattern-len (get-length-sym s)]))
|
||||
(cond
|
||||
|
||||
# match data structure template
|
||||
(or isarr (= t :struct) (= t :table))
|
||||
(or (= t :struct) (= t :table))
|
||||
(eachp [i sub-pattern] pattern
|
||||
(when (not isarr)
|
||||
(array/push anda [not= nil (get-sym s i)]))
|
||||
(array/push anda [not= nil (get-sym s i)])
|
||||
(visit-pattern-2 anda gun preds s i sub-pattern))
|
||||
|
||||
isarr
|
||||
(eachp [i sub-pattern] pattern
|
||||
# stop recursing to sub-patterns if the rest sigil is found
|
||||
(when (= sub-pattern '&)
|
||||
(break))
|
||||
(visit-pattern-2 anda gun preds s i sub-pattern))
|
||||
|
||||
# match local binding
|
||||
|
@ -106,6 +106,10 @@
|
||||
(assert (= nil (match {:a :hi} {:a a :b b} a)) "match 3")
|
||||
(assert (= nil (match [1 2] [a b c] a)) "match 4")
|
||||
(assert (= 2 (match [1 2] [a b] b)) "match 5")
|
||||
(assert (= [2 :a :b] (match [1 2 :a :b] [o & rest] rest)) "match 6")
|
||||
(assert (= [] (match @[:a] @[x & r] r :fallback)) "match 7")
|
||||
(assert (= :fallback (match @[1] @[x y & r] r :fallback)) "match 8")
|
||||
(assert (= [1 2 3 4] (match @[1 2 3 4] @[x y z & r] [x y z ;r] :fallback)) "match 9")
|
||||
|
||||
# And/or checks
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user