... | ... |
@@ -1,8 +1,11 @@ |
1 | 1 |
(ns dmr.events |
2 | 2 |
(:require |
3 |
- [cljs.reader :refer [read-string]] |
|
4 |
- [clojure.string :refer [lower-case split join starts-with?]] |
|
3 |
+ [clojure.edn :as edn] |
|
4 |
+ [clojure.core.match :refer-macros [match]] |
|
5 |
+ [clojure.walk :refer [postwalk]] |
|
6 |
+ [clojure.string :refer [lower-case split join starts-with? replace]] |
|
5 | 7 |
[re-frame.core :as re-frame] |
8 |
+ [sci.core :as sci] |
|
6 | 9 |
[dmr.db :as db] |
7 | 10 |
[day8.re-frame.tracing :refer-macros [fn-traced]])) |
8 | 11 |
|
... | ... |
@@ -77,6 +80,30 @@ |
77 | 80 |
(roll-dice (edn/read-string ndice) (edn/read-string nsides))))] |
78 | 81 |
(replace s dice-regex evaluated-roll))) |
79 | 82 |
|
83 |
+(defn infixify [expr] |
|
84 |
+ (match [expr] |
|
85 |
+ [([x] :seq)] (infixify x) |
|
86 |
+ [([x op & rest] :seq)] (list op (infixify x) (infixify rest)) |
|
87 |
+ [x :guard number?] x |
|
88 |
+ :else (throw (js/Error. (str "Expected number, but got '" (pr-str expr) "'"))))) |
|
89 |
+ |
|
90 |
+ |
|
91 |
+(defn evaluate-roll-expression [s] |
|
92 |
+ (let [string-expr (evaluate-rolls s) |
|
93 |
+ result (as-> string-expr x |
|
94 |
+ (str "(" x ")") ;So that 'read-string' reads everything |
|
95 |
+ (edn/read-string x) |
|
96 |
+ (postwalk #(if (vector? %) (reduce + %) %) x) |
|
97 |
+ (infixify x) |
|
98 |
+ (pr-str x) |
|
99 |
+ (sci/eval-string x))] |
|
100 |
+ {:roll-expression string-expr :result result})) |
|
101 |
+ |
|
102 |
+(defn safely-evaluate-roll-expression [s] |
|
103 |
+ (try |
|
104 |
+ (evaluate-roll-expression s) |
|
105 |
+ (catch js/Error e {:err (.-message e)}))) |
|
106 |
+ |
|
80 | 107 |
(defn execute [db cmdline] |
81 | 108 |
(let [append-history #(update-in db [:cmdline :history] conj {:input cmdline :output %}) |
82 | 109 |
entities (db :entities) |