From 9984a6c8ec76b3271ab52f14738d647cd3d8c21c Mon Sep 17 00:00:00 2001 From: Scott Richmond Date: Thu, 19 May 2022 19:27:32 -0400 Subject: [PATCH] Add basic list matching --- src/ludus/interpreter.clj | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/ludus/interpreter.clj b/src/ludus/interpreter.clj index 962c6ec..725139a 100644 --- a/src/ludus/interpreter.clj +++ b/src/ludus/interpreter.clj @@ -43,6 +43,28 @@ (recur (dec i) (merge ctx (:ctx match?))) {:success false :reason (str "Could not match " pattern " with " value)}))))))) +(defn- match-list [pattern value ctx-vol] + (cond + (not (vector? value)) {:success false :reason "Could not match non-list value to list"} + + (= ::data/tuple (first value)) {:success false :reason "Could not match tuple value to list pattern"} + + ;; TODO: fix this with splats + (not (= (count (:members pattern)) (count value))) + {:success false :reason "Cannot match lists of different lengths"} + + (= 0 (count (:members pattern)) (count value)) {:success true :ctx {}} + + :else (let [members (:members pattern)] + (loop [i (dec (count members)) + ctx {}] + (if (> 0 i) + {:success true :ctx ctx} + (let [match? (match (nth members i) (nth value i) ctx-vol)] + (if (:success match?) + (recur (dec i) (merge ctx (:ctx match?))) + {:success false :reason (str "Could not match " pattern " with " value)}))))))) + (defn- match [pattern value ctx-vol] (let [ctx @ctx-vol] (case (::ast/type pattern) @@ -63,6 +85,8 @@ ::ast/tuple (match-tuple pattern value ctx-vol) + ::ast/list (match-list pattern value ctx-vol) + (throw (ex-info "Unknown pattern on line " {:pattern pattern}))))) (defn- update-ctx [ctx new-ctx] @@ -407,10 +431,13 @@ (println (ex-message e)) (pp/pprint (ex-data e))))) -(comment +(do (def source " + let [1, 2, x] = [1, 2, 3] + + x ")