feat(calc): Understand percentages

This commit is contained in:
Sebastian Bensusan
2021-09-04 07:57:07 -07:00
committed by Tienson Qin
parent bfe6a5d6cb
commit c05034cc34
3 changed files with 20 additions and 9 deletions

View File

@@ -28,6 +28,7 @@
(defn eval* [env ast]
(insta/transform
{:number (comp edn/read-string #(str/replace % "," ""))
:percent (fn percent [a] (/ a 100.00))
:scientific edn/read-string
:negterm (fn neg [a] (- a))
:expr identity

View File

@@ -17,11 +17,12 @@ tan = <#'\s*'> <'tan('> expr <')'> <#'\s*'>
atan = <#'\s*'> <'atan('> expr <')'> <#'\s*'>
acos = <#'\s*'> <'acos('> expr <')'> <#'\s*'>
asin = <#'\s*'> <'asin('> expr <')'> <#'\s*'>
<posterm> = log | ln | trig | scientific | number | variable | <#'\s*'> <'('> expr <')'> <#'\s*'>
<posterm> = log | ln | trig | percent | scientific | number | variable | <#'\s*'> <'('> expr <')'> <#'\s*'>
negterm = <#'\s*'> <'-'> posterm
<term> = negterm | posterm
scientific = #'\s*[0-9]+\.?[0-9]*(e|E)-?[0-9]+()\s*'
number = #'\s*\d+(,\d+)*(\.\d*)?\s*'
percent = number <'%'> <#'\s*'>
variable = #'\s*[a-zA-Z]+(\_+[a-zA-Z]+)*\s*'
toassign = #'\s*[a-zA-Z]+(\_+[a-zA-Z]+)*\s*'
assignment = toassign <#'\s*'> <'='> <#'\s*'> expr

View File

@@ -27,7 +27,12 @@
(are [value expr] (= value (run expr))
-98123 "-98123"
-1123.0 " -112,3.0 "
-22.1124131 "-2,2.1124131")))
-22.1124131 "-2,2.1124131"))
(testing "even as percentages"
(are [value expr] (= value (run expr))
0.01 "1%"
1.0 " 100.00% "
0.00169781231 "0.169781231%")))
(testing "basic operations work"
(are [value expr] (= value (run expr))
1 "1 + 0"
@@ -48,15 +53,19 @@
-1 " 2 * 3 / 3 / -2"
#?(:clj 1/2
:cljs 0.5) " 1 / 2"
0.5 " 1/ 2.0"))
0.5 " 1/ 2.0"
2.0 "2*100%"
0.01 "2%/2"
500e3 "50% * 1e6"))
(testing "power"
(are [value expr] (= value (run expr))
1.0 "1 ^ 0"
4.0 "2^2 "
27.0 " 3^ 3"
0.125 " 2^ -3"
16.0 "2 ^ 2 ^ 2"
256.0 "4.000 ^ 4.0"))
1.0 "1 ^ 0"
4.0 "2^2 "
27.0 " 3^ 3"
0.125 " 2^ -3"
16.0 "2 ^ 2 ^ 2"
256.0 "4.000 ^ 4.0"
4096.0 "200% ^ 12"))
(testing "operator precedence"
(are [value expr] (= value (run expr))
1 "1 + 0 * 2"