From 1120f21df2327bcb2162f028978ccd8dfea4bc5e Mon Sep 17 00:00:00 2001 From: Scott Richmond Date: Sun, 19 May 2024 20:19:00 -0400 Subject: [PATCH] dict pattern matching --- janet/interpreter.janet | 54 +++++++++++++++++++++++++++++++++++------ 1 file changed, 46 insertions(+), 8 deletions(-) diff --git a/janet/interpreter.janet b/janet/interpreter.janet index bd761ea..35285ea 100644 --- a/janet/interpreter.janet +++ b/janet/interpreter.janet @@ -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) )