UNPKG

pogo

Version:

A readable, DSL friendly programming language that compiles to JavaScript

136 lines 5.63 kB
(function() { var self = this; var _; _ = require("underscore"); module.exports = function(terms) { var self = this; var macros, isValidComprehension, comprehensionExpressionFor, comprehensionExpressionsFrom, generator, map, definition, filter, expressions, isDefinition; macros = terms.macroDirectory(); isValidComprehension = function(term) { var firstItemIsNotHashEntry, secondItemIsWhereHashEntry, secondItemIsGenerator, theRestOfTheItemsAreNotHashEntries; if (term.items.length < 2) { return false; } firstItemIsNotHashEntry = function() { return !term.items[0].isHashEntry; }; secondItemIsWhereHashEntry = function() { return term.items[1].isHashEntry && term.items[1].field.length === 1 && term.items[1].field[0] === "where"; }; secondItemIsGenerator = function() { return term.items[1].value.isGenerator; }; theRestOfTheItemsAreNotHashEntries = function() { return !_.any(term.items.slice(2), function(item) { return item.isHashEntry; }); }; return firstItemIsNotHashEntry() && secondItemIsWhereHashEntry() && secondItemIsGenerator() && theRestOfTheItemsAreNotHashEntries(); }; comprehensionExpressionFor = function(expr) { if (expr.isGenerator) { return generator(expr); } else if (isDefinition(expr)) { return definition(expr); } else { return filter(expr); } }; comprehensionExpressionsFrom = function(term, resultsVariable) { var exprs, comprehensionExprs; exprs = term.items.slice(2); exprs.unshift(term.items[1].value); comprehensionExprs = function() { var gen1_results, gen2_items, gen3_i, expr; gen1_results = []; gen2_items = exprs; for (gen3_i = 0; gen3_i < gen2_items.length; ++gen3_i) { expr = gen2_items[gen3_i]; gen1_results.push(comprehensionExpressionFor(expr)); } return gen1_results; }(); comprehensionExprs.push(map(term.items[0], resultsVariable)); return expressions(comprehensionExprs); }; generator = function(expression) { return { isGenerator: true, iterator: expression.operatorArguments[0], collection: expression.operatorArguments[1], generate: function(rest) { var self = this; return [ terms.forEach(self.collection, self.iterator, terms.asyncStatements(rest.generate())) ]; } }; }; map = function(expression, resultsVariable) { return { isMap: true, generate: function() { var self = this; return [ terms.methodCall(resultsVariable, [ "push" ], [ expression ]) ]; } }; }; definition = function(expression) { return { isDefinition: true, generate: function(rest) { var self = this; var statements, gen4_o; statements = [ expression ]; gen4_o = statements; gen4_o.push.apply(gen4_o, rest.generate()); return statements; } }; }; filter = function(expression) { return { isFilter: true, generate: function(rest) { var self = this; return [ terms.ifExpression([ { condition: expression, body: terms.asyncStatements(rest.generate()) } ]) ]; } }; }; expressions = function(exprs) { return { expressions: exprs, generate: function() { var self = this; if (exprs.length > 0) { return exprs[0].generate(expressions(exprs.slice(1))); } else { return []; } } }; }; isDefinition = function(expression) { return expression.isDefinition; }; macros.addMacro([ "where" ], function(term, name, args) { var badComprehension, resultsVariable, exprs, statements, gen5_o; badComprehension = function() { return terms.errors.addTermWithMessage(term, "not a list comprehension, try:\n\n [y + 1, where: x <- [1..10], x % 2, y = x + 10]"); }; if (isValidComprehension(term)) { resultsVariable = terms.generatedVariable([ "results" ]); exprs = comprehensionExpressionsFrom(term, resultsVariable); statements = [ terms.definition(resultsVariable, terms.list([])) ]; gen5_o = statements; gen5_o.push.apply(gen5_o, exprs.generate()); statements.push(resultsVariable); return terms.scope(statements); } else { return badComprehension(); } }); return macros; }; }).call(this);