UNPKG

5.63 kBJavaScriptView Raw
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