 (defn check [bool]
   (when-not bool (throw (MatchFailure.))))
 
-(defn run-match [id->node node inputs output stack]
+(defn run-match [id->node node inputs output stack vars]
   (assert (= 1 (count inputs)))
   (let [input (first inputs)]
     (loop [branches (:branches node)]
       (if-let [[{:keys [pattern inputs node]} & branches] (seq branches)]
         (try
-          (let [vars #js {}]
-            (run-match-pattern id->node pattern (:path input) (:value input) output stack vars)
-            (case (:type node)
-              :match/return (do (assert (= 1 (count inputs)))
-                              (aget vars (first inputs)))
-              (run-node id->node node (map #(aget vars %) inputs) output stack)))
+          (run-match-pattern id->node pattern (:path input) (:value input) output stack vars)
+          (case (:type node)
+            :match/return (do (assert (= 1 (count inputs)))
+                            (aget vars (first inputs)))
+            (run-node id->node node (map #(aget vars %) inputs) output stack vars))
           (catch MatchFailure _
             (recur branches)))
         (throw (MatchFailure.))))))


;; efficient implementation of stack queries (maybe only compile the watched fn?)
;; efficient implementation of cursors (maybe via side-vars)

;; interpreter


                     (let [key (:value key-pattern)]
                       (check (contains? input-value key))
                       (run-match-pattern id->node (get value key-pattern) (conj input-path key) (get input-value key) output stack vars)))))
    (check (:value (run-node id->node pattern [(Cursor. input-path input-value)] output stack #js {})))))

(defn run-replace [id->node node inputs output stack]
  (swap! output assoc-in (:path (first inputs)) (:value (second inputs))))

(defn run-output [id->node node inputs output stack]
  (swap! output update-in (:path node) conj (:value (first inputs))))

;; ast

