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 });