UNPKG

pogo

Version:

A readable, DSL friendly programming language that compiles to JavaScript

161 lines (130 loc) 4.52 kB
var _ = require('underscore'); module.exports = function (terminals) { var cg = this; return cg.oldTerm(function () { this.terminals = terminals; this.subterms('terminals'); this.hasName = function () { return this.name().length > 0; }; this.isCall = function () { if (this.hasName()) { return this.hasArguments(); } else { return this.argumentTerminals().length > 1; } }; this.name = function () { return this._name || (this._name = _(this.terminals).filter(function (terminal) { return terminal.identifier; }).map(function (identifier) { return identifier.identifier; })); }; this.hasAsyncArgument = function () { return this._hasAsyncArgument || (this._hasAsyncArgument = _.any(this.terminals, function (t) { return t.isAsyncArgument; }) ); }; this.hasFutureArgument = function () { return this._hasFutureArgument || (this._hasFutureArgument = _.any(this.terminals, function (t) { return t.isFutureArgument; }) ); }; this.hasCallbackArgument = function () { return this._hasCallbackArgument || (this._hasCallbackArgument = _.any(this.terminals, function (t) { return t.isCallback; }) ); }; this.hasArguments = function () { return this._hasArguments || (this._hasArguments = this.argumentTerminals().length > 0 ); }; this.argumentTerminals = function() { if (this._argumentTerminals) { return this._argumentTerminals; } else { this._buildBlocks(); return this._argumentTerminals = _.compact(_.map(this.terminals, function (terminal) { return terminal.arguments(); })); } }; this.arguments = function() { return this._arguments || (this._arguments = _.flatten(this.argumentTerminals())); }; this.parameters = function (options) { var skipFirstParameter = options && options.skipFirstParameter; if (this._parameters) { return this._parameters; } var args = this.arguments() if (skipFirstParameter) { args = args.slice(1); } return this._parameters = _(args).map(function (arg) { return arg.parameter(); }); }; this.hasParameters = function () { return this._hasParameters || (this._hasParameters = this.argumentTerminals().length > 0 ); }; this._buildBlocks = function () { var parameters = []; var hasParameters = false; _(this.terminals).each(function (terminal) { if (terminal.isParameters) { parameters.push.apply(parameters, terminal.parameters); hasParameters = true; } else if (terminal.isBlock) { terminal.setParameters(parameters); terminal.notScope = hasParameters; parameters = []; hasParameters = false; } }); _(parameters).each(function (parm) { cg.errors.addTermWithMessage(parm, 'block parameter with no block'); }); }; this.hashEntry = function (options) { var withoutBlock = options && options.withoutBlock; var args = this.arguments(); var name = this.name(); if (withoutBlock && args.length > 0 && args[args.length - 1].isBlock) { args = args.slice(0, args.length - 1); } if (name.length > 0 && args.length === 1) { return cg.hashEntry(name, args[0]); } if (name.length > 0 && args.length === 0) { return cg.hashEntry(name); } if (name.length === 0 && args.length === 2 && args[0].isString) { return cg.hashEntry(args[0], args[1]) } return cg.errors.addTermWithMessage(this, 'cannot be a hash entry'); }; this.hashEntryBlock = function () { var args = this.arguments(); var lastArgument = args[args.length - 1]; if (lastArgument && lastArgument.isBlock) { return lastArgument; } }; this.hashKey = function () { var args = this.arguments(); if (args.length === 1 && args[0].isString) { return args[0]; } else if (!this.hasParameters() && !this.hasArguments() && this.hasName()) { return this.name(); } else { return cg.errors.addTermWithMessage(this, 'cannot be a hash key'); } } }); };