diff --git a/src/bean/errors.cljs b/src/bean/errors.cljs index c068d29..145cb7a 100644 --- a/src/bean/errors.cljs +++ b/src/bean/errors.cljs @@ -41,6 +41,10 @@ {:error "Matrices should be same size." :representation "Matrices should be same size."}) +(defn divide-by-zero [] + {:error "can't divide by zero" + :representation "can't divide by zero"}) + (defn type-mismatch-+-op [] {:error "+ only works for Integers" :representation "+ only works for Integers"}) diff --git a/src/bean/interpreter.cljs b/src/bean/interpreter.cljs index 8b18008..2beb543 100644 --- a/src/bean/interpreter.cljs +++ b/src/bean/interpreter.cljs @@ -118,11 +118,13 @@ (eval-sub-ast right))) (eval-sub-ast arg)) :Value (eval-sub-ast arg) - :Integer (ast-result (js/parseInt arg)) + :Number (ast-result (js/Number.parseFloat arg)) :String (ast-result arg) :QuotedString (ast-result arg) :Operation (ast-result (case arg "+" operators/bean-op-+ + "-" operators/bean-op-minus + "/" operators/bean-op-div "*" operators/bean-op-* "<" operators/bean-op-< ">" operators/bean-op-> diff --git a/src/bean/operators.cljs b/src/bean/operators.cljs index 35238d3..5668346 100644 --- a/src/bean/operators.cljs +++ b/src/bean/operators.cljs @@ -1,30 +1,46 @@ (ns bean.operators (:require [bean.errors :as errors])) +(defn format-number + [num] + (if (.isInteger js/Number num) num (js/Number (.toFixed num 4)))) + (defn bean-op-+ [left right] - (if (and (int? left) (int? right)) + (if (and (number? left) (number? right)) (+ left right) (errors/type-mismatch-+-op))) +(defn bean-op-minus [left right] + (if (and (number? left) (number? right)) + (format-number (- left right)) + (errors/type-mismatch-+-op))) + +(defn bean-op-div [left right] + (if (and (number? left) (number? right)) + (if (zero? right) + (errors/divide-by-zero) + (format-number (/ left right))) + (errors/type-mismatch-+-op))) + (defn bean-op-< [left right] - (if (and (int? left) (int? right)) + (if (and (number? left) (number? right)) (< left right) (errors/type-mismatch-<-op))) (defn bean-op-> [left right] - (if (and (int? left) (int? right)) + (if (and (number? left) (number? right)) (> left right) (errors/type-mismatch->-op))) (defn bean-op-= [left right] (if (and (or (string? left) - (int? left)) + (number? left)) (or (string? right) - (int? right))) + (number? right))) (= left right) (errors/type-mismatch-=-op))) (defn bean-op-* [left right] - (if (and (int? left) (int? right)) + (if (and (number? left) (number? right)) (* left right) (errors/type-mismatch-*-op))) diff --git a/src/bean/parser/parser.cljs b/src/bean/parser/parser.cljs index 20d7846..c95bcbd 100644 --- a/src/bean/parser/parser.cljs +++ b/src/bean/parser/parser.cljs @@ -12,14 +12,14 @@ ;; TODO: Integers are currently just natural numbers " CellContents = <'='> Expression / RawValue / Epsilon - = Integer / String - Integer = #'[0-9]+' + = Number / String + Number = #'[-]?[0-9]+([.][0-9]+)?' String = #'.*' CellRef = #'[A-Z]+' #'[1-9][0-9]*' MatrixRef = CellRef <':'> CellRef - Operation = '+' | '*' | '=' | '<' | '>' + Operation = '+' | '*' | '=' | '<' | '>' | '/' | '-' Expression = (Value | CellRef | MatrixRef | FunctionChain | Expression Operation Expression | FunctionInvocation | FunctionDefinition | FrameLookup) / Name @@ -32,7 +32,7 @@ FrameLookup = <'$'> Name LabelLookup = Name - Value = Integer / <'\"'> QuotedString <'\"'> + Value = Number / <'\"'> QuotedString <'\"'> QuotedString = #'[^\"]+' ")