1
0
Эх сурвалжийг харах

feat: add scientific numbers and variables with underscores

Sebastian Bensusan 4 жил өмнө
parent
commit
f611657bef

+ 1 - 0
src/main/frontend/extensions/calc.cljc

@@ -24,6 +24,7 @@
    (doall
     (insta/transform
      {:number     edn/read-string
+      :scientific edn/read-string
       :expr       identity
       :add        +
       :sub        -

+ 4 - 3
src/main/grammar/calc.bnf

@@ -17,8 +17,9 @@ tan = <#'\s*'> <'tan('> expr <')'> <#'\s*'>
 atan = <#'\s*'> <'atan('> expr <')'> <#'\s*'>
 acos = <#'\s*'> <'acos('> expr <')'> <#'\s*'>
 asin = <#'\s*'> <'asin('> expr <')'> <#'\s*'>
-<term> = number | variable | <#'\s*'> <'('> expr <')'> <#'\s*'>
+<term> = scientific | number | variable | <#'\s*'> <'('> expr <')'> <#'\s*'>
+scientific = #'\s*[0-9]+\.?[0-9]*(e|E)-?[0-9]+()\s*'
 number = #'\s*[0-9]+\.?[0-9]*()\s*'
-variable = #'\s*[a-zA-Z]+\s*'
-toassign =  #'\s*[a-zA-Z]+\s*'
+variable = #'\s*[[a-zA-Z]+\_*[a-zA-Z]*]*\s*'
+toassign = #'\s*[[a-zA-Z]+\_*[a-zA-Z]*]*\s*'
 assignment = toassign <#'\s*'> <'='> <#'\s*'> expr

+ 21 - 3
src/test/frontend/extensions/calc_test.cljc

@@ -48,6 +48,13 @@
       432.0 "(3*2) ^ (2 + 1) * 2"
       97.0  "(2 * 3) * 2 ^ (2 * 2) + 1"
       4.0   "2 * 3 / 2 ^ 2 * 2 + 1"))
+  (testing "scientific numbers"
+    (are [value expr] (= value (run expr))
+      1.0e1    "1.0e01"
+      1.23e-10 "123.0e-12"
+      12.3     "123.0e-1"
+      12.3     "123.0E-1"
+      2.0      "1e0 + 1e0"))
   (testing "scientific functions"
     (are [value expr] (= value (run expr))
       1.0  "cos( 0 * 1 )"
@@ -69,12 +76,23 @@
       {"y" 4}        "y =8 / 4 + 2 * 1 - 25 * 0 / 1"
       {"zzz" 14.0}   "zzz=3 *2 ^ 2 + 1 * 2"
       {"foo" 74.0}   "foo = (((3*2) ^ 2 + 1) * 2)"))
+  (testing "variables can have underscores"
+    (are [final-env expr] (let [env (calc/new-env)]
+                            (calc/eval env (calc/parse expr))
+                            (= final-env @env))
+      {"a_a" 1}           "a_a = 1"
+      {"a_a_" 1}          "a_a_ = 1"
+      {"_" 1}             "_ = 1"
+      {"__" 1}            "__ = 1"
+      {"foo_bar_baz" 1}   "foo_bar_baz = 1 + 0 * 2"
+      {"foo___bar_baz" 1} "foo___bar_baz = 1 + 0 * 2"))
   (testing "variables can be reused"
     (are [final-env exprs] (let [env (calc/new-env)]
-                            (doseq [expr exprs]
-                              (calc/eval env (calc/parse expr)))
-                            (= final-env @env))
+                             (doseq [expr exprs]
+                               (calc/eval env (calc/parse expr)))
+                             (= final-env @env))
       {"a" 1 "b" 2}          ["a = 1" "b = a + 1"]
+      {"a_a" 1 "b_b" 2}      ["a_a = 1" "b_b = a_a + 1"]
       {"variable" 1 "x" 0.0} ["variable = 1 + 0 * 2" "x = log(variable)"]
       {"x" 1 "u" 23 "v" 24}  ["x= 2 * 1 - 1 " "23 + 54" "u= 23" "v = x + u"]))
   (testing "variables can be rewritten"