Skip to content

Commit

Permalink
WIP implement a few functions
Browse files Browse the repository at this point in the history
  • Loading branch information
prabhanshuguptagit committed Feb 28, 2024
1 parent 7487761 commit ed42a20
Show file tree
Hide file tree
Showing 5 changed files with 166 additions and 63 deletions.
183 changes: 135 additions & 48 deletions src/bean/functions.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -16,64 +16,151 @@
(reduce str "" args))
(interpreter/eval-asts sheet asts)))

(defn bean-get* [sheet asts & [dirn]]
(defn- make-table-result [sheet table-result new-selection]
(let [new-selection (set new-selection)]
{:matrix (util/map-on-matrix
#(if (get new-selection %)
(util/get-cell (:grid sheet) %)
{:scalar "" :representation ""})
(area/addresses->address-matrix new-selection))
:table (merge table-result
{:selection new-selection})}))

(defn bean-row [sheet asts]
(let [ast-results (interpreter/eval-asts sheet asts)
error (interpreter/first-error ast-results)]
(if-not error
(let [table-result (:table (first ast-results))
label (:scalar (second ast-results))
existing-selection (:selection table-result)
vget-cells (tables/label-name->cells
sheet
(:name table-result) label dirn)
new-selection (set/intersection
vget-cells
existing-selection)]
(if (tables/label? sheet (:name table-result) label dirn)
{:matrix (util/map-on-matrix
#(if (get new-selection %)
(util/get-cell (:grid sheet) %)
{:scalar "" :representation ""})
(area/addresses->address-matrix new-selection))
:table (merge table-result
{:selection new-selection
:selection-dirn dirn})}
(errors/label-not-found
(:scalar (interpreter/eval-ast (second asts) sheet)))))
selection (:selection table-result)
table (tables/get-table sheet (:name table-result))
[start-r start-c] (:start table)
[end-r end-c] (:end table)]
(make-table-result
sheet
table-result
(apply set/union
(map
(fn [[r c]]
(set
(map
#(do [r %])
(range start-c (inc end-c)))))
selection))))
error)))

(defn bean-get [sheet asts]
(bean-get* sheet asts))

(defn bean-vget [sheet asts]
(bean-get* sheet asts :top))
(defn bean-col [sheet asts]
(let [ast-results (interpreter/eval-asts sheet asts)
error (interpreter/first-error ast-results)]
(if-not error
(let [table-result (:table (first ast-results))
selection (:selection table-result)
table (tables/get-table sheet (:name table-result))
[start-r start-c] (:start table)
[end-r end-c] (:end table)]
(make-table-result
sheet
table-result
(apply set/union
(map
(fn [[r c]]
(set
(map
#(do [% c])
(range start-r (inc end-r)))))
selection))))
error)))

