1 | (function() {
|
2 | var self = this;
|
3 | var _;
|
4 | _ = require("underscore");
|
5 | module.exports = function(terms) {
|
6 | var self = this;
|
7 | var macros, isValidComprehension, comprehensionExpressionFor, comprehensionExpressionsFrom, generator, map, definition, filter, expressions, isDefinition;
|
8 | macros = terms.macroDirectory();
|
9 | isValidComprehension = function(term) {
|
10 | var firstItemIsNotHashEntry, secondItemIsWhereHashEntry, secondItemIsGenerator, theRestOfTheItemsAreNotHashEntries;
|
11 | if (term.items.length < 2) {
|
12 | return false;
|
13 | }
|
14 | firstItemIsNotHashEntry = function() {
|
15 | return !term.items[0].isHashEntry;
|
16 | };
|
17 | secondItemIsWhereHashEntry = function() {
|
18 | return term.items[1].isHashEntry && term.items[1].field.length === 1 && term.items[1].field[0] === "where";
|
19 | };
|
20 | secondItemIsGenerator = function() {
|
21 | return term.items[1].value.isGenerator;
|
22 | };
|
23 | theRestOfTheItemsAreNotHashEntries = function() {
|
24 | return !_.any(term.items.slice(2), function(item) {
|
25 | return item.isHashEntry;
|
26 | });
|
27 | };
|
28 | return firstItemIsNotHashEntry() && secondItemIsWhereHashEntry() && secondItemIsGenerator() && theRestOfTheItemsAreNotHashEntries();
|
29 | };
|
30 | comprehensionExpressionFor = function(expr) {
|
31 | if (expr.isGenerator) {
|
32 | return generator(expr);
|
33 | } else if (isDefinition(expr)) {
|
34 | return definition(expr);
|
35 | } else {
|
36 | return filter(expr);
|
37 | }
|
38 | };
|
39 | comprehensionExpressionsFrom = function(term, resultsVariable) {
|
40 | var exprs, comprehensionExprs;
|
41 | exprs = term.items.slice(2);
|
42 | exprs.unshift(term.items[1].value);
|
43 | comprehensionExprs = function() {
|
44 | var gen1_results, gen2_items, gen3_i, expr;
|
45 | gen1_results = [];
|
46 | gen2_items = exprs;
|
47 | for (gen3_i = 0; gen3_i < gen2_items.length; ++gen3_i) {
|
48 | expr = gen2_items[gen3_i];
|
49 | gen1_results.push(comprehensionExpressionFor(expr));
|
50 | }
|
51 | return gen1_results;
|
52 | }();
|
53 | comprehensionExprs.push(map(term.items[0], resultsVariable));
|
54 | return expressions(comprehensionExprs);
|
55 | };
|
56 | generator = function(expression) {
|
57 | return {
|
58 | isGenerator: true,
|
59 | iterator: expression.operatorArguments[0],
|
60 | collection: expression.operatorArguments[1],
|
61 | generate: function(rest) {
|
62 | var self = this;
|
63 | return [ terms.forEach(self.collection, self.iterator, terms.asyncStatements(rest.generate())) ];
|
64 | }
|
65 | };
|
66 | };
|
67 | map = function(expression, resultsVariable) {
|
68 | return {
|
69 | isMap: true,
|
70 | generate: function() {
|
71 | var self = this;
|
72 | return [ terms.methodCall(resultsVariable, [ "push" ], [ expression ]) ];
|
73 | }
|
74 | };
|
75 | };
|
76 | definition = function(expression) {
|
77 | return {
|
78 | isDefinition: true,
|
79 | generate: function(rest) {
|
80 | var self = this;
|
81 | var statements, gen4_o;
|
82 | statements = [ expression ];
|
83 | gen4_o = statements;
|
84 | gen4_o.push.apply(gen4_o, rest.generate());
|
85 | return statements;
|
86 | }
|
87 | };
|
88 | };
|
89 | filter = function(expression) {
|
90 | return {
|
91 | isFilter: true,
|
92 | generate: function(rest) {
|
93 | var self = this;
|
94 | return [ terms.ifExpression([ {
|
95 | condition: expression,
|
96 | body: terms.asyncStatements(rest.generate())
|
97 | } ]) ];
|
98 | }
|
99 | };
|
100 | };
|
101 | expressions = function(exprs) {
|
102 | return {
|
103 | expressions: exprs,
|
104 | generate: function() {
|
105 | var self = this;
|
106 | if (exprs.length > 0) {
|
107 | return exprs[0].generate(expressions(exprs.slice(1)));
|
108 | } else {
|
109 | return [];
|
110 | }
|
111 | }
|
112 | };
|
113 | };
|
114 | isDefinition = function(expression) {
|
115 | return expression.isDefinition;
|
116 | };
|
117 | macros.addMacro([ "where" ], function(term, name, args) {
|
118 | var badComprehension, resultsVariable, exprs, statements, gen5_o;
|
119 | badComprehension = function() {
|
120 | return terms.errors.addTermWithMessage(term, "not a list comprehension, try:\n\n [y + 1, where: x <- [1..10], x % 2, y = x + 10]");
|
121 | };
|
122 | if (isValidComprehension(term)) {
|
123 | resultsVariable = terms.generatedVariable([ "results" ]);
|
124 | exprs = comprehensionExpressionsFrom(term, resultsVariable);
|
125 | statements = [ terms.definition(resultsVariable, terms.list([])) ];
|
126 | gen5_o = statements;
|
127 | gen5_o.push.apply(gen5_o, exprs.generate());
|
128 | statements.push(resultsVariable);
|
129 | return terms.scope(statements);
|
130 | } else {
|
131 | return badComprehension();
|
132 | }
|
133 | });
|
134 | return macros;
|
135 | };
|
136 | }).call(this); |
\ | No newline at end of file |