diff --git a/src/clojulator/calculator/evaluator.cljc b/src/clojulator/calculator/evaluator.cljc index 8d18df4..d39fe5a 100644 --- a/src/clojulator/calculator/evaluator.cljc +++ b/src/clojulator/calculator/evaluator.cljc @@ -7,7 +7,7 @@ "Polymorphic evaluator for AST nodes" (fn [node _history] (first node))) -(defmethod evaluate :Env [node history] +(defmethod evaluate :node/Env [node history] (let [var-name (second node)] (case var-name "p1" (repl1 history) @@ -17,25 +17,25 @@ (throw #?(:clj (Exception. error-msg) :cljs (js/Error. error-msg))))))) -(defmethod evaluate :Number [node _history] (second node)) +(defmethod evaluate :node/Number [node _history] (second node)) -(defmethod evaluate :Group +(defmethod evaluate :node/Group [node history] (-> node second (evaluate history))) -(defmethod evaluate :Caret [node history] (map-eval-reduce history Math/pow (rest node))) +(defmethod evaluate :node/Caret [node history] (map-eval-reduce history Math/pow (rest node))) -(defmethod evaluate :Star [node history] (map-eval-reduce history * (rest node))) +(defmethod evaluate :node/Star [node history] (map-eval-reduce history * (rest node))) -(defmethod evaluate :Slash [node history] (map-eval-reduce history / (rest node))) +(defmethod evaluate :node/Slash [node history] (map-eval-reduce history / (rest node))) -(defmethod evaluate :Modulo [node history] (map-eval-reduce history mod (rest node))) +(defmethod evaluate :node/Modulo [node history] (map-eval-reduce history mod (rest node))) -(defmethod evaluate :Plus [node history] (map-eval-reduce history + (rest node))) +(defmethod evaluate :node/Plus [node history] (map-eval-reduce history + (rest node))) -(defmethod evaluate :Minus [node history] +(defmethod evaluate :node/Minus [node history] (let [remaining (rest node)] (if (= 1 (count remaining)) (- (evaluate (first remaining) history)) diff --git a/src/clojulator/calculator/parser.cljc b/src/clojulator/calculator/parser.cljc index 971a27e..c9cddfb 100644 --- a/src/clojulator/calculator/parser.cljc +++ b/src/clojulator/calculator/parser.cljc @@ -29,11 +29,11 @@ inner expression is enclosed in a :CloseParen. Otherwise, throws a syntax error." [tokens] - (when (match tokens #{:OpenParen}) + (when (match tokens #{:token/OpenParen}) (let [expr (expression (rest tokens)) remaining-tokens (:remaining expr)] - (if (match remaining-tokens #{:CloseParen}) - {:node [:Group (:node expr)] :remaining (rest remaining-tokens)} + (if (match remaining-tokens #{:token/CloseParen}) + {:node [:node/Group (:node expr)] :remaining (rest remaining-tokens)} (parser-error (:remaining expr)))))) (defn- env @@ -41,16 +41,16 @@ Adds an environment variable node to the AST if the next token matches :Repl/*1, :Repl/*2, or :Repl/*3." [tokens] - (if (match tokens #{:Repl/*1 :Repl/*2 :Repl/*3}) - {:node [:Env (tok/lexeme (first tokens))] :remaining (rest tokens)} + (if (match tokens #{:token/*1 :token/*2 :token/*3}) + {:node [:node/Env (tok/lexeme (first tokens))] :remaining (rest tokens)} (parser-error tokens))) (defn- number "Number rule: Adds a number literal to the AST if the next token matches :Number" [tokens] - (if (match tokens #{:Number}) - {:node [:Number (tok/literal (first tokens))] :remaining (rest tokens)} + (if (match tokens #{:token/Number}) + {:node [:node/Number (tok/literal (first tokens))] :remaining (rest tokens)} (parser-error tokens))) (defn- primary @@ -58,8 +58,8 @@ Matches a group node, an environment variable, or a number literal." [tokens] (cond - (match tokens #{:OpenParen}) (group tokens) - (match tokens #{:Repl/*1 :Repl/*2 :Repl/*3}) (env tokens) + (match tokens #{:token/OpenParen}) (group tokens) + (match tokens #{:token/*1 :token/*2 :token/*3}) (env tokens) :else (number tokens))) (defn- unary @@ -67,9 +67,9 @@ Adds a unary node to the AST if the next token matches :Minus. Otherwise, matches a primary node." [tokens] - (if-let [minus (match tokens #{:Minus})] + (if (match tokens #{:token/Minus}) (let [p (unary (rest tokens))] - {:node [minus (:node p)] :remaining (:remaining p)}) + {:node [:node/Minus (:node p)] :remaining (:remaining p)}) (primary tokens))) (defn- binary-expression @@ -81,7 +81,7 @@ (if-let [operator (match remaining matchers)] (let [right (rule (rest remaining))] (recur - [operator expr (:node right)] + [(keyword "node" (name operator)) expr (:node right)] (:remaining right))) {:node expr :remaining remaining})))) @@ -89,19 +89,19 @@ "Exponent rule: ( ^ )* Adds an exponent node to the AST if the next token matches :Caret." [tokens] - (binary-expression tokens unary #{:Caret})) + (binary-expression tokens unary #{:token/Caret})) (defn- factor "Factor rule: ( [* / %] )* Adds a factor node to the AST if the next token matches :Star, :Slash, or :Modulo." [tokens] - (binary-expression tokens exponent #{:Star :Slash :Modulo})) + (binary-expression tokens exponent #{:token/Star :token/Slash :token/Modulo})) (defn- term "Term rule: ( [+ -] )* Adds a term node to the AST if the next token matches :Plus or :Minus." [tokens] - (binary-expression tokens factor #{:Plus :Minus})) + (binary-expression tokens factor #{:token/Plus :token/Minus})) (defn- expression "Expression rule: diff --git a/src/clojulator/calculator/token.cljc b/src/clojulator/calculator/token.cljc index 800fe54..d55f0cc 100644 --- a/src/clojulator/calculator/token.cljc +++ b/src/clojulator/calculator/token.cljc @@ -3,34 +3,34 @@ ;; Symbols that can be turned into tokens ;; Most symbols are represented as a single ;; character, but the history symbols are strings -(def symbol-tokens {\( :OpenParen - \) :CloseParen - \+ :Plus - \- :Minus - \* :Star - \/ :Slash - \^ :Caret - \% :Modulo - "p1" :Repl/*1 - "p2" :Repl/*2 - "p3" :Repl/*3}) +(def symbol-tokens {\( :token/OpenParen + \) :token/CloseParen + \+ :token/Plus + \- :token/Minus + \* :token/Star + \/ :token/Slash + \^ :token/Caret + \% :token/Modulo + "p1" :token/*1 + "p2" :token/*2 + "p3" :token/*3}) (defn token "Token constructor" ([type lexeme pos len] (token type lexeme pos len nil)) ([type lexeme pos len literal] - {:type type - :lexeme lexeme - :literal literal - :pos pos - :len len})) + {:token/type type + :token/lexeme lexeme + :token/literal literal + :token/pos pos + :token/len len})) (defn number->token "Given a number and a position, return a token that represents a numeric value in the expression." [n pos] (let [lexeme (str n)] - (token :Number lexeme pos (count lexeme) (parse-double n)))) + (token :token/Number lexeme pos (count lexeme) (parse-double n)))) (defn symbol->token "Given a symbol and a position, return a token @@ -42,20 +42,20 @@ (defn token-type [token] - (:type token)) + (:token/type token)) (defn lexeme [token] - (:lexeme token)) + (:token/lexeme token)) (defn literal [token] - (:literal token)) + (:token/literal token)) (defn pos [token] - (:pos token)) + (:token/pos token)) (defn length [token] - (:len token)) + (:token/len token)) diff --git a/src/clojulator/web/core.cljs b/src/clojulator/web/core.cljs index da1ae93..55a47f5 100644 --- a/src/clojulator/web/core.cljs +++ b/src/clojulator/web/core.cljs @@ -48,7 +48,6 @@ (defalias display [{:keys [last-result display]}] - (js/console.log "Display" display) [:div {:class ["w-full" "h-16" "sm:h-28" "bg-white" "border-2" "border-blue-400" "rounded-lg" "mt-5" "md:mt-0" "flex" "flex-col" "justify-evenly" "items-end" "pr-2" "border-blue-500" "text-right"]} [:div @@ -112,7 +111,6 @@ (defn render [root] (add-watch state :display (fn [_ _ _ new-state] - (js/console.log "Rendering wiht new state" new-state) (r/render root (index new-state)))) (r/render root (index @state))) diff --git a/test/calculator_test/evaluator_test.clj b/test/calculator_test/evaluator_test.clj index e880f51..e4c47ae 100644 --- a/test/calculator_test/evaluator_test.clj +++ b/test/calculator_test/evaluator_test.clj @@ -6,80 +6,80 @@ (deftest numeric-expression-tests (testing "evaluating a number should return the number" - (is (= 1.0 (evaluate [:Number 1.0] history))) - (is (= 10.0 (evaluate [:Number 10.0] history))) - (is (= 1234567890.0 (evaluate [:Number 1234567890.0] history)))) + (is (= 1.0 (evaluate [:node/Number 1.0] history))) + (is (= 10.0 (evaluate [:node/Number 10.0] history))) + (is (= 1234567890.0 (evaluate [:node/Number 1234567890.0] history)))) (testing "evaluating a number that is nil should return nil" - (is (nil? (evaluate [:Number nil] history))))) + (is (nil? (evaluate [:node/Number nil] history))))) (deftest environment-variable-tests (testing "evaluating an environment variable should return the value" - (is (nil? (evaluate [:Env "p1"] history))) - (is (= 1.0 (evaluate [:Env "p1"] (atom [1.0 nil nil])))) - (is (= 2.0 (evaluate [:Env "p2"] (atom [1.0 2.0 nil])))) - (is (= 3.0 (evaluate [:Env "p3"] (atom [1.0 2.0 3.0])))))) + (is (nil? (evaluate [:node/Env "p1"] history))) + (is (= 1.0 (evaluate [:node/Env "p1"] (atom [1.0 nil nil])))) + (is (= 2.0 (evaluate [:node/Env "p2"] (atom [1.0 2.0 nil])))) + (is (= 3.0 (evaluate [:node/Env "p3"] (atom [1.0 2.0 3.0])))))) (deftest unary-minus-tests (testing "evaluating a unary minus should return the negated number" - (is (= -1.0 (evaluate [:Minus [:Number 1.0]] history)))) + (is (= -1.0 (evaluate [:node/Minus [:node/Number 1.0]] history)))) (testing "evaluating a minus minus should return a positive number" - (is (= 1.0 (evaluate [:Minus [:Minus [:Number 1.0]]] history)))) + (is (= 1.0 (evaluate [:node/Minus [:node/Minus [:node/Number 1.0]]] history)))) (testing "evaluating a minus minus minus should return a negated number" - (is (= -1.0 (evaluate [:Minus [:Minus [:Minus [:Number 1.0]]]] history))))) + (is (= -1.0 (evaluate [:node/Minus [:node/Minus [:node/Minus [:node/Number 1.0]]]] history))))) (deftest simple-arithetic-expression-tests (testing "adding two numbers should return the sum" - (is (= 3.0 (evaluate [:Plus [:Number 1.0] [:Number 2.0]] history)))) + (is (= 3.0 (evaluate [:node/Plus [:node/Number 1.0] [:node/Number 2.0]] history)))) (testing "subtracting two numbers should return the difference" - (is (= -1.0 (evaluate [:Minus [:Number 1.0] [:Number 2.0]] history)))) + (is (= -1.0 (evaluate [:node/Minus [:node/Number 1.0] [:node/Number 2.0]] history)))) (testing "multiplying two numbers should return the product" - (is (= 2.0 (evaluate [:Star [:Number 1.0] [:Number 2.0]] history)))) + (is (= 2.0 (evaluate [:node/Star [:node/Number 1.0] [:node/Number 2.0]] history)))) (testing "dividing two numbers should return the quotient" - (is (= 0.5 (evaluate [:Slash [:Number 1.0] [:Number 2.0]] history))) + (is (= 0.5 (evaluate [:node/Slash [:node/Number 1.0] [:node/Number 2.0]] history))) (testing "dividing by zero should throw an exception" - (is (thrown? ArithmeticException (evaluate [:Slash [:Number 1.0] [:Number 0.0]] history))))) + (is (thrown? ArithmeticException (evaluate [:node/Slash [:node/Number 1.0] [:node/Number 0.0]] history))))) (testing "raising a number to a power should return the result" - (is (= 8.0 (evaluate [:Caret [:Number 2.0] [:Number 3.0]] history)))) + (is (= 8.0 (evaluate [:node/Caret [:node/Number 2.0] [:node/Number 3.0]] history)))) (testing "taking the remainder of two numbers should return the remainder" - (is (= 1.0 (evaluate [:Modulo [:Number 5.0] [:Number 2.0]] history))) - (is (= 0.0 (evaluate [:Modulo [:Number 3.0] [:Number 3.0]] history))))) + (is (= 1.0 (evaluate [:node/Modulo [:node/Number 5.0] [:node/Number 2.0]] history))) + (is (= 0.0 (evaluate [:node/Modulo [:node/Number 3.0] [:node/Number 3.0]] history))))) (deftest precedence-tests (testing "multiplicative expressions have higher precedence than additive expressions" ;; 1 + 2 * 3 - (is (= 7.0 (evaluate [:Plus [:Number 1.0] [:Star [:Number 2.0] [:Number 3.0]]] history))) + (is (= 7.0 (evaluate [:node/Plus [:node/Number 1.0] [:node/Star [:node/Number 2.0] [:node/Number 3.0]]] history))) ;; 2 * 3 - 5 - (is (= 1.0 (evaluate [:Minus [:Star [:Number 2.0] [:Number 3.0]] [:Number 5.0]] history))) + (is (= 1.0 (evaluate [:node/Minus [:node/Star [:node/Number 2.0] [:node/Number 3.0]] [:node/Number 5.0]] history))) ;; 1 + 4 % 2 - (is (= 1.0 (evaluate [:Plus [:Number 1.0] [:Modulo [:Number 4.0] [:Number 2.0]]] history)))) + (is (= 1.0 (evaluate [:node/Plus [:node/Number 1.0] [:node/Modulo [:node/Number 4.0] [:node/Number 2.0]]] history)))) (testing "exponentiation has higher precedence than multiplicative expressions" ;; 2 * 2 ^ 3 - (is (= 16.0 (evaluate [:Star [:Number 2.0] [:Caret [:Number 2.0] [:Number 3.0]]] history)))) + (is (= 16.0 (evaluate [:node/Star [:node/Number 2.0] [:node/Caret [:node/Number 2.0] [:node/Number 3.0]]] history)))) (testing "unary minus has higher precedence than multiplicative expressions" ;; -2 * 1 - (is (= -2.0 (evaluate [:Star [:Minus [:Number 2.0]] [:Number 1.0]] history))) + (is (= -2.0 (evaluate [:node/Star [:node/Minus [:node/Number 2.0]] [:node/Number 1.0]] history))) ;; 4 / -2 - (is (= -2.0 (evaluate [:Slash [:Number 4] [:Minus [:Number 2.0]]] history)))) + (is (= -2.0 (evaluate [:node/Slash [:node/Number 4] [:node/Minus [:node/Number 2.0]]] history)))) (testing "parentheses have the same precedence as numbers" ;; (2 * 3) + (6 - 2) - (is (= 10.0 (evaluate [:Plus - [:Group [:Star [:Number 2.0] [:Number 3.0]]] - [:Group [:Minus [:Number 6.0] [:Number 2.0]]]] history))))) + (is (= 10.0 (evaluate [:node/Plus + [:node/Group [:node/Star [:node/Number 2.0] [:node/Number 3.0]]] + [:node/Group [:node/Minus [:node/Number 6.0] [:node/Number 2.0]]]] history))))) (deftest associativity-tests (testing "additive exressions are left associative" ;; 2 - 1 + 3 - (is (= 4.0 (evaluate [:Plus [:Minus [:Number 2.0] [:Number 1.0]] [:Number 3.0]] history))) + (is (= 4.0 (evaluate [:node/Plus [:node/Minus [:node/Number 2.0] [:node/Number 1.0]] [:node/Number 3.0]] history))) ;; 2 + 1 - 3 - (is (= 0.0 (evaluate [:Minus [:Plus [:Number 2.0] [:Number 1.0]] [:Number 3.0]] history)))) + (is (= 0.0 (evaluate [:node/Minus [:node/Plus [:node/Number 2.0] [:node/Number 1.0]] [:node/Number 3.0]] history)))) (testing "multiplicative expressions are left associative" ;; 1 / 2 * 2 - (is (= 1.0 (evaluate [:Star [:Slash [:Number 1.0] [:Number 2.0]] [:Number 2.0]] history))) + (is (= 1.0 (evaluate [:node/Star [:node/Slash [:node/Number 1.0] [:node/Number 2.0]] [:node/Number 2.0]] history))) ;; 4 * 3 / 2 - (is (= 6.0 (evaluate [:Slash [:Star [:Number 4] [:Number 3]] [:Number 2.0]] history))) + (is (= 6.0 (evaluate [:node/Slash [:node/Star [:node/Number 4] [:node/Number 3]] [:node/Number 2.0]] history))) ;; 5 % 2 * 2 - (is (= 2.0 (evaluate [:Star [:Modulo [:Number 5.0] [:Number 2.0]] [:Number 2.0]] history)))) + (is (= 2.0 (evaluate [:node/Star [:node/Modulo [:node/Number 5.0] [:node/Number 2.0]] [:node/Number 2.0]] history)))) (testing "unary minus is right associative" - (is (= -1.0 (evaluate [:Minus [:Number 1.0]] history))) - (is (= -6.0 (evaluate [:Minus [:Group [:Star [:Number 2.0] [:Number 3.0]]]] history))))) + (is (= -1.0 (evaluate [:node/Minus [:node/Number 1.0]] history))) + (is (= -6.0 (evaluate [:node/Minus [:node/Group [:node/Star [:node/Number 2.0] [:node/Number 3.0]]]] history))))) diff --git a/test/calculator_test/parser_test.clj b/test/calculator_test/parser_test.clj index fa15a95..e399df8 100644 --- a/test/calculator_test/parser_test.clj +++ b/test/calculator_test/parser_test.clj @@ -5,84 +5,84 @@ (deftest numeric-expression-tests (testing "valid numbers should return a single node in AST" - (is (= [:Number 1.0] (parse (tokenize "1")))) - (is (= [:Number 10.0] (parse (tokenize "10")))) - (is (= [:Number 1234567890.0] (parse (tokenize "1234567890"))))) + (is (= [:node/Number 1.0] (parse (tokenize "1")))) + (is (= [:node/Number 10.0] (parse (tokenize "10")))) + (is (= [:node/Number 1234567890.0] (parse (tokenize "1234567890"))))) (testing "numbers larger than 9223372036854775807 should return nil" - (is (= [:Number (parse-double "9223372036854775808")] (parse (tokenize "9223372036854775808"))))) + (is (= [:node/Number (parse-double "9223372036854775808")] (parse (tokenize "9223372036854775808"))))) (testing "a single number wrapped in parentheses should return a node" - (is (= [:Group [:Number 1.0]] (parse (tokenize "(1)"))))) + (is (= [:node/Group [:node/Number 1.0]] (parse (tokenize "(1)"))))) (testing "a unary minus should return a minus number node" - (is (= [:Minus [:Number 1.0]] (parse (tokenize "-1"))))) + (is (= [:node/Minus [:node/Number 1.0]] (parse (tokenize "-1"))))) (testing "a minus minus should return a minus minus number node" - (is (= [:Minus [:Minus [:Number 1.0]]] (parse (tokenize "--1")))))) + (is (= [:node/Minus [:node/Minus [:node/Number 1.0]]] (parse (tokenize "--1")))))) (deftest environment-variable-tests (testing "valid environment variables should return a single node in AST" - (is (= [:Env "p1"] (parse (tokenize "p1")))) - (is (= [:Env "p2"] (parse (tokenize "p2")))) - (is (= [:Env "p3"] (parse (tokenize "p3")))))) + (is (= [:node/Env "p1"] (parse (tokenize "p1")))) + (is (= [:node/Env "p2"] (parse (tokenize "p2")))) + (is (= [:node/Env "p3"] (parse (tokenize "p3")))))) (deftest exponentiation-tests (testing "exponentiation should return an exponent node" - (is (= [:Caret [:Number 2.0] [:Number 2.0]] (parse (tokenize "2 ^ 2")))))) + (is (= [:node/Caret [:node/Number 2.0] [:node/Number 2.0]] (parse (tokenize "2 ^ 2")))))) (deftest multiplicative-tests (testing "multiplying two numbers should return a multiplication node" - (is (= [:Star [:Number 1.0] [:Number 2.0]] (parse (tokenize "1 * 2"))))) + (is (= [:node/Star [:node/Number 1.0] [:node/Number 2.0]] (parse (tokenize "1 * 2"))))) (testing "dividing two numbers should return a division node" - (is (= [:Slash [:Number 1.0] [:Number 2.0]] (parse (tokenize "1 / 2"))))) + (is (= [:node/Slash [:node/Number 1.0] [:node/Number 2.0]] (parse (tokenize "1 / 2"))))) (testing "taking the remainder of two numbers should return a modulo node" - (is (= [:Modulo [:Number 1.0] [:Number 2.0]] (parse (tokenize "1 % 2"))))) + (is (= [:node/Modulo [:node/Number 1.0] [:node/Number 2.0]] (parse (tokenize "1 % 2"))))) (testing "compound multiplicative expressions should return left-associative nested nodes" - (is (= [:Modulo - [:Star - [:Slash - [:Number 1.0] - [:Number 2.0]] - [:Number 2.0]] - [:Number 2.0]] (-> "1 / 2 * 2 % 2" tokenize parse))))) + (is (= [:node/Modulo + [:node/Star + [:node/Slash + [:node/Number 1.0] + [:node/Number 2.0]] + [:node/Number 2.0]] + [:node/Number 2.0]] (-> "1 / 2 * 2 % 2" tokenize parse))))) (deftest additive-tests (testing "adding two numbers should return a addition node" - (is (= [:Plus [:Number 1.0] [:Number 2.0]] (parse (tokenize "1 + 2"))))) + (is (= [:node/Plus [:node/Number 1.0] [:node/Number 2.0]] (parse (tokenize "1 + 2"))))) (testing "subtracting two numbers should return a subtraction node" - (is (= [:Minus [:Number 1.0] [:Number 2.0]] (parse (tokenize "1 - 2"))))) + (is (= [:node/Minus [:node/Number 1.0] [:node/Number 2.0]] (parse (tokenize "1 - 2"))))) (testing "compound additive expressions should return left-associative nested nodes" - (is (= [:Plus - [:Minus - [:Number 1.0] - [:Number 2.0]] - [:Number 2.0]] (-> "1 - 2 + 2" tokenize parse))))) + (is (= [:node/Plus + [:node/Minus + [:node/Number 1.0] + [:node/Number 2.0]] + [:node/Number 2.0]] (-> "1 - 2 + 2" tokenize parse))))) (deftest compound-expressions (testing "multiplicative expressions have higher precedence than additive expressions" - (is (= [:Plus - [:Number 1.0] - [:Star - [:Number 2.0] - [:Number 3.0]]] (-> "1 + 2 * 3" tokenize parse))) - (is (= [:Minus - [:Star - [:Number 1.0] - [:Number 2.0]] - [:Number 3.0]] (-> "1 * 2 - 3" tokenize parse))) - (is (= [:Minus - [:Modulo - [:Number 1.0] - [:Number 2.0]] - [:Number 3.0]] (-> "1 % 2 - 3" tokenize parse)))) + (is (= [:node/Plus + [:node/Number 1.0] + [:node/Star + [:node/Number 2.0] + [:node/Number 3.0]]] (-> "1 + 2 * 3" tokenize parse))) + (is (= [:node/Minus + [:node/Star + [:node/Number 1.0] + [:node/Number 2.0]] + [:node/Number 3.0]] (-> "1 * 2 - 3" tokenize parse))) + (is (= [:node/Minus + [:node/Modulo + [:node/Number 1.0] + [:node/Number 2.0]] + [:node/Number 3.0]] (-> "1 % 2 - 3" tokenize parse)))) (testing "exponentiation has higher precedence than multiplicative expressions" - (is (= [:Star - [:Number 2.0] - [:Caret - [:Number 2.0] - [:Number 3.0]]] (-> "2 * 2 ^ 3" tokenize parse)))) + (is (= [:node/Star + [:node/Number 2.0] + [:node/Caret + [:node/Number 2.0] + [:node/Number 3.0]]] (-> "2 * 2 ^ 3" tokenize parse)))) (testing "grouped expressions have higher precedence than multiplicative expressions" - (is (= [:Star - [:Group - [:Plus - [:Number 1.0] - [:Number 1.0]]] - [:Number 2.0]] (-> "(1 + 1) * 2" tokenize parse))))) + (is (= [:node/Star + [:node/Group + [:node/Plus + [:node/Number 1.0] + [:node/Number 1.0]]] + [:node/Number 2.0]] (-> "(1 + 1) * 2" tokenize parse))))) diff --git a/test/calculator_test/scanner_test.clj b/test/calculator_test/scanner_test.clj index ee44c86..b4a527d 100644 --- a/test/calculator_test/scanner_test.clj +++ b/test/calculator_test/scanner_test.clj @@ -7,7 +7,7 @@ ([end] (generate-number-tokens 0 end)) ([start end] (->> (range start end) (map (fn [n] [[(number->token (str n) 0)] (tokenize (str n))]))))) -(deftest simple-numeric-expressionk +(deftest simple-numeric-expression (testing "single digit numbers should return valid tokens" (let [results (generate-number-tokens 10)] (is (every? (fn [[a b]] (= a b)) results))))