 
 ;; efficient implementation of stack queries (maybe only compile the watched fn?)
 ;; efficient implementation of cursors (maybe via side-vars)
+;; passing a copy of vars into run-match is a messy hack
 
 ;; interpreter
 


(step-example example-d [] {"counter" 0})

(take 10 (iterate #(step-example example-d [] %) {"counter" 0}))

(defn print-stack
  ([frame]
   (print-stack 0 frame))
  ([indent frame]
   (println (.join (make-array indent) " ") "=>" (.-id frame) (.-vars frame))
   (doseq [call (.-calls frame)]
     (print-stack (+ indent 2) call))
   (when (js* "('result' in ~{frame})") ; seriously?

                     (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

