blob: d24bca30d14b476ed1d1ca10fb45fd52ec021141 [file] [log] [blame]
genia.likes.science@gmail.com512454d2013-05-28 03:32:20 -07001function AsterixSDK() {
2
3 // Asterix SDK => send
4 // Posts a message containing an API endpoint, json data,
5 // and a UI callback function.
6 //
7 // @param handler [Asterix REST Controller], a handler object
8 // that provides REST request information.
9 //
10 // Anticipated Usage:
11 //
12 // var a = AsterixSDK();
13 // var e = Expression;
14 // var h = AsterixRestController.bind(e);
15 // a.send(h);
16 myThis = this;
17 this.callbacks = {
18 "sync" : function() { alert("default sync"); },
19 "async" : function() {}
20 };
21 this.send = function(handler, cb) {
22 myThis.callbacks = cb;
23 this.handler = handler;
24 this.extras = handler["extras"];
25 this.xhr.post(
26 handler["endpoint"],
27 handler["apiData"],
28 this.branch
29 );
30 };
31
32 this.branch = function(response) {
33 if (response && response["error-code"]) {
34
35 alert("Error [Code" + response["error-code"][0] + "]: " + response["error-code"][1]);
36
37 } else if (response && response["results"]) {
38 var fn_callback = myThis.callbacks["sync"];
39 fn_callback(response, myThis.extras);
40
41 } else if (response["handle"]) {
42
43 var fn_callback = this.callbacks["async"];
44 fn_callback(response, extra);
45
46 } else if (response["status"]) {
47
48 var fn_callback = this.callbacks["sync"];
49 fn_callback(response, extra);
50 }
51 }
52
53 // Asterix SDK => bindingHandler
54 // AsterixExpression form handler where a new REST API point is bound. Takes as input any
55 // AsterixExpression, each of which is bindable.
56 this.bindingHandler = new AsterixExpression();
57 this.bind = this.bindingHandler.bind;
58}
59
60function AsterixExpression() {
61 this.init();
62 return this;
63}
64
65AsterixExpression.prototype.init = function () {
66 this.dataverse = ""; // TODO This shouldn't make it to send
67 this.boundTo = {};
68 this.clauses = [];
69 this.ui_callback_on_success = function() {};
70 this.ui_callback_on_success_async = function() {};
71};
72
73AsterixExpression.prototype.bind = function(expression) {
74 // If expression is an AsterixExpression, it becomes base
75 if (expression instanceof AsterixExpression) {
76 this.boundTo = expression;
77 } else if (expression instanceof AsterixClause) {
78 this.clauses.push(expression.val());
79 }
80 return this;
81};
82
83AsterixExpression.prototype.send = function(arc) {
84 // Hackiest of hacks
85 var g = new AsterixSDK();
86 g.send(arc, arc["callback"]);
87};
88
89AsterixExpression.prototype.clear = function() {
90 this.clauses.length = 0;
91 return this;
92};
93
94AsterixExpression.prototype.val = function() {
95 return this.clauses.join("\n");
96};
97
98AsterixExpression.prototype.success = function(fn, isSync) {
99 if (isSync) {
100 this.ui_callback_on_success = fn;
101 } else {
102 this.ui_callback_on_success_async = fn;
103 }
104 return this;
105};
106
107AsterixExpression.prototype.set = function(statements_arr) {
108 for (var i = 0; i < statements_arr.length; i++) {
109 this.clauses.push(statements_arr[i]);
110 }
111 return this;
112};
113
114AsterixExpression.prototype.use_dataverse = function(dv) {
115 this.dataverse = dv;
116 this.clauses.push("use dataverse " + dv + ";");
117 return this;
118};
119
120AsterixExpression.prototype.return = function(return_object) {
121 var components = [];
122 for (var key in return_object) {
123 components.push('"' + key + '" : ' + return_object[key]);
124 }
125
126 var return_expression = 'return { ' + components.join(', ') + ' }';
127 this.clauses.push(return_expression);
128 return this;
129};
130
genia.likes.science@gmail.com512454d2013-05-28 03:32:20 -0700131
genia.likes.science@gmail.com2ba32242013-05-31 03:10:48 -0700132// Functions that can be used to call core expressions/clauses more cleanly
133function AFLWOGR () {
genia.likes.science@gmail.com90d08722013-05-28 04:40:12 -0700134
genia.likes.science@gmail.com2ba32242013-05-31 03:10:48 -0700135}
genia.likes.science@gmail.com90d08722013-05-28 04:40:12 -0700136
genia.likes.science@gmail.com2ba32242013-05-31 03:10:48 -0700137function AClause () {
genia.likes.science@gmail.com90d08722013-05-28 04:40:12 -0700138
genia.likes.science@gmail.com2ba32242013-05-31 03:10:48 -0700139}
genia.likes.science@gmail.com90d08722013-05-28 04:40:12 -0700140
genia.likes.science@gmail.com2ba32242013-05-31 03:10:48 -0700141function ALetClause () {
genia.likes.science@gmail.com90d08722013-05-28 04:40:12 -0700142
genia.likes.science@gmail.com2ba32242013-05-31 03:10:48 -0700143}
genia.likes.science@gmail.com90d08722013-05-28 04:40:12 -0700144
genia.likes.science@gmail.com2ba32242013-05-31 03:10:48 -0700145function AWhereClause () {
genia.likes.science@gmail.com90d08722013-05-28 04:40:12 -0700146
genia.likes.science@gmail.com2ba32242013-05-31 03:10:48 -0700147}
148
149function AOrderbyClause () {
150
151}
152
153function AGroupClause () {
154
155}
156
157function ALimitClause () {
158
159}
160
161function ADistinctClause () {
162
163}
164
165function AVariable () {
166
167}
genia.likes.science@gmail.com90d08722013-05-28 04:40:12 -0700168
169// Temporary AsterixExpression Placeholder
170function AExpression () {
genia.likes.science@gmail.com512454d2013-05-28 03:32:20 -0700171 this._properties = {};
172 this._success = function() {};
173
genia.likes.science@gmail.com512454d2013-05-28 03:32:20 -0700174 return this;
175}
176
genia.likes.science@gmail.com90d08722013-05-28 04:40:12 -0700177
178AExpression.prototype.bind = function(options) {
genia.likes.science@gmail.com512454d2013-05-28 03:32:20 -0700179 var options = options || {};
180
genia.likes.science@gmail.com512454d2013-05-28 03:32:20 -0700181 if (options.hasOwnProperty("dataverse")) {
182 this._properties["dataverse"] = options["dataverse"];
183 }
184
185 if (options.hasOwnProperty("success")) {
186 this._success = options["success"];
187 }
genia.likes.science@gmail.com38612632013-05-28 13:11:52 -0700188
189 if (options.hasOwnProperty("return")) {
190 this._properties["return"] = " return " + options["return"].val();
191 }
genia.likes.science@gmail.com512454d2013-05-28 03:32:20 -0700192};
193
genia.likes.science@gmail.com512454d2013-05-28 03:32:20 -0700194
genia.likes.science@gmail.com90d08722013-05-28 04:40:12 -0700195AExpression.prototype.run = function() {
genia.likes.science@gmail.com512454d2013-05-28 03:32:20 -0700196 var success_fn = this._success;
197
198 $.ajax({
199 type : 'GET',
200 url : "http://localhost:19101/query",
201 data : {"query" : this.val()},
202 dataType : "json",
203 success : function(data) {
204 success_fn(data);
205 }
206 });
207
208 return this;
genia.likes.science@gmail.com90d08722013-05-28 04:40:12 -0700209};
210
211
212AExpression.prototype.val = function() {
213
genia.likes.science@gmail.com2ba32242013-05-31 03:10:48 -0700214 var value = "";
215
genia.likes.science@gmail.com90d08722013-05-28 04:40:12 -0700216 // If there is a dataverse defined, provide it.
217 if (this._properties.hasOwnProperty("dataverse")) {
genia.likes.science@gmail.com2ba32242013-05-31 03:10:48 -0700218 value += "use dataverse " + this._properties["dataverse"] + ";\n";
219 };
220
221 if (this._properties.hasOwnProperty("value")) {
222 value += this._properties["value"];
genia.likes.science@gmail.com90d08722013-05-28 04:40:12 -0700223 }
genia.likes.science@gmail.com2ba32242013-05-31 03:10:48 -0700224
225 return value;
genia.likes.science@gmail.com38612632013-05-28 13:11:52 -0700226};
227
genia.likes.science@gmail.com2ba32242013-05-31 03:10:48 -0700228// @param expressionValue [String]
229AExpression.prototype.set = function(expressionValue) {
230 this._properties["value"] = expressionValue;
231 return this;
genia.likes.science@gmail.com38612632013-05-28 13:11:52 -0700232};
233
genia.likes.science@gmail.com73dcc702013-05-28 04:21:28 -0700234
genia.likes.science@gmail.com90d08722013-05-28 04:40:12 -0700235AExpression.prototype.error = function(msg) {
236 return "Asterix FunctionExpression Error: " + msg;
237};
238
239
240// FunctionExpression
241// Parent: AsterixExpression
242//
243// @param options [Various],
244// @key function [String], a function to be applid to the expression
245// @key expression [AsterixExpression or AsterixClause] an AsterixExpression/Clause to which the fn will be applied
246function FunctionExpression(options) {
247
248 // Initialize superclass
249 AExpression.call(this);
250
251 // Possible to initialize a function epxression without inputs, or with them
252 this.bind(options);
253
254 // Return object
255 return this;
256}
257
258
259FunctionExpression.prototype = Object.create(AExpression.prototype);
260FunctionExpression.prototype.constructor = FunctionExpression;
261
262
263FunctionExpression.prototype.bind = function(options) {
264
265 AExpression.prototype.bind.call(this, options);
266
267 var options = options || {};
268
269 if (options.hasOwnProperty("function")) {
270 this._properties["function"] = options["function"];
271 }
272
273 if (options.hasOwnProperty("expression")) {
274 this._properties["expression"] = options["expression"];
275 }
276
277 return this;
278};
279
280FunctionExpression.prototype.val = function () {
genia.likes.science@gmail.com2ba32242013-05-31 03:10:48 -0700281 return this._properties["function"] + "(" + this._properties["expression"].val() + ")";
genia.likes.science@gmail.com90d08722013-05-28 04:40:12 -0700282};
283
genia.likes.science@gmail.com73dcc702013-05-28 04:21:28 -0700284
genia.likes.science@gmail.com73dcc702013-05-28 04:21:28 -0700285// FLWOGR ::= ( ForClause | LetClause ) ( Clause )* "return" Expression
286// Clause ::= ForClause | LetClause | WhereClause | OrderbyClause | GroupClause | LimitClause | DistinctClause
genia.likes.science@gmail.com38612632013-05-28 13:11:52 -0700287//
genia.likes.science@gmail.com73dcc702013-05-28 04:21:28 -0700288// WhereClause ::= "where" Expression
289// OrderbyClause ::= "order" "by" Expression ( ( "asc" ) | ( "desc" ) )? ( "," Expression ( ( "asc" ) | ( "desc" ) )? )*
genia.likes.science@gmail.comb4cb6b32013-05-29 04:30:38 -0700290//
genia.likes.science@gmail.com73dcc702013-05-28 04:21:28 -0700291// GroupClause ::= "group" "by" ( Variable ":=" )? Expression ( "," ( Variable ":=" )? Expression )* ( "decor" Variable ":=" Expression ( "," "decor" Variable ":=" Expression )* )? "with" VariableRef ( "," VariableRef )*
292// LimitClause ::= "limit" Expression ( "offset" Expression )?
293// DistinctClause ::= "distinct" "by" Expression ( "," Expression )*
genia.likes.science@gmail.com73dcc702013-05-28 04:21:28 -0700294
295
genia.likes.science@gmail.com38612632013-05-28 13:11:52 -0700296// FLWOGRExpression
genia.likes.science@gmail.com90d08722013-05-28 04:40:12 -0700297//
298// FLWOGRExpression ::= ( ForClause | LetClause ) ( Clause )* "return" Expression
genia.likes.science@gmail.com38612632013-05-28 13:11:52 -0700299function FLWOGRExpression (options) {
300 // Initialize superclass
301 AExpression.call(this);
genia.likes.science@gmail.com90d08722013-05-28 04:40:12 -0700302
genia.likes.science@gmail.com38612632013-05-28 13:11:52 -0700303 this._properties["clauses"] = [];
genia.likes.science@gmail.com79e603a2013-05-31 10:03:23 -0700304 this._properties["minSize"] = 0;
genia.likes.science@gmail.com38612632013-05-28 13:11:52 -0700305
306 // Bind options and return
307 this.bind(options);
308 return this;
genia.likes.science@gmail.com90d08722013-05-28 04:40:12 -0700309}
310
311
genia.likes.science@gmail.com38612632013-05-28 13:11:52 -0700312FLWOGRExpression.prototype = Object.create(AExpression.prototype);
313FLWOGRExpression.prototype.constructor = FLWOGRExpression;
314
315
316FLWOGRExpression.prototype.bind = function(options) {
317 AExpression.prototype.bind.call(this, options);
318
319 var options = options || {};
320
genia.likes.science@gmail.com79e603a2013-05-31 10:03:23 -0700321 if (options instanceof SetStatement) {
322 this._properties["clauses"].push(options);
323 this._properties["minSize"] += 1;
324 }
325
326 if (this._properties["clauses"].length <= this._properties["minSize"]) {
genia.likes.science@gmail.com38612632013-05-28 13:11:52 -0700327 // Needs to start with for or let clause
328 if (options instanceof ForClause || options instanceof LetClause) {
329 this._properties["clauses"].push(options);
330 }
331 } else {
332 if (options instanceof AQLClause) {
333 this._properties["clauses"].push(options);
334 }
335 }
336
337 return this;
338};
339
340
341FLWOGRExpression.prototype.val = function() {
342 var value = AExpression.prototype.val.call(this);
343
genia.likes.science@gmail.com2ba32242013-05-31 03:10:48 -0700344 var clauseValues = [];
genia.likes.science@gmail.com38612632013-05-28 13:11:52 -0700345 for (var c in this._properties["clauses"]) {
genia.likes.science@gmail.com2ba32242013-05-31 03:10:48 -0700346 clauseValues.push(this._properties["clauses"][c].val());
genia.likes.science@gmail.com38612632013-05-28 13:11:52 -0700347 }
348
genia.likes.science@gmail.com79e603a2013-05-31 10:03:23 -0700349 return value + clauseValues.join("\n");// + ";";
genia.likes.science@gmail.com38612632013-05-28 13:11:52 -0700350};
351
genia.likes.science@gmail.com2ba32242013-05-31 03:10:48 -0700352
genia.likes.science@gmail.com73dcc702013-05-28 04:21:28 -0700353// AQLClause
354//
355// Base Clause ::= ForClause | LetClause | WhereClause | OrderbyClause | GroupClause | LimitClause | DistinctClause
356function AQLClause() {
357 this._properties = {};
358 this._properties["clause"] = "";
359}
360
361AQLClause.prototype.val = function() {
362 var value = this._properties["clause"];
363
364 if (this._properties.hasOwnProperty("return")) {
365 value += " return " + this._properties["return"].val();
366 }
367
368 return value;
369};
370
371AQLClause.prototype.bind = function(options) {
372 var options = options || {};
373
374 if (options.hasOwnProperty("return")) {
375 this._properties["return"] = options["return"];
376 }
377
378 return this;
379};
380
genia.likes.science@gmail.com39578302013-05-31 04:42:26 -0700381AQLClause.prototype.set = function(value) {
382 this._properties["clause"] = value;
383 return this;
384};
385
genia.likes.science@gmail.com73dcc702013-05-28 04:21:28 -0700386
387// ForClause
388//
389// Grammar:
390// "for" Variable ( "at" Variable )? "in" ( Expression )
391//
392// @param for_variable [String], REQUIRED, first variable in clause
393// @param at_variable [String], NOT REQUIRED, first variable in clause
394// @param expression [AsterixExpression], REQUIRED, expression to evaluate
395//
396// TODO Error Checking
397function ForClause(for_variable, at_variable, expression) {
398 AQLClause.call(this);
399
400 // at_variable is optional, check if defined
401 var at = typeof at_variable ? at_variable : null;
402
403 // Prepare clause
404 this._properties["clause"] = "for $" + for_variable;
405 if (at != null) {
406 this._properties["clause"] += " at $" + at_variable;
407 }
408 this._properties["clause"] += " in " + expression.val();
409 return this;
410}
411
412ForClause.prototype = Object.create(AQLClause.prototype);
413ForClause.prototype.constructor = ForClause;
genia.likes.science@gmail.com38612632013-05-28 13:11:52 -0700414
415
416// LetClause
417//
418// Grammar:
419// LetClause ::= "let" Variable ":=" Expression
420//
421// @param let_variable [String]
422// @param expression [AExpression]
423//
424// TODO Vigorous error checking
425function LetClause(let_variable, expression) {
426 AQLClause.call(this);
427
428 this._properties["clause"] = "let $" + let_variable + " := ";
429 this._properties["clause"] += expression.val();
430
431 return this;
432}
433
434LetClause.prototype = Object.create(AQLClause.prototype);
435LetClause.prototype.constructor = LetClause;
436
437
genia.likes.science@gmail.com5ca104c2013-05-29 05:39:26 -0700438// ReturnClause
439//
440// Grammar:
441// return [AQLExpression]
442function ReturnClause(expression) {
443 AQLClause.call(this);
444
445 this._properties["clause"] = "return ";
genia.likes.science@gmail.com79e603a2013-05-31 10:03:23 -0700446 if (expression instanceof AExpression || expression instanceof AQLClause) {
genia.likes.science@gmail.com5ca104c2013-05-29 05:39:26 -0700447 this._properties["clause"] += expression.val();
genia.likes.science@gmail.com2ba32242013-05-31 03:10:48 -0700448 } else if ( Object.getPrototypeOf( expression ) === Object.prototype ) {
449
450 this._properties["clause"] += "{";
451 var returnStatements = [];
452 for (returnValue in expression) {
453
454 if (expression[returnValue] instanceof AExpression) {
genia.likes.science@gmail.comfba7cc82013-05-31 04:04:08 -0700455 returnStatements.push('"' + returnValue + '" ' + " : " + expression[returnValue].val());
genia.likes.science@gmail.com2ba32242013-05-31 03:10:48 -0700456 } else if (typeof expression[returnValue] == "string") {
genia.likes.science@gmail.comfba7cc82013-05-31 04:04:08 -0700457 returnStatements.push('"' + returnValue + '" ' + " : " + expression[returnValue]);
genia.likes.science@gmail.com2ba32242013-05-31 03:10:48 -0700458 }
459 }
460 this._properties["clause"] += returnStatements.join(",\n");
461 this._properties["clause"] += "}";
462
genia.likes.science@gmail.com5ca104c2013-05-29 05:39:26 -0700463 } else {
464 this._properties["clause"] += new AsterixExpression().set([expression]).val();
465 }
466
467 return this;
468}
469
470ReturnClause.prototype = Object.create(AQLClause.prototype);
471ReturnClause.prototype.constructor = ReturnClause;
472
genia.likes.science@gmail.com2ba32242013-05-31 03:10:48 -0700473ReturnClause.prototype.val = function () {
474 return this._properties["clause"];
475};
476
477
genia.likes.science@gmail.com38612632013-05-28 13:11:52 -0700478// WhereClause
479//
480// Grammar:
481// ::= "where" Expression
482//
483// @param expression [BooleanExpression], pushes this expression onto the stack
genia.likes.science@gmail.com38612632013-05-28 13:11:52 -0700484function WhereClause(expression) {
485 AQLClause.call(this);
486
487 this._properties["stack"] = [];
488
489 this.bind(expression);
490
491 return this;
492}
493
494
495WhereClause.prototype = Object.create(AQLClause.prototype);
496WhereClause.prototype.constructor = WhereClause;
497
498
499WhereClause.prototype.bind = function(expression) {
genia.likes.science@gmail.com64ca88e2013-05-31 10:40:39 -0700500 if (expression instanceof AExpression) {
genia.likes.science@gmail.com38612632013-05-28 13:11:52 -0700501 this._properties["stack"].push(expression);
502 }
503};
504
505
506WhereClause.prototype.val = function() {
507 var value = "where ";
508
509 var count = this._properties["stack"].length - 1;
510 while (count >= 0) {
511 value += this._properties["stack"][count].val() + " ";
512 count -= 1;
513 }
514
515 return value;
genia.likes.science@gmail.com64ca88e2013-05-31 10:40:39 -0700516};
genia.likes.science@gmail.com38612632013-05-28 13:11:52 -0700517
518
genia.likes.science@gmail.com2ba32242013-05-31 03:10:48 -0700519// LimitClause
520// Grammar:
521// LimitClause ::= "limit" Expression ( "offset" Expression )?
522//
523// @param limitExpression [REQUIRED, AQLExpression]
524// @param offsetExpression [OPTIONAL, AQLExpression]
525function LimitClause(limitExpression, offsetExpression) {
526
527 AQLClause.call(this);
528
529 // limitExpression required
530 this._properties["clause"] = "limit " + limitExpression.val();
531
532 // Optional: Offset
533 var offset = typeof offsetExpression ? offsetExpression : null;
534 if (offset != null) {
535 this._properties["clause"] += " offset " + offsetExpression.val();
536 }
537
538 return this;
539}
540
541LimitClause.prototype = Object.create(AQLClause.prototype);
542LimitClause.prototype.constructor = LimitClause;
543
544
545// OrderbyClause
546//
547// Grammar:
548// OrderbyClause ::= "order" "by" Expression ( ( "asc" ) | ( "desc" ) )? ( "," Expression ( ( "asc" ) | ( "desc" ) )? )*
549//
550// @params AQLExpressions and asc/desc strings, in any quantity. At least one required.
551function OrderbyClause() {
552
553 AQLClause.call(this);
554
555 // At least one argument expression is required, and first should be expression
556 if (arguments.length == 0 || !(arguments[0] instanceof AExpression)) {
557 // TODO Not sure which error to throw for an empty OrderBy but this should fail.
558 alert("Order By Error");
559 this._properties["clause"] = null;
560 return this;
561 }
562
563 var expc = 0;
564 var expressions = [];
565
566 while (expc < arguments.length) {
567
568 var expression = "";
569
570 if (arguments[expc] instanceof AExpression) {
571 expression += arguments[expc].val();
572 }
573
574 var next = expc + 1;
575 if (next < arguments.length && (arguments[next] == "asc" || arguments[next] == "desc")) {
576 expc++;
577 expression += " " + arguments[expc];
578 }
579
580 expressions.push(expression);
581
582 expc++;
583 }
584
585 this._properties["clause"] = "order by " + expressions.join(", ");
586 return this;
587}
588
589OrderbyClause.prototype = Object.create(AQLClause.prototype);
590OrderbyClause.prototype.constructor = OrderbyClause;
591
592
genia.likes.science@gmail.com6e392912013-05-31 03:46:59 -0700593// GroupClause
594//
595// Grammar:
596// GroupClause ::= "group" "by" ( Variable ":=" )? Expression ( "," ( Variable ":=" )? Expression )* ( "decor" Variable ":=" Expression ( "," "decor" Variable ":=" Expression )* )? "with" VariableRef ( "," VariableRef )*
597function GroupClause() {
598 AQLClause.call(this);
599
600 if (arguments.length == 0) {
601 // TODO Not sure which error to throw for an empty GroupBy but this should fail.
602 alert("Group Error");
603 this._properties["clause"] = null;
604 return this;
605 }
606
607 var expc = 0;
608 var expressions = [];
609 var variableRefs = [];
610 var isDecor = false;
611
612 while (expc < arguments.length) {
613
614 if (arguments[expc] instanceof AExpression) {
615
616 isDecor = false;
617 expressions.push(arguments[expc].val());
618
619 } else if (typeof arguments[expc] == "string") {
620
621 // Special keywords, decor & with
622 if (arguments[expc] == "decor") {
623 isDecor = true;
624 } else if (arguments[expc] == "with") {
625 isDecor = false;
626 expc++;
627 while (expc < arguments.length) {
628 variableRefs.push("$" + arguments[expc]);
629 expc++;
630 }
631
632 // Variables and variable refs
633 } else {
634
635 var nextc = expc + 1;
636 var expression = "";
637
638 if (isDecor) {
639 expression += "decor ";
640 isDecor = false;
641 }
642
643 expression += "$" + arguments[expc] + " := " + arguments[nextc].val();
644 expressions.push(expression);
645 expc++;
646 }
647 }
648
649 expc++;
650 }
651
652 this._properties["clause"] = "group by " + expressions.join(", ") + " with " + variableRefs.join(", ");
653 return this;
654}
655
656GroupClause.prototype = Object.create(AQLClause.prototype);
657GroupClause.prototype.constructor = GroupClause;
658
genia.likes.science@gmail.com38612632013-05-28 13:11:52 -0700659// BooleanExpression
660//
661// TODO
662function BooleanExpression(expression) {
663 this.value = expression;
genia.likes.science@gmail.com6fd7b2e2013-05-31 00:40:28 -0700664 alert("Debugging Bool: " + arguments.length + " " + expression);
genia.likes.science@gmail.com38612632013-05-28 13:11:52 -0700665}
666
667BooleanExpression.prototype.val = function() {
668 return this.value;
669}
genia.likes.science@gmail.com79e603a2013-05-31 10:03:23 -0700670
671
672// SetStatement
673//
674// Grammar
675// "set" Identifier StringLiteral
676function SetStatement (identifier, stringLiteral) {
677 AExpression.call(this);
678
679 var statement = "set " + identifier + ' "' + stringLiteral + '";';
680
681 AExpression.prototype.set.call(this, statement);
682
683 return this;
684}
685
686SetStatement.prototype = Object.create(AExpression.prototype);
687SetStatement.prototype.constructor = SetStatement;
genia.likes.science@gmail.come34c57b2013-05-31 10:15:49 -0700688
689
690// Quantified Expression
691//
692// Grammar
693// QuantifiedExpression ::= ( ( "some" ) | ( "every" ) ) Variable "in" Expression ( "," Variable "in" Expression )* "satisfies" Expression
694//
695// @param String some/every
696// @param [AExpression]
697// @param [Aexpression] satisfiesExpression
698function QuantifiedExpression (keyword, expressions, satisfiesExpression) {
699 AExpression.call(this);
700
701 var expression = keyword + " ";
702 var varsInExpressions = [];
703
704 for (var varInExpression in expressions) {
705 varsInExpressions.push(varInExpression + " in " + expressions[varInExpression].val());
706 }
707 expression += varsInExpressions.join(", ") + " satisfies " + satisfiesExpression.val();
708
709 AExpression.prototype.set.call(this, expression);
710
711 return this;
712}
713
714QuantifiedExpression.prototype = Object.create(AExpression.prototype);
715QuantifiedExpression.prototype.constructor = QuantifiedExpression;
genia.likes.science@gmail.com64ca88e2013-05-31 10:40:39 -0700716
717QuantifiedExpression.prototype.val = function() {
718 var value = AExpression.prototype.val.call(this);
719 return "(" + value + ")";
720};