|  | @@ -62,6 +62,9 @@
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  (def parse-variables (memoize (fn [expression]
 | 
	
		
			
				|  |  |                                  (js->clj (.getVariables mathjs expression)))))
 | 
	
		
			
				|  |  | +(def evaluate-expressions (memoize (fn [expression variables]
 | 
	
		
			
				|  |  | +                                     (.evaluate mathjs expression (clj->js variables)))))
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  (defn temp3 [[k v]]
 | 
	
		
			
				|  |  |    (let [w (name k)
 | 
	
		
			
				|  |  |          c (re-find #"^[A-Z]+" w)
 | 
	
	
		
			
				|  | @@ -85,26 +88,23 @@
 | 
	
		
			
				|  |  |                                                  :else [% 0]
 | 
	
		
			
				|  |  |                                                  )) x)) vars)
 | 
	
		
			
				|  |  |            parsed (zipmap (keys remaining) evaluated-vars)
 | 
	
		
			
				|  |  | -          ready-or-not (group-by (fn [[ k v ]] (some #(not= :not-yet (last %)) v)) parsed)
 | 
	
		
			
				|  |  | +          not-ready (group-by (fn [[ k v ]] (some #(= :not-yet (last %)) v)) parsed)
 | 
	
		
			
				|  |  |            ;TODO: detect circular references
 | 
	
		
			
				|  |  | -          prepared (map (fn [[k v]] [k (.evaluate mathjs (remaining k) (apply js-obj (flatten v)))]) (ready-or-not true))
 | 
	
		
			
				|  |  | +          prepared (map (fn [[k v]] [k (evaluate-expressions (remaining k) (apply hash-map (flatten v)))]) (not-ready nil))
 | 
	
		
			
				|  |  |            new-evaluated (reduce conj evaluated prepared)
 | 
	
		
			
				|  |  | -          still-remaining (apply hash-map (flatten (map #(list (key %) (remaining (key %))) (ready-or-not nil))))
 | 
	
		
			
				|  |  | -          ;merged (map temp3 prepared) ;TODO: only merge after recursion is complete (outside this function)
 | 
	
		
			
				|  |  | -          ]
 | 
	
		
			
				|  |  | +          still-remaining (apply hash-map (flatten (map #(list (key %) (remaining (key %))) (not-ready true))))]
 | 
	
		
			
				|  |  |        ;remaining ; {:B8 B7 * 2, :C7 D1, :B7 C5 + D6}
 | 
	
		
			
				|  |  |        ;vars ; ([B7] [D1] [C5 D6])
 | 
	
		
			
				|  |  |        ;remaining-vars ; {:B8 [B7], :C7 [D1], :B7 [C5 D6]}
 | 
	
		
			
				|  |  |        ;parsed ; {:B8 ([B7 :not-yet]), :C7 ([D1 0]), :B7 ([C5 269] [D6 4065])}
 | 
	
		
			
				|  |  | -      ;ready-or-not ; {nil [[:B8 ([B7 :not-yet])]], true [[:C7 ([D1 0])] [:B7 ([C5 269] [D6 4065])]]}
 | 
	
		
			
				|  |  | +      ;not-ready ; {true [[:B8 ([B7 :not-yet])]], nil [[:C7 ([D1 0])] [:B7 ([C5 269] [D6 4065])]]}
 | 
	
		
			
				|  |  |        ;prepared ; ([:C7 0] [:B7 4334])
 | 
	
		
			
				|  |  |        ;still-remaining ; {:B8 B7 * 2}
 | 
	
		
			
				|  |  |        ;evaluated; TODO: change name, consider putting "data" directly in here
 | 
	
		
			
				|  |  |        (recur new-evaluated still-remaining)
 | 
	
		
			
				|  |  |        ;new-evaluated
 | 
	
		
			
				|  |  |        )
 | 
	
		
			
				|  |  | -    )
 | 
	
		
			
				|  |  | -  )
 | 
	
		
			
				|  |  | +    ))
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  ;TODO: figure out how to re-evaluate only when the cell modified affects other cells
 | 
	
		
			
				|  |  |  (defn re-evaluate-data []
 | 
	
	
		
			
				|  | @@ -164,36 +164,6 @@
 | 
	
		
			
				|  |  |  (defn app []
 | 
	
		
			
				|  |  |    [:div
 | 
	
		
			
				|  |  |     [:h3 "Microtables"]
 | 
	
		
			
				|  |  | -   #_(do
 | 
	
		
			
				|  |  | -     (println (.stringify js/JSON (.parse mathjs "3 + 4x")))
 | 
	
		
			
				|  |  | -     (println (js->clj (.parse js/JSON (.stringify js/JSON (.parse mathjs "3 + 4x")))))
 | 
	
		
			
				|  |  | -     (println (type (js->clj (.stringify js/JSON (.parse mathjs "3 + 4x")))))
 | 
	
		
			
				|  |  | -     (println (js-obj "a" 2 "b" "one"))
 | 
	
		
			
				|  |  | -     (println (type (js-obj "a" 2 "b" "one")))
 | 
	
		
			
				|  |  | -     (println (type (.parse mathjs "3 + 4x")))
 | 
	
		
			
				|  |  | -     (println (.log js/console (.parse mathjs "3 + 4x")))
 | 
	
		
			
				|  |  | -     (println (.keys js/Object (.parse mathjs "3 + 4x")))
 | 
	
		
			
				|  |  | -     (println (js->clj (.parse mathjs "3 + 4x")))
 | 
	
		
			
				|  |  | -     (println (js->clj (.parse mathjs "3 + 4x") :keywordize-keys true))
 | 
	
		
			
				|  |  | -     (println (.-op (.parse mathjs "3 + 4x")))
 | 
	
		
			
				|  |  | -     (println (.-fn (.parse mathjs "3 + 4x")))
 | 
	
		
			
				|  |  | -     (println (js->clj (.-args (.parse mathjs "3 + 4x"))))
 | 
	
		
			
				|  |  | -     (println (.-comment (.parse mathjs "3 + 4x")))
 | 
	
		
			
				|  |  | -     (println (.-implicit (.parse mathjs "3 + 4x")))
 | 
	
		
			
				|  |  | -     (println (.-value (.parse mathjs "3 + 4x")))
 | 
	
		
			
				|  |  | -     (println (second (.-args (.parse mathjs "3 + 4x"))))
 | 
	
		
			
				|  |  | -     (println (.-implicit (second (.-args (.parse mathjs "3 + 4x")))))
 | 
	
		
			
				|  |  | -     (println (.-op (second (.-args (.parse mathjs "3 + 4x")))))
 | 
	
		
			
				|  |  | -     (println (.-fn (second (.-args (.parse mathjs "3 + 4x")))))
 | 
	
		
			
				|  |  | -     (println (.evaluate mathjs "3 + 4x" (js-obj "x" 10)))
 | 
	
		
			
				|  |  | -     (println (filter #(not= (first (:value %)) "=") @data-atom))
 | 
	
		
			
				|  |  | -     (let [rt (temp1 @data-atom)]
 | 
	
		
			
				|  |  | -       (do
 | 
	
		
			
				|  |  | -         (println rt)
 | 
	
		
			
				|  |  | -         (println (temp2 (:evaluated rt) (:remaining rt)))))
 | 
	
		
			
				|  |  | -     (println "data-atom")
 | 
	
		
			
				|  |  | -     (println @data-atom)
 | 
	
		
			
				|  |  | -     "hi")
 | 
	
		
			
				|  |  |     [sheet @data-atom]])
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  ;; -------------------------
 |