dict pattern matching

This commit is contained in:
Scott Richmond 2024-05-19 20:19:00 -04:00
parent d249ee0b21
commit 1120f21df2

View File

@ -126,7 +126,49 @@
(set (ctx (bindings i)) (matches i)))
{: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]
(print "in match-pattern, matching " value " with:")
@ -497,7 +539,7 @@
(def parsed (p/parse scanned))
(when (has-errors? parsed) (break (parsed :errors)))
(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]))
# (pp cleaned)
(interpret (parsed :ast) @{:^parent b/ctx})
@ -508,13 +550,9 @@
(do
(set source `
fn foobar {
(:foo, :bar) -> :foobar!
(_, _) -> :not_foobar
}
let bar = foobar (:foo, _)
bar (:baz)
let #{:a ay, :b (:ok, bee), ...c} = #{:a 1, :b (:ok, 42), :c 3}
`)
(def result (run))
# (b/show result)
)