dict pattern matching
This commit is contained in:
parent
d249ee0b21
commit
1120f21df2
|
@ -126,7 +126,49 @@
|
||||||
(set (ctx (bindings i)) (matches i)))
|
(set (ctx (bindings i)) (matches i)))
|
||||||
{:success true :ctx ctx})
|
{:success true :ctx ctx})
|
||||||
|
|
||||||
(defn- match-dict [pattern value ctx] (todo "dict pattern"))
|
(defn- match-dict [pattern value ctx]
|
||||||
|
(when (not (table? value))
|
||||||
|
(break {:success false :miss [pattern value]}))
|
||||||
|
(def val-size (length value))
|
||||||
|
(var members (pattern :data))
|
||||||
|
(def patt-len (length members))
|
||||||
|
(when (empty? members)
|
||||||
|
(break (if (empty? value)
|
||||||
|
{:success true :ctx ctx}
|
||||||
|
{:success false :miss [pattern value]})))
|
||||||
|
(var splat nil)
|
||||||
|
(def splat? (= :splat ((last members) :type)))
|
||||||
|
(when splat?
|
||||||
|
(when (< val-size patt-len)
|
||||||
|
(print "mismatched splatted dict lengths")
|
||||||
|
(break {:success false :miss [pattern value]}))
|
||||||
|
(print "splat!")
|
||||||
|
(set splat (last members))
|
||||||
|
(set members (slice members 0 (dec patt-len))))
|
||||||
|
(when (and (not splat?) (not= val-size patt-len))
|
||||||
|
(print "mismatched dict lengths")
|
||||||
|
(break {:success false :miss [pattern value]}))
|
||||||
|
(var success true)
|
||||||
|
(def matched-keys @[])
|
||||||
|
(for i 0 (length members)
|
||||||
|
(def curr-pair (get members i))
|
||||||
|
(def [curr-key curr-patt] (curr-pair :data))
|
||||||
|
(def key (interpret curr-key ctx))
|
||||||
|
(def curr-val (value key))
|
||||||
|
(def match? (match-pattern curr-patt curr-val ctx))
|
||||||
|
(array/push matched-keys key)
|
||||||
|
(when (not (match? :success))
|
||||||
|
(set success false)
|
||||||
|
(break)))
|
||||||
|
(when (and splat? (splat :data) success)
|
||||||
|
(def rest (merge value))
|
||||||
|
(each key matched-keys
|
||||||
|
(set (rest key) nil))
|
||||||
|
(match-word (splat :data) rest ctx))
|
||||||
|
(if success
|
||||||
|
{:success true :ctx ctx}
|
||||||
|
{:success false :miss [pattern value]}))
|
||||||
|
|
||||||
|
|
||||||
(defn- match-pattern* [pattern value &opt ctx]
|
(defn- match-pattern* [pattern value &opt ctx]
|
||||||
(print "in match-pattern, matching " value " with:")
|
(print "in match-pattern, matching " value " with:")
|
||||||
|
@ -497,7 +539,7 @@
|
||||||
(def parsed (p/parse scanned))
|
(def parsed (p/parse scanned))
|
||||||
(when (has-errors? parsed) (break (parsed :errors)))
|
(when (has-errors? parsed) (break (parsed :errors)))
|
||||||
(def validated (v/valid parsed b/ctx))
|
(def validated (v/valid parsed b/ctx))
|
||||||
(when (has-errors? validated) (break (validated :errors)))
|
# (when (has-errors? validated) (break (validated :errors)))
|
||||||
# (def cleaned (get-in parsed [:ast :data 1]))
|
# (def cleaned (get-in parsed [:ast :data 1]))
|
||||||
# (pp cleaned)
|
# (pp cleaned)
|
||||||
(interpret (parsed :ast) @{:^parent b/ctx})
|
(interpret (parsed :ast) @{:^parent b/ctx})
|
||||||
|
@ -508,13 +550,9 @@
|
||||||
|
|
||||||
(do
|
(do
|
||||||
(set source `
|
(set source `
|
||||||
fn foobar {
|
let #{:a ay, :b (:ok, bee), ...c} = #{:a 1, :b (:ok, 42), :c 3}
|
||||||
(:foo, :bar) -> :foobar!
|
|
||||||
(_, _) -> :not_foobar
|
|
||||||
}
|
|
||||||
let bar = foobar (:foo, _)
|
|
||||||
bar (:baz)
|
|
||||||
`)
|
`)
|
||||||
(def result (run))
|
(def result (run))
|
||||||
|
# (b/show result)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user