Browse Source

created cleaner version of re-evaluate function (not yet integrated)

Brandon Wong 4 years ago
parent
commit
2ea44d48d9
1 changed files with 74 additions and 3 deletions
  1. 74 3
      frontend/src/microtables_frontend/core.cljs

+ 74 - 3
frontend/src/microtables_frontend/core.cljs

@@ -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]])
 
 ;; -------------------------