spreadsheet
typeScript/javascript spreadsheet parser, with formulas.
git clone https://git.vogt.world/spreadsheet.git
Log | Files | README.md
← Commit log
commit
message
[MULTIPLY, MINUS, RAND] formulas tested and added
author
Ben Vogt <[email protected]>
date
2017-05-25 02:54:46
stats
10 file(s) changed, 942 insertions(+), 130 deletions(-)
files
DOCS.md
README.md
TODO.md
dist/Formulas/AllFormulas.js
dist/Formulas/Math.js
dist/parser.js
src/Formulas/AllFormulas.ts
src/Formulas/Math.ts
tests/Formulas/MathTest.ts
tests/SheetFormulaTest.ts
   1diff --git a/DOCS.md b/DOCS.md
   2index e0af4a4..f118041 100644
   3--- a/DOCS.md
   4+++ b/DOCS.md
   5@@ -889,6 +889,33 @@
   6 @constructor
   7 ```
   8 
   9+### MULTIPLY 
  10+
  11+```
  12+  Returns the product of two numbers. Equivalent to the `` operator. 
  13+@param factor1 - The first multiplicand. 
  14+@param factor2 - The second multiplicand. 
  15+@constructor
  16+```
  17+
  18+### MINUS 
  19+
  20+```
  21+  Returns the result of the first number minus the second number. Equivalent to the `-` operator. 
  22+@param one - The first number. 
  23+@param two - the second number. 
  24+@returns {number} 
  25+@constructor
  26+```
  27+
  28+### RAND 
  29+
  30+```
  31+  Returns a random number between 0 inclusive and 1 exclusive. 
  32+@returns {number} 
  33+@constructor
  34+```
  35+
  36 ### TRUNC 
  37 
  38 ```
  39diff --git a/README.md b/README.md
  40index 20d7f9a..2662566 100644
  41--- a/README.md
  42+++ b/README.md
  43@@ -80,11 +80,12 @@ When adding a formula, or fixing a bug please follow the commit message format:
  44 ```
  45 If you're adding a new formula, before you submit a pull request or push ensure that:
  46 1) The formula is tested inside the proper category file in `tests/Formulas`.
  47-2) The formula tests for reference errors, N/A errors, value errors for each input.
  48-3) That the formula is tested for parsing inside `SheetFormulaTest.ts`.
  49-4) Run tests with `npm run test`.
  50-5) Build with `npm run build`.
  51-6) Build DOCS.md with `npm run docs`.
  52+2) Make sure the formula is exported, and imported/exported in `AllFormulas.ts`.
  53+3) The formula tests for reference errors, N/A errors, value errors for each input.
  54+4) That the formula is tested for parsing inside `SheetFormulaTest.ts`.
  55+5) Run tests with `npm run test`.
  56+6) Build with `npm run build`.
  57+7) Build DOCS.md with `npm run docs`.
  58 
  59 
  60 ## Why?
  61diff --git a/TODO.md b/TODO.md
  62index c351330..9de0c54 100644
  63--- a/TODO.md
  64+++ b/TODO.md
  65@@ -54,7 +54,6 @@ For example 64 tbs to a qt.
  66 * MULTINOMIAL
  67 * PRODUCT
  68 * QUOTIENT
  69-* RAND
  70 * RANDBETWEEN
  71 * SERIESSUM
  72 * SIGN
  73@@ -151,8 +150,6 @@ For example 64 tbs to a qt.
  74 * TRIM
  75 * UPPER
  76 * VALUE
  77-* MINUS
  78-* MULTIPLY
  79 * FREQUENCY
  80 * GROWTH
  81 * LINEST
  82diff --git a/dist/Formulas/AllFormulas.js b/dist/Formulas/AllFormulas.js
  83index 8fc555c..c476a0c 100644
  84--- a/dist/Formulas/AllFormulas.js
  85+++ b/dist/Formulas/AllFormulas.js
  86@@ -52,6 +52,9 @@ exports.TRUNC = Math_1.TRUNC;
  87 exports.RADIANS = Math_1.RADIANS;
  88 exports.DEGREES = Math_1.DEGREES;
  89 exports.COMBIN = Math_1.COMBIN;
  90+exports.MULTIPLY = Math_1.MULTIPLY;
  91+exports.MINUS = Math_1.MINUS;
  92+exports.RAND = Math_1.RAND;
  93 var Logical_1 = require("./Logical");
  94 exports.AND = Logical_1.AND;
  95 exports.EXACT = Logical_1.EXACT;
  96diff --git a/dist/Formulas/Math.js b/dist/Formulas/Math.js
  97index 0603a00..c7c815e 100644
  98--- a/dist/Formulas/Math.js
  99+++ b/dist/Formulas/Math.js
 100@@ -741,6 +741,43 @@ var SUMSQ = function () {
 101     return result;
 102 };
 103 exports.SUMSQ = SUMSQ;
 104+/**
 105+ * Returns the product of two numbers. Equivalent to the `*` operator.
 106+ * @param factor1 - The first multiplicand.
 107+ * @param factor2 - The second multiplicand.
 108+ * @constructor
 109+ */
 110+var MULTIPLY = function (factor1, factor2) {
 111+    ArgsChecker_1.ArgsChecker.checkLength(arguments, 2, "MULTIPLY");
 112+    var x = TypeConverter_1.TypeConverter.firstValueAsNumber(factor1);
 113+    var y = TypeConverter_1.TypeConverter.firstValueAsNumber(factor1);
 114+    return x * y;
 115+};
 116+exports.MULTIPLY = MULTIPLY;
 117+/**
 118+ * Returns the result of the first number minus the second number. Equivalent to the `-` operator.
 119+ * @param one - The first number.
 120+ * @param two - the second number.
 121+ * @returns {number}
 122+ * @constructor
 123+ */
 124+var MINUS = function (one, two) {
 125+    ArgsChecker_1.ArgsChecker.checkLength(arguments, 2, "MINUS");
 126+    var x = TypeConverter_1.TypeConverter.firstValueAsNumber(one);
 127+    var y = TypeConverter_1.TypeConverter.firstValueAsNumber(two);
 128+    return x - y;
 129+};
 130+exports.MINUS = MINUS;
 131+/**
 132+ * Returns a random number between 0 inclusive and 1 exclusive.
 133+ * @returns {number}
 134+ * @constructor
 135+ */
 136+var RAND = function () {
 137+    ArgsChecker_1.ArgsChecker.checkLength(arguments, 0, "RAND");
 138+    return Math.random();
 139+};
 140+exports.RAND = RAND;
 141 /**
 142  * Truncates a number to a certain number of significant digits by omitting less significant digits.
 143  * @param value - The value to be truncated.
 144diff --git a/dist/parser.js b/dist/parser.js
 145index 4206cfd..7579d6c 100644
 146--- a/dist/parser.js
 147+++ b/dist/parser.js
 148@@ -71,13 +71,87 @@
 149  recoverable: (boolean: TRUE when the parser has a error recovery rule available for this particular error)
 150  }
 151  */
 152-var Parser = (function(){
 153-  var o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[1,4],$V1=[1,5],$V2=[1,7],$V3=[1,10],$V4=[1,8],$V5=[1,9],$V6=[1,11],$V7=[1,16],$V8=[1,17],$V9=[1,14],$Va=[1,15],$Vb=[1,18],$Vc=[1,20],$Vd=[1,21],$Ve=[1,22],$Vf=[1,23],$Vg=[1,24],$Vh=[1,25],$Vi=[1,26],$Vj=[1,27],$Vk=[1,28],$Vl=[1,29],$Vm=[5,11,12,13,15,16,17,18,19,20,21,22,30,31],$Vn=[5,11,12,13,15,16,17,18,19,20,21,22,30,31,33],$Vo=[1,38],$Vp=[5,11,12,13,15,16,17,18,19,20,21,22,30,31,35],$Vq=[5,12,13,15,16,17,18,19,30,31],$Vr=[5,12,15,16,17,18,30,31],$Vs=[5,12,13,15,16,17,18,19,20,21,30,31],$Vt=[15,30,31],$Vu=[5,11,12,13,15,16,17,18,19,20,21,22,30,31,32,36];
 154-  var parser = {trace: function trace() { },
 155+var Parser = (function () {
 156+  var o = function (k, v, o, l) {
 157+    for (o = o || {}, l = k.length; l--; o[k[l]] = v);
 158+    return o
 159+  }, $V0 = [1, 4], $V1 = [1, 5], $V2 = [1, 7], $V3 = [1, 10], $V4 = [1, 8], $V5 = [1, 9], $V6 = [1, 11], $V7 = [1, 16], $V8 = [1, 17], $V9 = [1, 14], $Va = [1, 15], $Vb = [1, 18], $Vc = [1, 20], $Vd = [1, 21], $Ve = [1, 22], $Vf = [1, 23], $Vg = [1, 24], $Vh = [1, 25], $Vi = [1, 26], $Vj = [1, 27], $Vk = [1, 28], $Vl = [1, 29], $Vm = [5, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 22, 30, 31], $Vn = [5, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 22, 30, 31, 33], $Vo = [1, 38], $Vp = [5, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 22, 30, 31, 35], $Vq = [5, 12, 13, 15, 16, 17, 18, 19, 30, 31], $Vr = [5, 12, 15, 16, 17, 18, 30, 31], $Vs = [5, 12, 13, 15, 16, 17, 18, 19, 20, 21, 30, 31], $Vt = [15, 30, 31], $Vu = [5, 11, 12, 13, 15, 16, 17, 18, 19, 20, 21, 22, 30, 31, 32, 36];
 160+  var parser = {
 161+    trace: function trace() {
 162+    },
 163     yy: {},
 164-    symbols_: {"error":2,"expressions":3,"expression":4,"EOF":5,"variableSequence":6,"TIME_AMPM":7,"TIME_24":8,"number":9,"STRING":10,"&":11,"=":12,"+":13,"(":14,")":15,"<":16,">":17,"NOT":18,"-":19,"*":20,"/":21,"^":22,"FUNCTION":23,"expseq":24,"cell":25,"FIXEDCELL":26,":":27,"CELL":28,"ARRAY":29,";":30,",":31,"VARIABLE":32,"DECIMAL":33,"NUMBER":34,"%":35,"#":36,"!":37,"$accept":0,"$end":1},
 165-    terminals_: {5:"EOF",7:"TIME_AMPM",8:"TIME_24",10:"STRING",11:"&",12:"=",13:"+",14:"(",15:")",16:"<",17:">",18:"NOT",19:"-",20:"*",21:"/",22:"^",23:"FUNCTION",26:"FIXEDCELL",27:":",28:"CELL",29:"ARRAY",30:";",31:",",32:"VARIABLE",33:"DECIMAL",34:"NUMBER",35:"%",36:"#",37:"!"},
 166-    productions_: [0,[3,2],[4,1],[4,1],[4,1],[4,1],[4,1],[4,3],[4,3],[4,3],[4,3],[4,4],[4,4],[4,4],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,3],[4,2],[4,2],[4,3],[4,4],[4,1],[4,1],[4,2],[25,1],[25,3],[25,1],[25,3],[24,1],[24,1],[24,3],[24,3],[6,1],[6,3],[9,1],[9,3],[9,2],[2,3],[2,4]],
 167+    symbols_: {
 168+      "error": 2,
 169+      "expressions": 3,
 170+      "expression": 4,
 171+      "EOF": 5,
 172+      "variableSequence": 6,
 173+      "TIME_AMPM": 7,
 174+      "TIME_24": 8,
 175+      "number": 9,
 176+      "STRING": 10,
 177+      "&": 11,
 178+      "=": 12,
 179+      "+": 13,
 180+      "(": 14,
 181+      ")": 15,
 182+      "<": 16,
 183+      ">": 17,
 184+      "NOT": 18,
 185+      "-": 19,
 186+      "*": 20,
 187+      "/": 21,
 188+      "^": 22,
 189+      "FUNCTION": 23,
 190+      "expseq": 24,
 191+      "cell": 25,
 192+      "FIXEDCELL": 26,
 193+      ":": 27,
 194+      "CELL": 28,
 195+      "ARRAY": 29,
 196+      ";": 30,
 197+      ",": 31,
 198+      "VARIABLE": 32,
 199+      "DECIMAL": 33,
 200+      "NUMBER": 34,
 201+      "%": 35,
 202+      "#": 36,
 203+      "!": 37,
 204+      "$accept": 0,
 205+      "$end": 1
 206+    },
 207+    terminals_: {
 208+      5: "EOF",
 209+      7: "TIME_AMPM",
 210+      8: "TIME_24",
 211+      10: "STRING",
 212+      11: "&",
 213+      12: "=",
 214+      13: "+",
 215+      14: "(",
 216+      15: ")",
 217+      16: "<",
 218+      17: ">",
 219+      18: "NOT",
 220+      19: "-",
 221+      20: "*",
 222+      21: "/",
 223+      22: "^",
 224+      23: "FUNCTION",
 225+      26: "FIXEDCELL",
 226+      27: ":",
 227+      28: "CELL",
 228+      29: "ARRAY",
 229+      30: ";",
 230+      31: ",",
 231+      32: "VARIABLE",
 232+      33: "DECIMAL",
 233+      34: "NUMBER",
 234+      35: "%",
 235+      36: "#",
 236+      37: "!"
 237+    },
 238+    productions_: [0, [3, 2], [4, 1], [4, 1], [4, 1], [4, 1], [4, 1], [4, 3], [4, 3], [4, 3], [4, 3], [4, 4], [4, 4], [4, 4], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 3], [4, 2], [4, 2], [4, 3], [4, 4], [4, 1], [4, 1], [4, 2], [25, 1], [25, 3], [25, 1], [25, 3], [24, 1], [24, 1], [24, 3], [24, 3], [6, 1], [6, 3], [9, 1], [9, 3], [9, 2], [2, 3], [2, 4]],
 239     performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) {
 240       /* this == yyval */
 241 
 242@@ -85,7 +159,7 @@ var Parser = (function(){
 243       switch (yystate) {
 244         case 1:
 245 
 246-          return $$[$0-1];
 247+          return $$[$0 - 1];
 248 
 249           break;
 250         case 2:
 251@@ -115,72 +189,72 @@ var Parser = (function(){
 252           break;
 253         case 7:
 254 
 255-          this.$ = yy.handler.helper.specialMatch('&', $$[$0-2], $$[$0]);
 256+          this.$ = yy.handler.helper.specialMatch('&', $$[$0 - 2], $$[$0]);
 257 
 258           break;
 259         case 8:
 260 
 261-          this.$ = yy.handler.helper.logicMatch('=', $$[$0-2], $$[$0]);
 262+          this.$ = yy.handler.helper.logicMatch('=', $$[$0 - 2], $$[$0]);
 263 
 264           break;
 265         case 9:
 266 
 267-          this.$ = yy.handler.helper.mathMatch('+', $$[$0-2], $$[$0]);
 268+          this.$ = yy.handler.helper.mathMatch('+', $$[$0 - 2], $$[$0]);
 269 
 270           break;
 271         case 10:
 272 
 273-          this.$ = yy.handler.helper.number($$[$0-1]);
 274+          this.$ = yy.handler.helper.number($$[$0 - 1]);
 275 
 276           break;
 277         case 11:
 278 
 279-          this.$ = yy.handler.helper.logicMatch('<=', $$[$0-3], $$[$0]);
 280+          this.$ = yy.handler.helper.logicMatch('<=', $$[$0 - 3], $$[$0]);
 281 
 282           break;
 283         case 12:
 284 
 285-          this.$ = yy.handler.helper.logicMatch('>=', $$[$0-3], $$[$0]);
 286+          this.$ = yy.handler.helper.logicMatch('>=', $$[$0 - 3], $$[$0]);
 287 
 288           break;
 289         case 13:
 290 
 291-          this.$ = yy.handler.helper.logicMatch('<>', $$[$0-3], $$[$0]);
 292+          this.$ = yy.handler.helper.logicMatch('<>', $$[$0 - 3], $$[$0]);
 293 
 294           break;
 295         case 14:
 296 
 297-          this.$ = yy.handler.helper.logicMatch('NOT', $$[$0-2], $$[$0]);
 298+          this.$ = yy.handler.helper.logicMatch('NOT', $$[$0 - 2], $$[$0]);
 299 
 300           break;
 301         case 15:
 302 
 303-          this.$ = yy.handler.helper.logicMatch('>', $$[$0-2], $$[$0]);
 304+          this.$ = yy.handler.helper.logicMatch('>', $$[$0 - 2], $$[$0]);
 305 
 306           break;
 307         case 16:
 308 
 309-          this.$ = yy.handler.helper.logicMatch('<', $$[$0-2], $$[$0]);
 310+          this.$ = yy.handler.helper.logicMatch('<', $$[$0 - 2], $$[$0]);
 311 
 312           break;
 313         case 17:
 314 
 315-          this.$ = yy.handler.helper.mathMatch('-', $$[$0-2], $$[$0]);
 316+          this.$ = yy.handler.helper.mathMatch('-', $$[$0 - 2], $$[$0]);
 317 
 318           break;
 319         case 18:
 320 
 321-          this.$ = yy.handler.helper.mathMatch('*', $$[$0-2], $$[$0]);
 322+          this.$ = yy.handler.helper.mathMatch('*', $$[$0 - 2], $$[$0]);
 323 
 324           break;
 325         case 19:
 326 
 327-          this.$ = yy.handler.helper.mathMatch('/', $$[$0-2], $$[$0]);
 328+          this.$ = yy.handler.helper.mathMatch('/', $$[$0 - 2], $$[$0]);
 329 
 330           break;
 331         case 20:
 332 
 333-          this.$ = yy.handler.helper.mathMatch('^', $$[$0-2], $$[$0]);
 334+          this.$ = yy.handler.helper.mathMatch('^', $$[$0 - 2], $$[$0]);
 335 
 336           break;
 337         case 21:
 338@@ -203,12 +277,12 @@ var Parser = (function(){
 339           break;
 340         case 23:
 341 
 342-          this.$ = yy.handler.helper.callFunction.call(this, $$[$0-2], '');
 343+          this.$ = yy.handler.helper.callFunction.call(this, $$[$0 - 2], '');
 344 
 345           break;
 346         case 24:
 347 
 348-          this.$ = yy.handler.helper.callFunction.call(this, $$[$0-3], $$[$0-1]);
 349+          this.$ = yy.handler.helper.callFunction.call(this, $$[$0 - 3], $$[$0 - 1]);
 350 
 351           break;
 352         case 28:
 353@@ -218,7 +292,7 @@ var Parser = (function(){
 354           break;
 355         case 29:
 356 
 357-          this.$ = yy.handler.helper.fixedCellRangeValue.call(yy.obj, $$[$0-2], $$[$0]);
 358+          this.$ = yy.handler.helper.fixedCellRangeValue.call(yy.obj, $$[$0 - 2], $$[$0]);
 359 
 360           break;
 361         case 30:
 362@@ -228,7 +302,7 @@ var Parser = (function(){
 363           break;
 364         case 31:
 365 
 366-          this.$ = yy.handler.helper.cellRangeValue.call(yy.obj, $$[$0-2], $$[$0]);
 367+          this.$ = yy.handler.helper.cellRangeValue.call(yy.obj, $$[$0 - 2], $$[$0]);
 368 
 369           break;
 370         case 32:
 371@@ -252,12 +326,13 @@ var Parser = (function(){
 372           this.$ = result;
 373 
 374           break;
 375-        case 34: case 35:
 376+        case 34:
 377+        case 35:
 378 
 379-        $$[$0-2].push($$[$0]);
 380-        this.$ = $$[$0-2];
 381+          $$[$0 - 2].push($$[$0]);
 382+          this.$ = $$[$0 - 2];
 383 
 384-        break;
 385+          break;
 386         case 36:
 387 
 388           this.$ = [$$[$0]];
 389@@ -265,7 +340,7 @@ var Parser = (function(){
 390           break;
 391         case 37:
 392 
 393-          this.$ = (yy.handler.utils.isArray($$[$0-2]) ? $$[$0-2] : [$$[$0-2]]);
 394+          this.$ = (yy.handler.utils.isArray($$[$0 - 2]) ? $$[$0 - 2] : [$$[$0 - 2]]);
 395           this.$.push($$[$0]);
 396 
 397           break;
 398@@ -276,23 +351,496 @@ var Parser = (function(){
 399           break;
 400         case 39:
 401 
 402-          this.$ = ($$[$0-2] + '.' + $$[$0]) * 1;
 403+          this.$ = ($$[$0 - 2] + '.' + $$[$0]) * 1;
 404 
 405           break;
 406         case 40:
 407 
 408-          this.$ = $$[$0-1] * 0.01;
 409+          this.$ = $$[$0 - 1] * 0.01;
 410 
 411           break;
 412-        case 41: case 42:
 413+        case 41:
 414+        case 42:
 415 
 416-        this.$ = $$[$0-2] + $$[$0-1] + $$[$0];
 417+          this.$ = $$[$0 - 2] + $$[$0 - 1] + $$[$0];
 418 
 419-        break;
 420+          break;
 421       }
 422     },
 423-    table: [{2:13,3:1,4:2,6:3,7:$V0,8:$V1,9:6,10:$V2,13:$V3,14:$V4,19:$V5,23:$V6,25:12,26:$V7,28:$V8,32:$V9,34:$Va,36:$Vb},{1:[3]},{5:[1,19],11:$Vc,12:$Vd,13:$Ve,16:$Vf,17:$Vg,18:$Vh,19:$Vi,20:$Vj,21:$Vk,22:$Vl},o($Vm,[2,2],{33:[1,30]}),o($Vm,[2,3]),o($Vm,[2,4]),o($Vm,[2,5],{35:[1,31]}),o($Vm,[2,6]),{2:13,4:32,6:3,7:$V0,8:$V1,9:6,10:$V2,13:$V3,14:$V4,19:$V5,23:$V6,25:12,26:$V7,28:$V8,32:$V9,34:$Va,36:$Vb},{2:13,4:33,6:3,7:$V0,8:$V1,9:6,10:$V2,13:$V3,14:$V4,19:$V5,23:$V6,25:12,26:$V7,28:$V8,32:$V9,34:$Va,36:$Vb},{2:13,4:34,6:3,7:$V0,8:$V1,9:6,10:$V2,13:$V3,14:$V4,19:$V5,23:$V6,25:12,26:$V7,28:$V8,32:$V9,34:$Va,36:$Vb},{14:[1,35]},o($Vm,[2,25]),o($Vm,[2,26],{2:36,32:[1,37],36:$Vb}),o($Vn,[2,36],{36:$Vo}),o($Vp,[2,38],{33:[1,39]}),o($Vm,[2,28],{27:[1,40]}),o($Vm,[2,30],{27:[1,41]}),{32:[1,42]},{1:[2,1]},{2:13,4:43,6:3,7:$V0,8:$V1,9:6,10:$V2,13:$V3,14:$V4,19:$V5,23:$V6,25:12,26:$V7,28:$V8,32:$V9,34:$Va,36:$Vb},{2:13,4:44,6:3,7:$V0,8:$V1,9:6,10:$V2,13:$V3,14:$V4,19:$V5,23:$V6,25:12,26:$V7,28:$V8,32:$V9,34:$Va,36:$Vb},{2:13,4:45,6:3,7:$V0,8:$V1,9:6,10:$V2,13:$V3,14:$V4,19:$V5,23:$V6,25:12,26:$V7,28:$V8,32:$V9,34:$Va,36:$Vb},{2:13,4:48,6:3,7:$V0,8:$V1,9:6,10:$V2,12:[1,46],13:$V3,14:$V4,17:[1,47],19:$V5,23:$V6,25:12,26:$V7,28:$V8,32:$V9,34:$Va,36:$Vb},{2:13,4:50,6:3,7:$V0,8:$V1,9:6,10:$V2,12:[1,49],13:$V3,14:$V4,19:$V5,23:$V6,25:12,26:$V7,28:$V8,32:$V9,34:$Va,36:$Vb},{2:13,4:51,6:3,7:$V0,8:$V1,9:6,10:$V2,13:$V3,14:$V4,19:$V5,23:$V6,25:12,26:$V7,28:$V8,32:$V9,34:$Va,36:$Vb},{2:13,4:52,6:3,7:$V0,8:$V1,9:6,10:$V2,13:$V3,14:$V4,19:$V5,23:$V6,25:12,26:$V7,28:$V8,32:$V9,34:$Va,36:$Vb},{2:13,4:53,6:3,7:$V0,8:$V1,9:6,10:$V2,13:$V3,14:$V4,19:$V5,23:$V6,25:12,26:$V7,28:$V8,32:$V9,34:$Va,36:$Vb},{2:13,4:54,6:3,7:$V0,8:$V1,9:6,10:$V2,13:$V3,14:$V4,19:$V5,23:$V6,25:12,26:$V7,28:$V8,32:$V9,34:$Va,36:$Vb},{2:13,4:55,6:3,7:$V0,8:$V1,9:6,10:$V2,13:$V3,14:$V4,19:$V5,23:$V6,25:12,26:$V7,28:$V8,32:$V9,34:$Va,36:$Vb},{32:[1,56]},o($Vp,[2,40]),{11:$Vc,12:$Vd,13:$Ve,15:[1,57],16:$Vf,17:$Vg,18:$Vh,19:$Vi,20:$Vj,21:$Vk,22:$Vl},o($Vq,[2,21],{11:$Vc,20:$Vj,21:$Vk,22:$Vl}),o($Vq,[2,22],{11:$Vc,20:$Vj,21:$Vk,22:$Vl}),{2:13,4:60,6:3,7:$V0,8:$V1,9:6,10:$V2,13:$V3,14:$V4,15:[1,58],19:$V5,23:$V6,24:59,25:12,26:$V7,28:$V8,29:[1,61],32:$V9,34:$Va,36:$Vb},o($Vm,[2,27]),{36:$Vo},{32:[1,62]},{34:[1,63]},{26:[1,64]},{28:[1,65]},{37:[1,66]},o($Vm,[2,7]),o([5,12,15,30,31],[2,8],{11:$Vc,13:$Ve,16:$Vf,17:$Vg,18:$Vh,19:$Vi,20:$Vj,21:$Vk,22:$Vl}),o($Vq,[2,9],{11:$Vc,20:$Vj,21:$Vk,22:$Vl}),{2:13,4:67,6:3,7:$V0,8:$V1,9:6,10:$V2,13:$V3,14:$V4,19:$V5,23:$V6,25:12,26:$V7,28:$V8,32:$V9,34:$Va,36:$Vb},{2:13,4:68,6:3,7:$V0,8:$V1,9:6,10:$V2,13:$V3,14:$V4,19:$V5,23:$V6,25:12,26:$V7,28:$V8,32:$V9,34:$Va,36:$Vb},o($Vr,[2,16],{11:$Vc,13:$Ve,19:$Vi,20:$Vj,21:$Vk,22:$Vl}),{2:13,4:69,6:3,7:$V0,8:$V1,9:6,10:$V2,13:$V3,14:$V4,19:$V5,23:$V6,25:12,26:$V7,28:$V8,32:$V9,34:$Va,36:$Vb},o($Vr,[2,15],{11:$Vc,13:$Ve,19:$Vi,20:$Vj,21:$Vk,22:$Vl}),o([5,12,15,18,30,31],[2,14],{11:$Vc,13:$Ve,16:$Vf,17:$Vg,19:$Vi,20:$Vj,21:$Vk,22:$Vl}),o($Vq,[2,17],{11:$Vc,20:$Vj,21:$Vk,22:$Vl}),o($Vs,[2,18],{11:$Vc,22:$Vl}),o($Vs,[2,19],{11:$Vc,22:$Vl}),o([5,12,13,15,16,17,18,19,20,21,22,30,31],[2,20],{11:$Vc}),o($Vn,[2,37]),o($Vm,[2,10]),o($Vm,[2,23]),{15:[1,70],30:[1,71],31:[1,72]},o($Vt,[2,32],{11:$Vc,12:$Vd,13:$Ve,16:$Vf,17:$Vg,18:$Vh,19:$Vi,20:$Vj,21:$Vk,22:$Vl}),o($Vt,[2,33]),{37:[1,73]},o($Vp,[2,39]),o($Vm,[2,29]),o($Vm,[2,31]),o($Vu,[2,41]),o($Vr,[2,11],{11:$Vc,13:$Ve,19:$Vi,20:$Vj,21:$Vk,22:$Vl}),o($Vr,[2,13],{11:$Vc,13:$Ve,19:$Vi,20:$Vj,21:$Vk,22:$Vl}),o($Vr,[2,12],{11:$Vc,13:$Ve,19:$Vi,20:$Vj,21:$Vk,22:$Vl}),o($Vm,[2,24]),{2:13,4:74,6:3,7:$V0,8:$V1,9:6,10:$V2,13:$V3,14:$V4,19:$V5,23:$V6,25:12,26:$V7,28:$V8,32:$V9,34:$Va,36:$Vb},{2:13,4:75,6:3,7:$V0,8:$V1,9:6,10:$V2,13:$V3,14:$V4,19:$V5,23:$V6,25:12,26:$V7,28:$V8,32:$V9,34:$Va,36:$Vb},o($Vu,[2,42]),o($Vt,[2,34],{11:$Vc,12:$Vd,13:$Ve,16:$Vf,17:$Vg,18:$Vh,19:$Vi,20:$Vj,21:$Vk,22:$Vl}),o($Vt,[2,35],{11:$Vc,12:$Vd,13:$Ve,16:$Vf,17:$Vg,18:$Vh,19:$Vi,20:$Vj,21:$Vk,22:$Vl})],
 424-    defaultActions: {19:[2,1]},
 425+    table: [{
 426+      2: 13,
 427+      3: 1,
 428+      4: 2,
 429+      6: 3,
 430+      7: $V0,
 431+      8: $V1,
 432+      9: 6,
 433+      10: $V2,
 434+      13: $V3,
 435+      14: $V4,
 436+      19: $V5,
 437+      23: $V6,
 438+      25: 12,
 439+      26: $V7,
 440+      28: $V8,
 441+      32: $V9,
 442+      34: $Va,
 443+      36: $Vb
 444+    }, {1: [3]}, {
 445+      5: [1, 19],
 446+      11: $Vc,
 447+      12: $Vd,
 448+      13: $Ve,
 449+      16: $Vf,
 450+      17: $Vg,
 451+      18: $Vh,
 452+      19: $Vi,
 453+      20: $Vj,
 454+      21: $Vk,
 455+      22: $Vl
 456+    }, o($Vm, [2, 2], {33: [1, 30]}), o($Vm, [2, 3]), o($Vm, [2, 4]), o($Vm, [2, 5], {35: [1, 31]}), o($Vm, [2, 6]), {
 457+      2: 13,
 458+      4: 32,
 459+      6: 3,
 460+      7: $V0,
 461+      8: $V1,
 462+      9: 6,
 463+      10: $V2,
 464+      13: $V3,
 465+      14: $V4,
 466+      19: $V5,
 467+      23: $V6,
 468+      25: 12,
 469+      26: $V7,
 470+      28: $V8,
 471+      32: $V9,
 472+      34: $Va,
 473+      36: $Vb
 474+    }, {
 475+      2: 13,
 476+      4: 33,
 477+      6: 3,
 478+      7: $V0,
 479+      8: $V1,
 480+      9: 6,
 481+      10: $V2,
 482+      13: $V3,
 483+      14: $V4,
 484+      19: $V5,
 485+      23: $V6,
 486+      25: 12,
 487+      26: $V7,
 488+      28: $V8,
 489+      32: $V9,
 490+      34: $Va,
 491+      36: $Vb
 492+    }, {
 493+      2: 13,
 494+      4: 34,
 495+      6: 3,
 496+      7: $V0,
 497+      8: $V1,
 498+      9: 6,
 499+      10: $V2,
 500+      13: $V3,
 501+      14: $V4,
 502+      19: $V5,
 503+      23: $V6,
 504+      25: 12,
 505+      26: $V7,
 506+      28: $V8,
 507+      32: $V9,
 508+      34: $Va,
 509+      36: $Vb
 510+    }, {14: [1, 35]}, o($Vm, [2, 25]), o($Vm, [2, 26], {
 511+      2: 36,
 512+      32: [1, 37],
 513+      36: $Vb
 514+    }), o($Vn, [2, 36], {36: $Vo}), o($Vp, [2, 38], {33: [1, 39]}), o($Vm, [2, 28], {27: [1, 40]}), o($Vm, [2, 30], {27: [1, 41]}), {32: [1, 42]}, {1: [2, 1]}, {
 515+      2: 13,
 516+      4: 43,
 517+      6: 3,
 518+      7: $V0,
 519+      8: $V1,
 520+      9: 6,
 521+      10: $V2,
 522+      13: $V3,
 523+      14: $V4,
 524+      19: $V5,
 525+      23: $V6,
 526+      25: 12,
 527+      26: $V7,
 528+      28: $V8,
 529+      32: $V9,
 530+      34: $Va,
 531+      36: $Vb
 532+    }, {
 533+      2: 13,
 534+      4: 44,
 535+      6: 3,
 536+      7: $V0,
 537+      8: $V1,
 538+      9: 6,
 539+      10: $V2,
 540+      13: $V3,
 541+      14: $V4,
 542+      19: $V5,
 543+      23: $V6,
 544+      25: 12,
 545+      26: $V7,
 546+      28: $V8,
 547+      32: $V9,
 548+      34: $Va,
 549+      36: $Vb
 550+    }, {
 551+      2: 13,
 552+      4: 45,
 553+      6: 3,
 554+      7: $V0,
 555+      8: $V1,
 556+      9: 6,
 557+      10: $V2,
 558+      13: $V3,
 559+      14: $V4,
 560+      19: $V5,
 561+      23: $V6,
 562+      25: 12,
 563+      26: $V7,
 564+      28: $V8,
 565+      32: $V9,
 566+      34: $Va,
 567+      36: $Vb
 568+    }, {
 569+      2: 13,
 570+      4: 48,
 571+      6: 3,
 572+      7: $V0,
 573+      8: $V1,
 574+      9: 6,
 575+      10: $V2,
 576+      12: [1, 46],
 577+      13: $V3,
 578+      14: $V4,
 579+      17: [1, 47],
 580+      19: $V5,
 581+      23: $V6,
 582+      25: 12,
 583+      26: $V7,
 584+      28: $V8,
 585+      32: $V9,
 586+      34: $Va,
 587+      36: $Vb
 588+    }, {
 589+      2: 13,
 590+      4: 50,
 591+      6: 3,
 592+      7: $V0,
 593+      8: $V1,
 594+      9: 6,
 595+      10: $V2,
 596+      12: [1, 49],
 597+      13: $V3,
 598+      14: $V4,
 599+      19: $V5,
 600+      23: $V6,
 601+      25: 12,
 602+      26: $V7,
 603+      28: $V8,
 604+      32: $V9,
 605+      34: $Va,
 606+      36: $Vb
 607+    }, {
 608+      2: 13,
 609+      4: 51,
 610+      6: 3,
 611+      7: $V0,
 612+      8: $V1,
 613+      9: 6,
 614+      10: $V2,
 615+      13: $V3,
 616+      14: $V4,
 617+      19: $V5,
 618+      23: $V6,
 619+      25: 12,
 620+      26: $V7,
 621+      28: $V8,
 622+      32: $V9,
 623+      34: $Va,
 624+      36: $Vb
 625+    }, {
 626+      2: 13,
 627+      4: 52,
 628+      6: 3,
 629+      7: $V0,
 630+      8: $V1,
 631+      9: 6,
 632+      10: $V2,
 633+      13: $V3,
 634+      14: $V4,
 635+      19: $V5,
 636+      23: $V6,
 637+      25: 12,
 638+      26: $V7,
 639+      28: $V8,
 640+      32: $V9,
 641+      34: $Va,
 642+      36: $Vb
 643+    }, {
 644+      2: 13,
 645+      4: 53,
 646+      6: 3,
 647+      7: $V0,
 648+      8: $V1,
 649+      9: 6,
 650+      10: $V2,
 651+      13: $V3,
 652+      14: $V4,
 653+      19: $V5,
 654+      23: $V6,
 655+      25: 12,
 656+      26: $V7,
 657+      28: $V8,
 658+      32: $V9,
 659+      34: $Va,
 660+      36: $Vb
 661+    }, {
 662+      2: 13,
 663+      4: 54,
 664+      6: 3,
 665+      7: $V0,
 666+      8: $V1,
 667+      9: 6,
 668+      10: $V2,
 669+      13: $V3,
 670+      14: $V4,
 671+      19: $V5,
 672+      23: $V6,
 673+      25: 12,
 674+      26: $V7,
 675+      28: $V8,
 676+      32: $V9,
 677+      34: $Va,
 678+      36: $Vb
 679+    }, {
 680+      2: 13,
 681+      4: 55,
 682+      6: 3,
 683+      7: $V0,
 684+      8: $V1,
 685+      9: 6,
 686+      10: $V2,
 687+      13: $V3,
 688+      14: $V4,
 689+      19: $V5,
 690+      23: $V6,
 691+      25: 12,
 692+      26: $V7,
 693+      28: $V8,
 694+      32: $V9,
 695+      34: $Va,
 696+      36: $Vb
 697+    }, {32: [1, 56]}, o($Vp, [2, 40]), {
 698+      11: $Vc,
 699+      12: $Vd,
 700+      13: $Ve,
 701+      15: [1, 57],
 702+      16: $Vf,
 703+      17: $Vg,
 704+      18: $Vh,
 705+      19: $Vi,
 706+      20: $Vj,
 707+      21: $Vk,
 708+      22: $Vl
 709+    }, o($Vq, [2, 21], {11: $Vc, 20: $Vj, 21: $Vk, 22: $Vl}), o($Vq, [2, 22], {
 710+      11: $Vc,
 711+      20: $Vj,
 712+      21: $Vk,
 713+      22: $Vl
 714+    }), {
 715+      2: 13,
 716+      4: 60,
 717+      6: 3,
 718+      7: $V0,
 719+      8: $V1,
 720+      9: 6,
 721+      10: $V2,
 722+      13: $V3,
 723+      14: $V4,
 724+      15: [1, 58],
 725+      19: $V5,
 726+      23: $V6,
 727+      24: 59,
 728+      25: 12,
 729+      26: $V7,
 730+      28: $V8,
 731+      29: [1, 61],
 732+      32: $V9,
 733+      34: $Va,
 734+      36: $Vb
 735+    }, o($Vm, [2, 27]), {36: $Vo}, {32: [1, 62]}, {34: [1, 63]}, {26: [1, 64]}, {28: [1, 65]}, {37: [1, 66]}, o($Vm, [2, 7]), o([5, 12, 15, 30, 31], [2, 8], {
 736+      11: $Vc,
 737+      13: $Ve,
 738+      16: $Vf,
 739+      17: $Vg,
 740+      18: $Vh,
 741+      19: $Vi,
 742+      20: $Vj,
 743+      21: $Vk,
 744+      22: $Vl
 745+    }), o($Vq, [2, 9], {11: $Vc, 20: $Vj, 21: $Vk, 22: $Vl}), {
 746+      2: 13,
 747+      4: 67,
 748+      6: 3,
 749+      7: $V0,
 750+      8: $V1,
 751+      9: 6,
 752+      10: $V2,
 753+      13: $V3,
 754+      14: $V4,
 755+      19: $V5,
 756+      23: $V6,
 757+      25: 12,
 758+      26: $V7,
 759+      28: $V8,
 760+      32: $V9,
 761+      34: $Va,
 762+      36: $Vb
 763+    }, {
 764+      2: 13,
 765+      4: 68,
 766+      6: 3,
 767+      7: $V0,
 768+      8: $V1,
 769+      9: 6,
 770+      10: $V2,
 771+      13: $V3,
 772+      14: $V4,
 773+      19: $V5,
 774+      23: $V6,
 775+      25: 12,
 776+      26: $V7,
 777+      28: $V8,
 778+      32: $V9,
 779+      34: $Va,
 780+      36: $Vb
 781+    }, o($Vr, [2, 16], {11: $Vc, 13: $Ve, 19: $Vi, 20: $Vj, 21: $Vk, 22: $Vl}), {
 782+      2: 13,
 783+      4: 69,
 784+      6: 3,
 785+      7: $V0,
 786+      8: $V1,
 787+      9: 6,
 788+      10: $V2,
 789+      13: $V3,
 790+      14: $V4,
 791+      19: $V5,
 792+      23: $V6,
 793+      25: 12,
 794+      26: $V7,
 795+      28: $V8,
 796+      32: $V9,
 797+      34: $Va,
 798+      36: $Vb
 799+    }, o($Vr, [2, 15], {
 800+      11: $Vc,
 801+      13: $Ve,
 802+      19: $Vi,
 803+      20: $Vj,
 804+      21: $Vk,
 805+      22: $Vl
 806+    }), o([5, 12, 15, 18, 30, 31], [2, 14], {
 807+      11: $Vc,
 808+      13: $Ve,
 809+      16: $Vf,
 810+      17: $Vg,
 811+      19: $Vi,
 812+      20: $Vj,
 813+      21: $Vk,
 814+      22: $Vl
 815+    }), o($Vq, [2, 17], {11: $Vc, 20: $Vj, 21: $Vk, 22: $Vl}), o($Vs, [2, 18], {
 816+      11: $Vc,
 817+      22: $Vl
 818+    }), o($Vs, [2, 19], {
 819+      11: $Vc,
 820+      22: $Vl
 821+    }), o([5, 12, 13, 15, 16, 17, 18, 19, 20, 21, 22, 30, 31], [2, 20], {11: $Vc}), o($Vn, [2, 37]), o($Vm, [2, 10]), o($Vm, [2, 23]), {
 822+      15: [1, 70],
 823+      30: [1, 71],
 824+      31: [1, 72]
 825+    }, o($Vt, [2, 32], {
 826+      11: $Vc,
 827+      12: $Vd,
 828+      13: $Ve,
 829+      16: $Vf,
 830+      17: $Vg,
 831+      18: $Vh,
 832+      19: $Vi,
 833+      20: $Vj,
 834+      21: $Vk,
 835+      22: $Vl
 836+    }), o($Vt, [2, 33]), {37: [1, 73]}, o($Vp, [2, 39]), o($Vm, [2, 29]), o($Vm, [2, 31]), o($Vu, [2, 41]), o($Vr, [2, 11], {
 837+      11: $Vc,
 838+      13: $Ve,
 839+      19: $Vi,
 840+      20: $Vj,
 841+      21: $Vk,
 842+      22: $Vl
 843+    }), o($Vr, [2, 13], {11: $Vc, 13: $Ve, 19: $Vi, 20: $Vj, 21: $Vk, 22: $Vl}), o($Vr, [2, 12], {
 844+      11: $Vc,
 845+      13: $Ve,
 846+      19: $Vi,
 847+      20: $Vj,
 848+      21: $Vk,
 849+      22: $Vl
 850+    }), o($Vm, [2, 24]), {
 851+      2: 13,
 852+      4: 74,
 853+      6: 3,
 854+      7: $V0,
 855+      8: $V1,
 856+      9: 6,
 857+      10: $V2,
 858+      13: $V3,
 859+      14: $V4,
 860+      19: $V5,
 861+      23: $V6,
 862+      25: 12,
 863+      26: $V7,
 864+      28: $V8,
 865+      32: $V9,
 866+      34: $Va,
 867+      36: $Vb
 868+    }, {
 869+      2: 13,
 870+      4: 75,
 871+      6: 3,
 872+      7: $V0,
 873+      8: $V1,
 874+      9: 6,
 875+      10: $V2,
 876+      13: $V3,
 877+      14: $V4,
 878+      19: $V5,
 879+      23: $V6,
 880+      25: 12,
 881+      26: $V7,
 882+      28: $V8,
 883+      32: $V9,
 884+      34: $Va,
 885+      36: $Vb
 886+    }, o($Vu, [2, 42]), o($Vt, [2, 34], {
 887+      11: $Vc,
 888+      12: $Vd,
 889+      13: $Ve,
 890+      16: $Vf,
 891+      17: $Vg,
 892+      18: $Vh,
 893+      19: $Vi,
 894+      20: $Vj,
 895+      21: $Vk,
 896+      22: $Vl
 897+    }), o($Vt, [2, 35], {11: $Vc, 12: $Vd, 13: $Ve, 16: $Vf, 17: $Vg, 18: $Vh, 19: $Vi, 20: $Vj, 21: $Vk, 22: $Vl})],
 898+    defaultActions: {19: [2, 1]},
 899     parseError: function parseError(str, hash) {
 900       if (hash.recoverable) {
 901         this.trace(str);
 902@@ -319,7 +867,7 @@ var Parser = (function(){
 903       //this.reductionCount = this.shiftCount = 0;
 904 
 905       var lexer = Object.create(this.lexer);
 906-      var sharedState = { yy: {} };
 907+      var sharedState = {yy: {}};
 908       // copy state
 909       for (var k in this.yy) {
 910         if (Object.prototype.hasOwnProperty.call(this.yy, k)) {
 911@@ -344,7 +892,7 @@ var Parser = (function(){
 912         this.parseError = Object.getPrototypeOf(this).parseError;
 913       }
 914 
 915-      function popStack (n) {
 916+      function popStack(n) {
 917         stack.length = stack.length - 2 * n;
 918         vstack.length = vstack.length - n;
 919         lstack.length = lstack.length - n;
 920@@ -390,7 +938,7 @@ var Parser = (function(){
 921               var depth = 0;
 922 
 923               // try to recover from error
 924-              for(;;) {
 925+              for (; ;) {
 926                 // check for error recovery rule in this state
 927                 if ((TERROR.toString()) in table[state]) {
 928                   return depth;
 929@@ -412,15 +960,15 @@ var Parser = (function(){
 930               expected = [];
 931               for (p in table[state]) {
 932                 if (this.terminals_[p] && p > TERROR) {
 933-                  expected.push("'"+this.terminals_[p]+"'");
 934+                  expected.push("'" + this.terminals_[p] + "'");
 935                 }
 936               }
 937               if (lexer.showPosition) {
 938-                errStr = 'Parse error on line '+(yylineno+1)+":\n"+lexer.showPosition()+"\nExpecting "+expected.join(', ') + ", got '" + (this.terminals_[symbol] || symbol)+ "'";
 939+                errStr = 'Parse error on line ' + (yylineno + 1) + ":\n" + lexer.showPosition() + "\nExpecting " + expected.join(', ') + ", got '" + (this.terminals_[symbol] || symbol) + "'";
 940               } else {
 941-                errStr = 'Parse error on line '+(yylineno+1)+": Unexpected " +
 942+                errStr = 'Parse error on line ' + (yylineno + 1) + ": Unexpected " +
 943                   (symbol == EOF ? "end of input" :
 944-                    ("'"+(this.terminals_[symbol] || symbol)+"'"));
 945+                    ("'" + (this.terminals_[symbol] || symbol) + "'"));
 946               }
 947               this.parseError(errStr, {
 948                 text: lexer.match,
 949@@ -456,14 +1004,14 @@ var Parser = (function(){
 950 
 951             preErrorSymbol = (symbol == TERROR ? null : symbol); // save the lookahead token
 952             symbol = TERROR;         // insert generic error symbol as new lookahead
 953-            state = stack[stack.length-1];
 954+            state = stack[stack.length - 1];
 955             action = table[state] && table[state][TERROR];
 956             recovering = 3; // allow 3 real symbols to be shifted before reporting a new error
 957           }
 958 
 959         // this shouldn't happen, unless resolve defaults are off
 960         if (action[0] instanceof Array && action.length > 1) {
 961-          throw new Error('Parse Error: multiple actions possible at state: '+state+', token: '+symbol);
 962+          throw new Error('Parse Error: multiple actions possible at state: ' + state + ', token: ' + symbol);
 963         }
 964 
 965         switch (action[0]) {
 966@@ -497,16 +1045,16 @@ var Parser = (function(){
 967             len = this.productions_[action[1]][1];
 968 
 969             // perform semantic action
 970-            yyval.$ = vstack[vstack.length-len]; // default to $$ = $1
 971+            yyval.$ = vstack[vstack.length - len]; // default to $$ = $1
 972             // default location, uses first token for firsts, last for lasts
 973             yyval._$ = {
 974-              first_line: lstack[lstack.length-(len||1)].first_line,
 975-              last_line: lstack[lstack.length-1].last_line,
 976-              first_column: lstack[lstack.length-(len||1)].first_column,
 977-              last_column: lstack[lstack.length-1].last_column
 978+              first_line: lstack[lstack.length - (len || 1)].first_line,
 979+              last_line: lstack[lstack.length - 1].last_line,
 980+              first_column: lstack[lstack.length - (len || 1)].first_column,
 981+              last_column: lstack[lstack.length - 1].last_column
 982             };
 983             if (ranges) {
 984-              yyval._$.range = [lstack[lstack.length-(len||1)].range[0], lstack[lstack.length-1].range[1]];
 985+              yyval._$.range = [lstack[lstack.length - (len || 1)].range[0], lstack[lstack.length - 1].range[1]];
 986             }
 987             r = this.performAction.apply(yyval, [yytext, yyleng, yylineno, sharedState.yy, action[1], vstack, lstack].concat(args));
 988 
 989@@ -516,16 +1064,16 @@ var Parser = (function(){
 990 
 991             // pop off stack
 992             if (len) {
 993-              stack = stack.slice(0,-1*len*2);
 994-              vstack = vstack.slice(0, -1*len);
 995-              lstack = lstack.slice(0, -1*len);
 996+              stack = stack.slice(0, -1 * len * 2);
 997+              vstack = vstack.slice(0, -1 * len);
 998+              lstack = lstack.slice(0, -1 * len);
 999             }
1000 
1001             stack.push(this.productions_[action[1]][0]);    // push nonterminal (reduce)
1002             vstack.push(yyval.$);
1003             lstack.push(yyval._$);
1004             // goto new state = table[STATE][NONTERMINAL]
1005-            newState = table[stack[stack.length-2]][stack[stack.length-1]];
1006+            newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
1007             stack.push(newState);
1008             break;
1009 
1010@@ -537,15 +1085,16 @@ var Parser = (function(){
1011       }
1012 
1013       return true;
1014-    }};
1015+    }
1016+  };
1017 
1018   /* generated by jison-lex 0.3.4 */
1019-  var lexer = (function(){
1020+  var lexer = (function () {
1021     var lexer = ({
1022 
1023-      EOF:1,
1024+      EOF: 1,
1025 
1026-      parseError:function parseError(str, hash) {
1027+      parseError: function parseError(str, hash) {
1028         if (this.yy.parser) {
1029           this.yy.parser.parseError(str, hash);
1030         } else {
1031@@ -554,7 +1103,7 @@ var Parser = (function(){
1032       },
1033 
1034 // resets the lexer, sets new input
1035-      setInput:function (input, yy) {
1036+      setInput: function (input, yy) {
1037         this.yy = yy || this.yy || {};
1038         this._input = input;
1039         this._more = this._backtrack = this.done = false;
1040@@ -568,14 +1117,14 @@ var Parser = (function(){
1041           last_column: 0
1042         };
1043         if (this.options.ranges) {
1044-          this.yylloc.range = [0,0];
1045+          this.yylloc.range = [0, 0];
1046         }
1047         this.offset = 0;
1048         return this;
1049       },
1050 
1051 // consumes and returns one char from the input
1052-      input:function () {
1053+      input: function () {
1054         var ch = this._input[0];
1055         this.yytext += ch;
1056         this.yyleng++;
1057@@ -598,7 +1147,7 @@ var Parser = (function(){
1058       },
1059 
1060 // unshifts one char (or a string) into the input
1061-      unput:function (ch) {
1062+      unput: function (ch) {
1063         var len = ch.length;
1064         var lines = ch.split(/(?:\r\n?|\n)/g);
1065 
1066@@ -633,13 +1182,13 @@ var Parser = (function(){
1067       },
1068 
1069 // When called from action, caches matched text and appends it on next action
1070-      more:function () {
1071+      more: function () {
1072         this._more = true;
1073         return this;
1074       },
1075 
1076 // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead.
1077-      reject:function () {
1078+      reject: function () {
1079         if (this.options.backtrack_lexer) {
1080           this._backtrack = true;
1081         } else {
1082@@ -654,34 +1203,34 @@ var Parser = (function(){
1083       },
1084 
1085 // retain first n characters of the match
1086-      less:function (n) {
1087+      less: function (n) {
1088         this.unput(this.match.slice(n));
1089       },
1090 
1091 // displays already matched input, i.e. for error messages
1092-      pastInput:function () {
1093+      pastInput: function () {
1094         var past = this.matched.substr(0, this.matched.length - this.match.length);
1095-        return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
1096+        return (past.length > 20 ? '...' : '') + past.substr(-20).replace(/\n/g, "");
1097       },
1098 
1099 // displays upcoming input, i.e. for error messages
1100-      upcomingInput:function () {
1101+      upcomingInput: function () {
1102         var next = this.match;
1103         if (next.length < 20) {
1104-          next += this._input.substr(0, 20-next.length);
1105+          next += this._input.substr(0, 20 - next.length);
1106         }
1107-        return (next.substr(0,20) + (next.length > 20 ? '...' : '')).replace(/\n/g, "");
1108+        return (next.substr(0, 20) + (next.length > 20 ? '...' : '')).replace(/\n/g, "");
1109       },
1110 
1111 // displays the character position where the lexing error occurred, i.e. for error messages
1112-      showPosition:function () {
1113+      showPosition: function () {
1114         var pre = this.pastInput();
1115         var c = new Array(pre.length + 1).join("-");
1116         return pre + this.upcomingInput() + "\n" + c + "^";
1117       },
1118 
1119 // test the lexed token: return FALSE when not a match, otherwise return token
1120-      test_match:function (match, indexed_rule) {
1121+      test_match: function (match, indexed_rule) {
1122         var token,
1123           lines,
1124           backup;
1125@@ -753,7 +1302,7 @@ var Parser = (function(){
1126       },
1127 
1128 // return next match in input
1129-      next:function () {
1130+      next: function () {
1131         if (this.done) {
1132           return this.EOF;
1133         }
1134@@ -811,7 +1360,7 @@ var Parser = (function(){
1135       },
1136 
1137 // return next match that has a token
1138-      lex:function lex() {
1139+      lex: function lex() {
1140         var r = this.next();
1141         if (r) {
1142           return r;
1143@@ -821,12 +1370,12 @@ var Parser = (function(){
1144       },
1145 
1146 // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack)
1147-      begin:function begin(condition) {
1148+      begin: function begin(condition) {
1149         this.conditionStack.push(condition);
1150       },
1151 
1152 // pop the previously active lexer condition state off the condition stack
1153-      popState:function popState() {
1154+      popState: function popState() {
1155         var n = this.conditionStack.length - 1;
1156         if (n > 0) {
1157           return this.conditionStack.pop();
1158@@ -836,7 +1385,7 @@ var Parser = (function(){
1159       },
1160 
1161 // produce the lexer rule set which is active for the currently active lexer condition state
1162-      _currentRules:function _currentRules() {
1163+      _currentRules: function _currentRules() {
1164         if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) {
1165           return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules;
1166         } else {
1167@@ -845,7 +1394,7 @@ var Parser = (function(){
1168       },
1169 
1170 // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available
1171-      topState:function topState(n) {
1172+      topState: function topState(n) {
1173         n = this.conditionStack.length - 1 - Math.abs(n || 0);
1174         if (n >= 0) {
1175           return this.conditionStack[n];
1176@@ -855,29 +1404,34 @@ var Parser = (function(){
1177       },
1178 
1179 // alias for begin(condition)
1180-      pushState:function pushState(condition) {
1181+      pushState: function pushState(condition) {
1182         this.begin(condition);
1183       },
1184 
1185 // return the number of states currently on the stack
1186-      stateStackSize:function stateStackSize() {
1187+      stateStackSize: function stateStackSize() {
1188         return this.conditionStack.length;
1189       },
1190       options: {},
1191-      performAction: function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
1192-        var YYSTATE=YY_START;
1193-        switch($avoiding_name_collisions) {
1194+      performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) {
1195+        var YYSTATE = YY_START;
1196+        switch ($avoiding_name_collisions) {
1197           case 0:/* skip whitespace */
1198             break;
1199-          case 1:return 10;
1200+          case 1:
1201+            return 10;
1202             break;
1203-          case 2:return 10;
1204+          case 2:
1205+            return 10;
1206             break;
1207-          case 3:return 23;
1208+          case 3:
1209+            return 23;
1210             break;
1211-          case 4:return 7;
1212+          case 4:
1213+            return 7;
1214             break;
1215-          case 5:return 8;
1216+          case 5:
1217+            return 8;
1218             break;
1219           case 6:
1220             //if (yy.obj.type == 'cell') return 26;
1221@@ -891,68 +1445,96 @@ var Parser = (function(){
1222             return 28;
1223 
1224             break;
1225-          case 8:return 23;
1226+          case 8:
1227+            return 23;
1228             break;
1229-          case 9:return 32;
1230+          case 9:
1231+            return 32;
1232             break;
1233-          case 10:return 32;
1234+          case 10:
1235+            return 32;
1236             break;
1237-          case 11:return 34;
1238+          case 11:
1239+            return 34;
1240             break;
1241-          case 12:return 29;
1242+          case 12:
1243+            return 29;
1244             break;
1245           case 13:/* skip whitespace */
1246             break;
1247-          case 14:return 11;
1248+          case 14:
1249+            return 11;
1250             break;
1251-          case 15:return ' ';
1252+          case 15:
1253+            return ' ';
1254             break;
1255-          case 16:return 33;
1256+          case 16:
1257+            return 33;
1258             break;
1259-          case 17:return 27;
1260+          case 17:
1261+            return 27;
1262             break;
1263-          case 18:return 30;
1264+          case 18:
1265+            return 30;
1266             break;
1267-          case 19:return 31;
1268+          case 19:
1269+            return 31;
1270             break;
1271-          case 20:return 20;
1272+          case 20:
1273+            return 20;
1274             break;
1275-          case 21:return 21;
1276+          case 21:
1277+            return 21;
1278             break;
1279-          case 22:return 19;
1280+          case 22:
1281+            return 19;
1282             break;
1283-          case 23:return 13;
1284+          case 23:
1285+            return 13;
1286             break;
1287-          case 24:return 22;
1288+          case 24:
1289+            return 22;
1290             break;
1291-          case 25:return 14;
1292+          case 25:
1293+            return 14;
1294             break;
1295-          case 26:return 15;
1296+          case 26:
1297+            return 15;
1298             break;
1299-          case 27:return 17;
1300+          case 27:
1301+            return 17;
1302             break;
1303-          case 28:return 16;
1304+          case 28:
1305+            return 16;
1306             break;
1307-          case 29:return 18;
1308+          case 29:
1309+            return 18;
1310             break;
1311-          case 30:return '"';
1312+          case 30:
1313+            return '"';
1314             break;
1315-          case 31:return "'";
1316+          case 31:
1317+            return "'";
1318             break;
1319-          case 32:return "!";
1320+          case 32:
1321+            return "!";
1322             break;
1323-          case 33:return 12;
1324+          case 33:
1325+            return 12;
1326             break;
1327-          case 34:return 35;
1328+          case 34:
1329+            return 35;
1330             break;
1331-          case 35:return 36;
1332+          case 35:
1333+            return 36;
1334             break;
1335-          case 36:return 5;
1336+          case 36:
1337+            return 5;
1338             break;
1339         }
1340       },
1341       // NOTE: Alterations made in some regular-expressions to allow for formulas containing dot-notation. Eg: F.INV
1342-      rules: [ /^(?:\s+)/,
1343+      rules: [/^(?:\s+)/,
1344         /^(?:"(\\["]|[^"])*")/,
1345         /^(?:'(\\[']|[^'])*')/,
1346         /^(?:[A-Za-z.]{1,}[A-Za-z_0-9]+(?=[(]))/, // Changed from /^(?:[A-Za-z]{1,}[A-Za-z_0-9]+(?=[(]))/
1347@@ -988,16 +1570,23 @@ var Parser = (function(){
1348         /^(?:=)/,
1349         /^(?:%)/,
1350         /^(?:[#])/,
1351-        /^(?:$)/ ],
1352-      conditions: {"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36],"inclusive":true}}
1353+        /^(?:$)/],
1354+      conditions: {
1355+        "INITIAL": {
1356+          "rules": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36],
1357+          "inclusive": true
1358+        }
1359+      }
1360     });
1361     return lexer;
1362   })();
1363   parser.lexer = lexer;
1364-  function Parser () {
1365+  function Parser() {
1366     this.yy = {};
1367   }
1368-  Parser.prototype = parser;parser.Parser = Parser;
1369+
1370+  Parser.prototype = parser;
1371+  parser.Parser = Parser;
1372   return new Parser;
1373 })();
1374 
1375diff --git a/src/Formulas/AllFormulas.ts b/src/Formulas/AllFormulas.ts
1376index 5cc850d..79602c9 100644
1377--- a/src/Formulas/AllFormulas.ts
1378+++ b/src/Formulas/AllFormulas.ts
1379@@ -49,7 +49,10 @@ import {
1380   TRUNC,
1381   RADIANS,
1382   DEGREES,
1383-  COMBIN
1384+  COMBIN,
1385+  MULTIPLY,
1386+  MINUS,
1387+  RAND
1388 } from "./Math";
1389 import {
1390   AND,
1391@@ -267,5 +270,8 @@ export {
1392   TODAY,
1393   TIME,
1394   WORKDAY,
1395-  WORKDAY$INTL
1396+  WORKDAY$INTL,
1397+  MULTIPLY,
1398+  MINUS,
1399+  RAND
1400 }
1401\ No newline at end of file
1402diff --git a/src/Formulas/Math.ts b/src/Formulas/Math.ts
1403index 9fe043f..f96a998 100644
1404--- a/src/Formulas/Math.ts
1405+++ b/src/Formulas/Math.ts
1406@@ -747,6 +747,44 @@ var SUMSQ = function (...values) {
1407 };
1408 
1409 
1410+/**
1411+ * Returns the product of two numbers. Equivalent to the `*` operator.
1412+ * @param factor1 - The first multiplicand.
1413+ * @param factor2 - The second multiplicand.
1414+ * @constructor
1415+ */
1416+var MULTIPLY = function (factor1, factor2) {
1417+  ArgsChecker.checkLength(arguments, 2, "MULTIPLY");
1418+  var x = TypeConverter.firstValueAsNumber(factor1);
1419+  var y = TypeConverter.firstValueAsNumber(factor1);
1420+  return x * y;
1421+};
1422+
1423+
1424+/**
1425+ * Returns the result of the first number minus the second number. Equivalent to the `-` operator.
1426+ * @param one - The first number.
1427+ * @param two - the second number.
1428+ * @returns {number}
1429+ * @constructor
1430+ */
1431+var MINUS = function (one, two) {
1432+  ArgsChecker.checkLength(arguments, 2, "MINUS");
1433+  var x = TypeConverter.firstValueAsNumber(one);
1434+  var y = TypeConverter.firstValueAsNumber(two);
1435+  return x - y;
1436+};
1437+
1438+/**
1439+ * Returns a random number between 0 inclusive and 1 exclusive.
1440+ * @returns {number}
1441+ * @constructor
1442+ */
1443+var RAND = function () {
1444+  ArgsChecker.checkLength(arguments, 0, "RAND");
1445+  return Math.random();
1446+};
1447+
1448 /**
1449  * Truncates a number to a certain number of significant digits by omitting less significant digits.
1450  * @param value - The value to be truncated.
1451@@ -1021,6 +1059,8 @@ export {
1452   LOG,
1453   LOG10,
1454   LN,
1455+  MULTIPLY,
1456+  MINUS,
1457   TAN,
1458   TANH,
1459   ROUND,
1460@@ -1039,5 +1079,6 @@ export {
1461   TRUNC,
1462   RADIANS,
1463   DEGREES,
1464-  COMBIN
1465+  COMBIN,
1466+  RAND
1467 }
1468\ No newline at end of file
1469diff --git a/tests/Formulas/MathTest.ts b/tests/Formulas/MathTest.ts
1470index 52a5b4a..ae27e35 100644
1471--- a/tests/Formulas/MathTest.ts
1472+++ b/tests/Formulas/MathTest.ts
1473@@ -19,6 +19,7 @@ import {
1474   INT,
1475   ISEVEN,
1476   ISODD,
1477+  MULTIPLY,
1478   MOD,
1479   ODD,
1480   SIN,
1481@@ -49,7 +50,9 @@ import {
1482   TRUNC,
1483   RADIANS,
1484   DEGREES,
1485-  COMBIN
1486+  COMBIN,
1487+  MINUS,
1488+  RAND
1489 } from "../../src/Formulas/Math";
1490 import * as ERRORS from "../../src/Errors";
1491 import {
1492@@ -1152,3 +1155,36 @@ test("TRUNC", function(){
1493     TRUNC.apply(this, [3.1, 1, 1]);
1494   }, ERRORS.NA_ERROR);
1495 });
1496+
1497+
1498+test("MULTIPLY", function(){
1499+  assertEquals(MULTIPLY(2, 2), 4);
1500+  assertEquals(MULTIPLY(2, "2"), 4);
1501+  assertEquals(MULTIPLY([2, []], ["2"]), 4);
1502+  catchAndAssertEquals(function() {
1503+    MULTIPLY.apply(this, [3.1, 1, 1]);
1504+  }, ERRORS.NA_ERROR);
1505+  catchAndAssertEquals(function() {
1506+    MULTIPLY.apply(this, [1]);
1507+  }, ERRORS.NA_ERROR);
1508+});
1509+
1510+
1511+test("MINUS", function(){
1512+  assertEquals(MINUS(2, 2), 0);
1513+  assertEquals(MINUS(2, 10), -8);
1514+  assertEquals(MINUS(2, "12"), -10);
1515+  assertEquals(MINUS([4, []], ["2"]), 2);
1516+  catchAndAssertEquals(function() {
1517+    MINUS.apply(this, [3.1, 1, 1]);
1518+  }, ERRORS.NA_ERROR);
1519+  catchAndAssertEquals(function() {
1520+    MINUS.apply(this, [1]);
1521+  }, ERRORS.NA_ERROR);
1522+});
1523+
1524+test("RAND", function(){
1525+  catchAndAssertEquals(function() {
1526+    RAND.apply(this, [3]);
1527+  }, ERRORS.NA_ERROR);
1528+});
1529diff --git a/tests/SheetFormulaTest.ts b/tests/SheetFormulaTest.ts
1530index 69142bc..a9a2a47 100644
1531--- a/tests/SheetFormulaTest.ts
1532+++ b/tests/SheetFormulaTest.ts
1533@@ -23,6 +23,14 @@ function assertFormulaEquals(formula: string, expectation: any) {
1534   assertEquals(cell.getValue(), expectation);
1535 }
1536 
1537+function assertFormulaResultsInType(formula: string, type: string) {
1538+  var sheet  = new Sheet();
1539+  sheet.setCell("A1", formula);
1540+  var cell = sheet.getCell("A1");
1541+  assertEquals(cell.getError(), null);
1542+  assertEquals(typeof cell.getValue(), type);
1543+}
1544+
1545 function testFormulaToArray(formula: string, expectation: any) {
1546   var sheet  = new Sheet();
1547   sheet.setCell("A1", formula);
1548@@ -234,6 +242,22 @@ test("Sheet DELTA", function(){
1549   assertFormulaEquals('=DELTA(2, 2)', 1);
1550 });
1551 
1552+test("Sheet RAND", function(){
1553+  assertFormulaResultsInType('=RAND()', "number");
1554+});
1555+
1556+test("Sheet MULTIPLY", function(){
1557+  assertFormulaEquals('=MULTIPLY(10, 10)', 100);
1558+});
1559+
1560+test("Sheet MULTIPLY", function(){
1561+  assertFormulaEquals('=MINUS(22, 1)', 21);
1562+});
1563+
1564+test("Sheet DELTA", function(){
1565+  assertFormulaEquals('=DELTA(2, 2)', 1);
1566+});
1567+
1568 test("Sheet DEVSQ", function(){
1569   assertFormulaEquals('=DEVSQ(1, 2)', 0.5);
1570 });