(defn bean-hget [sheet asts]
(bean-get* sheet asts :left))
(defn bean-reduce [sheet asts]
(let [ast-results (interpreter/eval-asts sheet asts)
error (interpreter/first-error ast-results)]
(if-not error
(let [table-result (:table (first ast-results))
f (:scalar (second ast-results))
selection (:selection table-result)]
(if (empty? selection)
{:matrix [[{:scalar "" :representation ""}]]}
(apply
reduce
(remove
nil?
[#(if (= (:scalar %2) "")
%1
(if (= (:scalar %1) "")
%2
(interpreter/apply-user-f sheet f [%1 %2])))
(first (next (next ast-results)))
(map #(util/get-cell (:grid sheet) %) selection)]))))
error)))

(defn bean-table [sheet asts]
;; This doesn't work for matrices right now
;; It should: eval-matrix should perhaps return a :selection also
(defn bean-filter [sheet asts]
(let [ast-results (interpreter/eval-asts sheet asts)
error (interpreter/first-error ast-results)]
(if-not error
(if (cell-ref? (first asts))
(let [[_ [_ a n]] (first asts)
address (util/a1->rc a (js/parseInt n))
table-name (tables/cell-table address sheet)
table (tables/get-table sheet table-name)]
(if table-name
{:matrix (interpreter/eval-matrix (:start table)
(:end table)
(:grid sheet))
:table {:name table-name
:selection (area/area->addresses
(select-keys table [:start :end]))
:selection-dirn nil}}
(errors/undefined-table-at (str a n))))
(errors/invalid-table-args
(str (:scalar (first ast-results)))))
(let [table-result (:table (first ast-results))
f (:scalar (second ast-results))
selection (:selection table-result)]
(make-table-result
sheet table-result
(filter
#(:scalar
(interpreter/apply-user-f sheet f
[(util/get-cell (:grid sheet) %)]))
selection)))
error)))

(defn bean-error [sheet asts]
(let [str-err (str (:error (interpreter/eval-ast (first asts) sheet)))]
{:scalar str-err
:representation str-err}))
(defn bean-get* [sheet asts & [dirn]]
(let [ast-results (interpreter/eval-asts sheet asts)
error (interpreter/first-error ast-results)]
(if-not error
(let [table-result (:table (first ast-results))
label (:scalar (second ast-results))
existing-selection (:selection table-result)
vget-cells (tables/label-name->cells
sheet
(:name table-result) label dirn)
new-selection (set/intersection
vget-cells
existing-selection)]
(if (tables/label? sheet (:name table-result) label dirn)
(make-table-result sheet table-result new-selection)
(errors/label-not-found
(:scalar (interpreter/eval-ast (second asts) sheet)))))
error)))

(defn bean-get [sheet asts]
(bean-get* sheet asts))

(defn bean-vget [sheet asts]
(bean-get* sheet asts :top))

(defn bean-hget [sheet asts]
(bean-get* sheet asts :left))

(defn bean-table [sheet asts]
(let [ast-results (interpreter/eval-asts sheet asts)
error (interpreter/first-error ast-results)]
(if-not error
(if (cell-ref? (first asts))
(let [[_ [_ a n]] (first asts)
address (util/a1->rc a (js/parseInt n))
table-name (tables/cell-table address sheet)
table (tables/get-table sheet table-name)]
(if table-name
{:matrix (interpreter/eval-matrix (:start table)
(:end table)
(:grid sheet))
:table {:name table-name
:selection (area/area->addresses
(select-keys table [:start :end]))
:selection-dirn nil}}
(errors/undefined-table-at (str a n))))
(errors/invalid-table-args
(str (:scalar (first ast-results)))))
error)))

(defn bean-error [sheet asts]
(let [str-err (str (:error (interpreter/eval-ast (first asts) sheet)))]
{:scalar str-err
:representation str-err}))
12 changes: 9 additions & 3 deletions src/bean/grid.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@
:representation "f"}
"table" {:scalar functions/bean-table
:representation "f"}
"filter" {:scalar functions/bean-filter
:representation "f"}
"reduce" {:scalar functions/bean-reduce
:representation "f"}
"row" {:scalar functions/bean-row
:representation "f"}
"col" {:scalar functions/bean-col
:representation "f"}
"error" {:scalar functions/bean-error
:representation "f"}})

Expand Down Expand Up @@ -225,9 +233,7 @@
(reduce #(eval-dep %2 %1) sheet* deps-to-reval))))

(defn update-cell [address sheet content]
(if (= (:content (util/get-cell (:grid sheet) address)) content)
sheet
(eval-cell address (tables/expand-tables sheet address) content)))
(eval-cell address (tables/expand-tables sheet address) content))

(defn- merge-cell [sheet address merge-with]
(let [sheet* (if (not= merge-with address)
Expand Down
19 changes: 12 additions & 7 deletions src/bean/interpreter.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
[bean.errors :as errors]
[bean.operators :as operators]))

(defn- ast-result [error-or-val]
(defn ast-result [error-or-val]
(if-let [error (:error error-or-val)]
(errors/stringified-error error)
{:scalar error-or-val
Expand Down Expand Up @@ -121,14 +121,19 @@
(defn- bound-to-xyz [values]
(into {} (map vector ["x" "y" "z"] values)))

(defn- apply-f [sheet f asts]
(defn apply-system-f [sheet f asts]
(f sheet asts))

(defn apply-user-f [sheet f args]
(eval-ast f (update-in sheet [:bindings]
merge (bound-to-xyz args))))

(defn apply-f [sheet f asts]
(let [fn-ast (:scalar f)]
(if (fn? fn-ast)
(fn-ast sheet asts)
(eval-ast fn-ast
(update-in sheet [:bindings]
merge (bound-to-xyz
(eval-asts sheet asts)))))))
(apply-system-f sheet fn-ast asts)
(apply-user-f
sheet fn-ast (eval-asts sheet asts)))))

(defn eval-cell [cell sheet]
(-> (eval-ast (:ast cell) sheet)
Expand Down
12 changes: 8 additions & 4 deletions src/bean/ui/events.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@
:error
:evaluated)))))

(rf/reg-event-db
::refresh-bindings
(fn refresh-bindings [db [_]]
(update-in db [:sheet :bindings] merge grid/default-bindings)))

(rf/reg-event-db
::update-cell
(fn update-cell [db [_ address content]]
Expand Down Expand Up @@ -104,10 +109,9 @@
(rf/reg-event-fx
::select-table
(fn select-table [{:keys [db]} [_ table-name]]
(let [{:keys [start]} (get-in db [:sheet :tables table-name])]
(merge
{:db (assoc-in db [:ui :grid :selected-table] table-name)}
(when start {:fx [[:dispatch [::edit-cell start]]]})))))
(when-let [{:keys [start]} (get-in db [:sheet :tables table-name])]
{:db (assoc-in db [:ui :grid :selected-table] table-name)
:fx [[:dispatch [::edit-cell start]]]})))

(rf/reg-event-fx
::make-table
Expand Down
3 changes: 2 additions & 1 deletion src/bean/ui/main.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
(routes/start)
(r/render
[root/routed]
(.getElementById js/document "app")))
(.getElementById js/document "app"))
(rf/dispatch [::events/refresh-bindings]))

(defn ^:export main []
(rf/dispatch-sync [::events/initialize-db])
Expand Down

0 comments on commit ed42a20

Please sign in to comment.