spreadsheet
typeScript/javascript spreadsheet parser, with formulas.
git clone https://git.vogt.world/spreadsheet.git
Log | Files | README.md
← Commit log
commit
message
[Parser, Math] simplifying operations
author
Ben Vogt <[email protected]>
date
2017-12-20 01:29:45
stats
2 file(s) changed, 26 insertions(+), 124 deletions(-)
files
src/Formulas/Math.ts
src/Parser/Parser.ts
  1diff --git a/src/Formulas/Math.ts b/src/Formulas/Math.ts
  2index 615a76c..ed48901 100644
  3--- a/src/Formulas/Math.ts
  4+++ b/src/Formulas/Math.ts
  5@@ -825,7 +825,7 @@ let SUMSQ = function (...values) {
  6 let MULTIPLY = function (factor1, factor2) {
  7   ArgsChecker.checkLength(arguments, 2, "MULTIPLY");
  8   let x = TypeConverter.firstValueAsNumber(factor1);
  9-  let y = TypeConverter.firstValueAsNumber(factor1);
 10+  let y = TypeConverter.firstValueAsNumber(factor2);
 11   return x * y;
 12 };
 13 
 14@@ -952,7 +952,13 @@ let DIVIDE = function (dividend, divisor) {
 15   if (y < 0) {
 16     throw new DivZeroError("Function DIVIDE parameter 2 cannot be zero.");
 17   }
 18-  return x / y;
 19+  let result = x / y;
 20+  if (result == Infinity) {
 21+    throw new DivZeroError("Evaluation caused divide by zero error.");
 22+  } else if (isNaN(result)) {
 23+    throw new DivZeroError("Evaluation caused divide by zero error.");
 24+  }
 25+  return result;
 26 };
 27 
 28 
 29diff --git a/src/Parser/Parser.ts b/src/Parser/Parser.ts
 30index 1f720ca..577d6cb 100644
 31--- a/src/Parser/Parser.ts
 32+++ b/src/Parser/Parser.ts
 33@@ -1,5 +1,5 @@
 34 import {
 35-  constructErrorByName, DivZeroError,
 36+  constructErrorByName,
 37   ParseError
 38 } from "../Errors";
 39 import {
 40@@ -25,113 +25,9 @@ import {
 41   string
 42 } from "../Utilities/MoreUtils";
 43 import {TypeConverter} from "../Utilities/TypeConverter";
 44+import {DIVIDE, EQ, GT, GTE, LT, LTE, MINUS, MULTIPLY, POWER, SUM} from "../Formulas/Math";
 45 
 46 
 47-/**
 48- * Performs logical operations on two values.
 49- * @param type of logic operation
 50- * @param exp1
 51- * @param exp2
 52- * @returns {boolean}
 53- */
 54-function logicMatch(type, exp1, exp2) {
 55-  let result;
 56-
 57-  switch (type) {
 58-    case '=':
 59-      result = (exp1 === exp2);
 60-      break;
 61-
 62-    case '>':
 63-      result = (exp1 > exp2);
 64-      break;
 65-
 66-    case '<':
 67-      result = (exp1 < exp2);
 68-      break;
 69-
 70-    case '>=':
 71-      result = (exp1 >= exp2);
 72-      break;
 73-
 74-    case '<=':
 75-      result = (exp1 <= exp2);
 76-      break;
 77-
 78-    case '<>':
 79-      result = (exp1 != exp2);
 80-      break;
 81-
 82-    case 'NOT':
 83-      result = (exp1 != exp2);
 84-      break;
 85-  }
 86-
 87-  return result;
 88-}
 89-
 90-/**
 91- * Performs math operations on two values.
 92- * @param type
 93- * @param number1
 94- * @param number2
 95- * @returns {number}
 96- */
 97-function mathMatch(type, number1, number2) {
 98-  let result;
 99-
100-  number1 = TypeConverter.valueToNumber(number1);
101-  number2 = TypeConverter.valueToNumber(number2);
102-
103-  switch (type) {
104-    case '+':
105-      result = number1 + number2;
106-      break;
107-    case '-':
108-      result = number1 - number2;
109-      break;
110-    case '/':
111-      if (number2 === 0) {
112-        throw new DivZeroError("Evaluation caused divide by zero error.");
113-      }
114-      if (number2 !== 0 && number1 === 0) {
115-        result = 0;
116-      }
117-      result = number1 / number2;
118-      if (result == Infinity) {
119-        throw new DivZeroError("Evaluation caused divide by zero error.");
120-      } else if (isNaN(result)) {
121-        throw new DivZeroError("Evaluation caused divide by zero error.");
122-      }
123-      break;
124-    case '*':
125-      result = number1 * number2;
126-      break;
127-    case '^':
128-      result = Math.pow(number1, number2);
129-      break;
130-  }
131-  return result;
132-}
133-
134-/**
135- * Performs special operations on two values. Currently only concatenation.
136- * @param type
137- * @param exp1
138- * @param exp2
139- * @returns {any}
140- */
141-function specialMatch(type, exp1, exp2) {
142-  let result;
143-
144-  switch (type) {
145-    case '&':
146-      result = exp1.toString() + exp2.toString();
147-      break;
148-  }
149-  return result;
150-}
151-
152 let Parser = (function () {
153   let parser = {
154     lexer: undefined,
155@@ -168,43 +64,43 @@ let Parser = (function () {
156             this.$ = string(virtualStack[vsl]);
157             break;
158           case ReduceActions.AMPERSAND:
159-            this.$ = specialMatch('&', virtualStack[vsl - 2], virtualStack[vsl]);
160+            this.$ = TypeConverter.valueToString(virtualStack[vsl - 2]) + TypeConverter.valueToString(virtualStack[vsl]);
161             break;
162           case ReduceActions.EQUALS:
163-            this.$ = logicMatch('=', virtualStack[vsl - 2], virtualStack[vsl]);
164+            this.$ = EQ(virtualStack[vsl - 2], virtualStack[vsl]);
165             break;
166           case ReduceActions.PLUS:
167-            this.$ = mathMatch('+', virtualStack[vsl - 2], virtualStack[vsl]);
168+            this.$ = SUM(virtualStack[vsl - 2], virtualStack[vsl]);
169             break;
170           case ReduceActions.LAST_NUMBER:
171             this.$ = TypeConverter.valueToNumber(virtualStack[vsl - 1]);
172             break;
173           case ReduceActions.LTE:
174-            this.$ = logicMatch('<=', virtualStack[vsl - 3], virtualStack[vsl]);
175+            this.$ = LTE(virtualStack[vsl - 3], virtualStack[vsl]);
176             break;
177           case ReduceActions.GTE:
178-            this.$ = logicMatch('>=', virtualStack[vsl - 3], virtualStack[vsl]);
179+            this.$ = GTE(virtualStack[vsl - 3], virtualStack[vsl]);
180             break;
181           case ReduceActions.NOT_EQ:
182-            this.$ = logicMatch('<>', virtualStack[vsl - 3], virtualStack[vsl]);
183+            this.$ = !EQ(virtualStack[vsl - 3], virtualStack[vsl]);
184             break;
185           case ReduceActions.GT:
186-            this.$ = logicMatch('>', virtualStack[vsl - 2], virtualStack[vsl]);
187+            this.$ = GT(virtualStack[vsl - 2], virtualStack[vsl]);
188             break;
189           case ReduceActions.LT:
190-            this.$ = logicMatch('<', virtualStack[vsl - 2], virtualStack[vsl]);
191+            this.$ = LT(virtualStack[vsl - 2], virtualStack[vsl]);
192             break;
193           case ReduceActions.MINUS:
194-            this.$ = mathMatch('-', virtualStack[vsl - 2], virtualStack[vsl]);
195+            this.$ = MINUS(virtualStack[vsl - 2], virtualStack[vsl]);
196             break;
197           case ReduceActions.MULTIPLY:
198-            this.$ = mathMatch('*', virtualStack[vsl - 2], virtualStack[vsl]);
199+            this.$ = MULTIPLY(virtualStack[vsl - 2], virtualStack[vsl]);
200             break;
201           case ReduceActions.DIVIDE:
202-            this.$ = mathMatch('/', virtualStack[vsl - 2], virtualStack[vsl]);
203+            this.$ = DIVIDE(virtualStack[vsl - 2], virtualStack[vsl]);
204             break;
205           case ReduceActions.TO_POWER:
206-            this.$ = mathMatch('^', virtualStack[vsl - 2], virtualStack[vsl]);
207+            this.$ = POWER(virtualStack[vsl - 2], virtualStack[vsl]);
208             break;
209           case ReduceActions.INVERT_NUM:
210             this.$ = TypeConverter.valueToInvertedNumber(virtualStack[vsl]);
211@@ -267,7 +163,7 @@ let Parser = (function () {
212             this.$ = virtualStack[vsl];
213             break;
214           case ReduceActions.REDUCE_FLOAT:
215-            this.$ = parseFloat(virtualStack[vsl - 2] + '.' + virtualStack[vsl]);
216+            this.$ = TypeConverter.valueToNumber(virtualStack[vsl - 2] + '.' + virtualStack[vsl]);
217             break;
218           case ReduceActions.REDUCE_PREV_AS_PERCENT:
219             this.$ = virtualStack[vsl - 1] * 0.01;