|
@@ -62,8 +62,8 @@
|
|
|
|
|
|
(def parse-variables (memoize (fn [expression]
|
|
|
(js->clj (.getVariables mathjs expression)))))
|
|
|
-(def evaluate-expressions (memoize (fn [expression variables]
|
|
|
- (.evaluate mathjs expression (clj->js variables)))))
|
|
|
+(def evaluate-expression (memoize (fn [expression variables]
|
|
|
+ (.evaluate mathjs expression (clj->js variables)))))
|
|
|
|
|
|
(defn temp3 [[k v]]
|
|
|
(let [w (name k)
|
|
@@ -90,7 +90,7 @@
|
|
|
parsed (zipmap (keys remaining) evaluated-vars)
|
|
|
not-ready (group-by (fn [[ k v ]] (some #(= :not-yet (last %)) v)) parsed)
|
|
|
;TODO: detect circular references
|
|
|
- prepared (map (fn [[k v]] [k (evaluate-expressions (remaining k) (apply hash-map (flatten v)))]) (not-ready nil))
|
|
|
+ prepared (map (fn [[k v]] [k (evaluate-expression (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 %))) (not-ready true))))]
|
|
|
;remaining ; {:B8 B7 * 2, :C7 D1, :B7 C5 + D6}
|
|
@@ -106,6 +106,73 @@
|
|
|
)
|
|
|
))
|
|
|
|
|
|
+(def str->rc (memoize (fn [s]
|
|
|
+ (let [c (re-find #"^[A-Z]+" s)
|
|
|
+ r (.parseInt js/window (re-find #"[0-9]+$" s))]
|
|
|
+ {:row r :col c}))))
|
|
|
+
|
|
|
+(defn find-cell [data c r]
|
|
|
+ (some #(if (and (= (:col %) c) (= (:row %) r)) %) data))
|
|
|
+(defn find-val [data c r]
|
|
|
+ (let [l (find-cell data c r)
|
|
|
+ v (get l :display (get l :value))]
|
|
|
+ (println "found?" c r v l (get l :value) (get l :display))
|
|
|
+ (cond
|
|
|
+ (nil? v) 0
|
|
|
+ (and (string? v) (= (first v) "=")) :not-yet
|
|
|
+ :else v)))
|
|
|
+(defn copy-display-values' [data display-values]
|
|
|
+ (if (empty? display-values)
|
|
|
+ data
|
|
|
+ (let [v (first display-values)
|
|
|
+ r (:row v)
|
|
|
+ c (:col v)
|
|
|
+ inserted (map #(if (and (= r (:row %)) (= c (:col %)) (= (first (:value %)) "=")) (assoc % :display (:display v)) %) data)]
|
|
|
+ (recur inserted (rest display-values)))))
|
|
|
+(defn copy-display-values [data display-values]
|
|
|
+ (let [removed (map #(-> % (dissoc :vars) (dissoc :refs) (dissoc :found) (dissoc :inputs)) display-values)]
|
|
|
+ (into data removed)))
|
|
|
+
|
|
|
+(defn experimental [data]
|
|
|
+ (let [remove-old-displays (map #(dissoc % :display) data)
|
|
|
+ {has-formula true original-values false} (group-by #(= (first (:value %)) "=") remove-old-displays)
|
|
|
+ ;TODO: detect circular references
|
|
|
+ variables (map #(assoc % :vars (parse-variables (subs (:value %) 1))) has-formula)
|
|
|
+ first-mapped-cell-keys (map (fn [datum] (assoc datum :refs (map str->rc (:vars datum)))) variables)]
|
|
|
+ (loop [values original-values mapped-cell-keys first-mapped-cell-keys]
|
|
|
+ (let [search-values (map (fn [datum] (assoc datum :found (map #(find-val (concat values mapped-cell-keys) (:col %) (:row %)) (:refs datum)))) mapped-cell-keys)
|
|
|
+ {not-ready true ready nil} (group-by (fn [datum] (some #(= :not-yet %) (:found datum))) search-values)
|
|
|
+ prepped-for-eval (map (fn [datum] (assoc datum :inputs (apply hash-map (interleave (:vars datum) (:found datum))))) ready)
|
|
|
+ evaluated (map (fn [datum] (assoc datum :display (evaluate-expression (subs (:value datum) 1) (:inputs datum)))) prepped-for-eval)
|
|
|
+ updated-values (copy-display-values values evaluated)
|
|
|
+ ]
|
|
|
+ (println)
|
|
|
+ (println)
|
|
|
+ (println)
|
|
|
+ (println "has-formula" has-formula)
|
|
|
+ (println "values" values)
|
|
|
+ (println "variables" variables)
|
|
|
+ (println "mapped-cell-keys" mapped-cell-keys)
|
|
|
+ (println "search-values" search-values)
|
|
|
+ (println "not ready to eval" not-ready)
|
|
|
+ (println " nil?" (nil? not-ready))
|
|
|
+ (println "ready to eval" ready)
|
|
|
+ (println "prepped-for-eval" prepped-for-eval)
|
|
|
+ (println "evaluated" evaluated)
|
|
|
+ (println "updated-values" updated-values)
|
|
|
+ (println "done!")
|
|
|
+ (println)
|
|
|
+ (println "loop " values " " mapped-cell-keys)
|
|
|
+ (println "")
|
|
|
+ (println "recur " updated-values " " not-ready)
|
|
|
+ (if (nil? not-ready)
|
|
|
+ updated-values
|
|
|
+ (recur updated-values not-ready)
|
|
|
+ )
|
|
|
+ ))
|
|
|
+ )
|
|
|
+ )
|
|
|
+
|
|
|
;TODO: figure out how to re-evaluate only when the cell modified affects other cells
|
|
|
(defn re-evaluate-data []
|
|
|
(let [rt (temp1 @data-atom)
|
|
@@ -164,6 +231,10 @@
|
|
|
(defn app []
|
|
|
[:div
|
|
|
[:h3 "Microtables"]
|
|
|
+ (do
|
|
|
+ (println "hi again")
|
|
|
+ (experimental @data-atom)
|
|
|
+ "hi again")
|
|
|
[sheet @data-atom]])
|
|
|
|
|
|
;; -------------------------
|