Fix bug allowing repeated name in tuples
This commit is contained in:
parent
a56a4b565a
commit
df511ce5eb
|
@ -34,26 +34,49 @@
|
||||||
|
|
||||||
(declare interpret-ast match interpret interpret-file)
|
(declare interpret-ast match interpret interpret-file)
|
||||||
|
|
||||||
|
(defn- match-splatted-tuple [pattern value ctx-vol]
|
||||||
|
(let [length (:length pattern) members (:members pattern)
|
||||||
|
ctx-diff (volatile! @ctx-vol)]
|
||||||
|
(if (> length (count value))
|
||||||
|
{:success false :reason "Could not match tuple lengths"}
|
||||||
|
(loop [i 0 ctx {}]
|
||||||
|
(if (= (dec length) i)
|
||||||
|
(
|
||||||
|
;; TODO: write the actual splat here
|
||||||
|
;; check if the name is already bound
|
||||||
|
;; then pack everything into a list
|
||||||
|
;; and return success with the list bound to the name
|
||||||
|
)
|
||||||
|
(let [match? (match (nth members i) (nth value (inc i)) ctx-diff)]
|
||||||
|
(if (:success match?)
|
||||||
|
(recur (inc i) (vswap! ctx-diff #(merge % (:ctx match?))))
|
||||||
|
{:success :false :reason (str "Could not match " pattern " with " value)}
|
||||||
|
)))))))
|
||||||
|
|
||||||
(defn- match-tuple [pattern value ctx-vol]
|
(defn- match-tuple [pattern value ctx-vol]
|
||||||
(cond
|
(cond
|
||||||
(not (vector? value)) {:success false :reason "Could not match non-tuple value to tuple"}
|
(not (vector? value)) {:success false :reason "Could not match non-tuple value to tuple"}
|
||||||
|
|
||||||
(not (= ::data/tuple (first value))) {:success false :reason "Could not match list to tuple"}
|
(not (= ::data/tuple (first value))) {:success false :reason "Could not match list to tuple"}
|
||||||
|
|
||||||
|
(= ::ast/splat (::ast/type (last (:members pattern))))
|
||||||
|
(match-splatted-tuple pattern value ctx-vol)
|
||||||
|
|
||||||
(not (= (:length pattern) (dec (count value))))
|
(not (= (:length pattern) (dec (count value))))
|
||||||
{:success false :reason "Cannot match tuples of different lengths"}
|
{:success false :reason "Cannot match tuples of different lengths"}
|
||||||
|
|
||||||
(= 0 (:length pattern) (dec (count value))) {:success true :ctx {}}
|
(= 0 (:length pattern) (dec (count value))) {:success true :ctx {}}
|
||||||
|
|
||||||
:else (let [members (:members pattern)]
|
:else (let [members (:members pattern)
|
||||||
|
ctx-diff (volatile! @ctx-vol)]
|
||||||
(loop [i (:length pattern)
|
(loop [i (:length pattern)
|
||||||
ctx {}]
|
ctx {}]
|
||||||
(if (= 0 i)
|
(if (= 0 i)
|
||||||
{:success true :ctx ctx}
|
{:success true :ctx ctx}
|
||||||
(let [match? (match (nth members (dec i)) (nth value i) ctx-vol)]
|
(let [match? (match (nth members (dec i)) (nth value i) ctx-diff)]
|
||||||
(if (:success match?)
|
(if (:success match?)
|
||||||
(recur (dec i) (merge ctx (:ctx match?)))
|
(recur (dec i) (vswap! ctx-diff #(merge % (:ctx match?))))
|
||||||
{:success false :reason (str "Could not match " pattern " with " value)})))))))
|
{:success false :reason (str "Could not match " pattern " with " value " because " (:reason match?))})))))))
|
||||||
|
|
||||||
(defn- match-list [pattern value ctx-vol]
|
(defn- match-list [pattern value ctx-vol]
|
||||||
(cond
|
(cond
|
||||||
|
@ -661,14 +684,10 @@
|
||||||
)))))
|
)))))
|
||||||
|
|
||||||
|
|
||||||
(comment
|
(do
|
||||||
(process/start-vm)
|
(process/start-vm)
|
||||||
(def source "
|
(def source "
|
||||||
let foo = (:a, :b)
|
let (a, b) = (1, 2)
|
||||||
|
|
||||||
if let (x, y) = foo then :foo else :bar
|
|
||||||
|
|
||||||
y
|
|
||||||
|
|
||||||
")
|
")
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user