From 30a18fdaebd7feb35db6a1d76272b109f3fb30d2 Mon Sep 17 00:00:00 2001 From: Jeremy Ashkenas Date: Wed, 6 Oct 2010 22:44:32 -0400 Subject: [PATCH] Removed the silly 'Node' suffix from everything. --- lib/grammar.js | 242 ++++++------ lib/nodes.js | 952 ++++++++++++++++++++++----------------------- lib/parser.js | 240 ++++++------ src/grammar.coffee | 246 ++++++------ src/helpers.coffee | 2 +- src/nodes.coffee | 416 ++++++++++---------- 6 files changed, 1049 insertions(+), 1049 deletions(-) diff --git a/lib/grammar.js b/lib/grammar.js index 9455ab95..3433ec39 100644 --- a/lib/grammar.js +++ b/lib/grammar.js @@ -9,7 +9,7 @@ return [patternString, '$$ = $1;', options]; } action = (match = (action + '').match(unwrap)) ? match[1] : ("(" + action + "())"); - action = action.replace(/\b(?:[A-Z][a-z]+Node|Expressions)\b/g, 'yy.$&'); + action = action.replace(/\bnew (\w+)\b/g, 'new yy.$1').replace(/Expressions\.wrap/g, 'yy.Expressions.wrap'); return [patternString, ("$$ = " + action + ";"), options]; }; grammar = { @@ -30,11 +30,11 @@ Line: [o("Expression"), o("Statement")], Statement: [ o("Return"), o("Throw"), o("BREAK", function() { - return new LiteralNode($1); + return new Literal($1); }), o("CONTINUE", function() { - return new LiteralNode($1); + return new Literal($1); }), o("DEBUGGER", function() { - return new LiteralNode($1); + return new Literal($1); }) ], Expression: [o("Value"), o("Invocation"), o("Code"), o("Operation"), o("Assign"), o("If"), o("Try"), o("While"), o("For"), o("Switch"), o("Extends"), o("Class"), o("Existence"), o("Comment")], @@ -49,77 +49,77 @@ ], Identifier: [ o("IDENTIFIER", function() { - return new LiteralNode($1); + return new Literal($1); }) ], AlphaNumeric: [ o("NUMBER", function() { - return new LiteralNode($1); + return new Literal($1); }), o("STRING", function() { - return new LiteralNode($1); + return new Literal($1); }) ], Literal: [ o("AlphaNumeric"), o("JS", function() { - return new LiteralNode($1); + return new Literal($1); }), o("REGEX", function() { - return new LiteralNode($1); + return new Literal($1); }), o("TRUE", function() { - return new LiteralNode(true); + return new Literal(true); }), o("FALSE", function() { - return new LiteralNode(false); + return new Literal(false); }), o("YES", function() { - return new LiteralNode(true); + return new Literal(true); }), o("NO", function() { - return new LiteralNode(false); + return new Literal(false); }), o("ON", function() { - return new LiteralNode(true); + return new Literal(true); }), o("OFF", function() { - return new LiteralNode(false); + return new Literal(false); }) ], Assign: [ o("Assignable = Expression", function() { - return new AssignNode($1, $3); + return new Assign($1, $3); }), o("Assignable = INDENT Expression OUTDENT", function() { - return new AssignNode($1, $4); + return new Assign($1, $4); }) ], AssignObj: [ o("Identifier", function() { - return new ValueNode($1); + return new Value($1); }), o("AlphaNumeric"), o("ThisProperty"), o("Identifier : Expression", function() { - return new AssignNode(new ValueNode($1), $3, 'object'); + return new Assign(new Value($1), $3, 'object'); }), o("AlphaNumeric : Expression", function() { - return new AssignNode(new ValueNode($1), $3, 'object'); + return new Assign(new Value($1), $3, 'object'); }), o("Identifier : INDENT Expression OUTDENT", function() { - return new AssignNode(new ValueNode($1), $4, 'object'); + return new Assign(new Value($1), $4, 'object'); }), o("AlphaNumeric : INDENT Expression OUTDENT", function() { - return new AssignNode(new ValueNode($1), $4, 'object'); + return new Assign(new Value($1), $4, 'object'); }), o("Comment") ], Return: [ o("RETURN Expression", function() { - return new ReturnNode($2); + return new Return($2); }), o("RETURN", function() { - return new ReturnNode; + return new Return; }) ], Comment: [ o("HERECOMMENT", function() { - return new CommentNode($1); + return new Comment($1); }) ], Existence: [ o("Expression ?", function() { - return new ExistenceNode($1); + return new Existence($1); }) ], Code: [ o("PARAM_START ParamList PARAM_END FuncGlyph Block", function() { - return new CodeNode($2, $5, $4); + return new Code($2, $5, $4); }), o("FuncGlyph Block", function() { - return new CodeNode([], $2, $1); + return new Code([], $2, $1); }) ], FuncGlyph: [ @@ -141,63 +141,63 @@ ], Param: [ o("PARAM", function() { - return new LiteralNode($1); + return new Literal($1); }), o("@ PARAM", function() { - return new ParamNode($2, true); + return new Param($2, true); }), o("PARAM . . .", function() { - return new ParamNode($1, false, true); + return new Param($1, false, true); }), o("@ PARAM . . .", function() { - return new ParamNode($2, true, true); + return new Param($2, true, true); }) ], Splat: [ o("Expression . . .", function() { - return new SplatNode($1); + return new Splat($1); }) ], SimpleAssignable: [ o("Identifier", function() { - return new ValueNode($1); + return new Value($1); }), o("Value Accessor", function() { return $1.push($2); }), o("Invocation Accessor", function() { - return new ValueNode($1, [$2]); + return new Value($1, [$2]); }), o("ThisProperty") ], Assignable: [ o("SimpleAssignable"), o("Array", function() { - return new ValueNode($1); + return new Value($1); }), o("Object", function() { - return new ValueNode($1); + return new Value($1); }) ], Value: [ o("Assignable"), o("Literal", function() { - return new ValueNode($1); + return new Value($1); }), o("Parenthetical", function() { - return new ValueNode($1); + return new Value($1); }), o("Range", function() { - return new ValueNode($1); + return new Value($1); }), o("This"), o("NULL", function() { - return new ValueNode(new LiteralNode('null')); + return new Value(new Literal('null')); }) ], Accessor: [ o("PROPERTY_ACCESS Identifier", function() { - return new AccessorNode($2); + return new Accessor($2); }), o("PROTOTYPE_ACCESS Identifier", function() { - return new AccessorNode($2, 'prototype'); + return new Accessor($2, 'prototype'); }), o("::", function() { - return new AccessorNode(new LiteralNode('prototype')); + return new Accessor(new Literal('prototype')); }), o("SOAK_ACCESS Identifier", function() { - return new AccessorNode($2, 'soak'); + return new Accessor($2, 'soak'); }), o("Index"), o("Slice", function() { - return new SliceNode($1); + return new Slice($1); }) ], Index: [ o("INDEX_START Expression INDEX_END", function() { - return new IndexNode($2); + return new Index($2); }), o("INDEX_SOAK Index", function() { $2.soakNode = true; return $2; @@ -208,7 +208,7 @@ ], Object: [ o("{ AssignList OptComma }", function() { - return new ObjectNode($2); + return new ObjectLiteral($2); }) ], AssignList: [ @@ -226,30 +226,30 @@ ], Class: [ o("CLASS SimpleAssignable", function() { - return new ClassNode($2); + return new Class($2); }), o("CLASS SimpleAssignable EXTENDS Value", function() { - return new ClassNode($2, $4); + return new Class($2, $4); }), o("CLASS SimpleAssignable INDENT ClassBody OUTDENT", function() { - return new ClassNode($2, null, $4); + return new Class($2, null, $4); }), o("CLASS SimpleAssignable EXTENDS Value INDENT ClassBody OUTDENT", function() { - return new ClassNode($2, $4, $6); + return new Class($2, $4, $6); }), o("CLASS INDENT ClassBody OUTDENT", function() { - return new ClassNode('__temp__', null, $3); + return new Class('__temp__', null, $3); }), o("CLASS", function() { - return new ClassNode('__temp__', null, new Expressions); + return new Class('__temp__', null, new Expressions); }), o("CLASS EXTENDS Value", function() { - return new ClassNode('__temp__', $3, new Expressions); + return new Class('__temp__', $3, new Expressions); }), o("CLASS EXTENDS Value INDENT ClassBody OUTDENT", function() { - return new ClassNode('__temp__', $3, $5); + return new Class('__temp__', $3, $5); }) ], ClassAssign: [ o("AssignObj", function() { return $1; }), o("ThisProperty : Expression", function() { - return new AssignNode(new ValueNode($1), $3, 'this'); + return new Assign(new Value($1), $3, 'this'); }), o("ThisProperty : INDENT Expression OUTDENT", function() { - return new AssignNode(new ValueNode($1), $4, 'this'); + return new Assign(new Value($1), $4, 'this'); }) ], ClassBody: [ @@ -265,18 +265,18 @@ ], Extends: [ o("SimpleAssignable EXTENDS Value", function() { - return new ExtendsNode($1, $3); + return new Extends($1, $3); }) ], Invocation: [ o("Value OptFuncExist Arguments", function() { - return new CallNode($1, $3, $2); + return new Call($1, $3, $2); }), o("Invocation OptFuncExist Arguments", function() { - return new CallNode($1, $3, $2); + return new Call($1, $3, $2); }), o("SUPER", function() { - return new CallNode('super', [new SplatNode(new LiteralNode('arguments'))]); + return new Call('super', [new Splat(new Literal('arguments'))]); }), o("SUPER Arguments", function() { - return new CallNode('super', $2); + return new Call('super', $2); }) ], OptFuncExist: [ @@ -295,9 +295,9 @@ ], This: [ o("THIS", function() { - return new ValueNode(new LiteralNode('this')); + return new Value(new Literal('this')); }), o("@", function() { - return new ValueNode(new LiteralNode('this')); + return new Value(new Literal('this')); }) ], RangeDots: [ @@ -309,28 +309,28 @@ ], ThisProperty: [ o("@ Identifier", function() { - return new ValueNode(new LiteralNode('this'), [new AccessorNode($2)], 'this'); + return new Value(new Literal('this'), [new Accessor($2)], 'this'); }) ], Range: [ o("[ Expression RangeDots Expression ]", function() { - return new RangeNode($2, $4, $3); + return new Range($2, $4, $3); }) ], Slice: [ o("INDEX_START Expression RangeDots Expression INDEX_END", function() { - return new RangeNode($2, $4, $3); + return new Range($2, $4, $3); }), o("INDEX_START Expression RangeDots INDEX_END", function() { - return new RangeNode($2, null, $3); + return new Range($2, null, $3); }), o("INDEX_START RangeDots Expression INDEX_END", function() { - return new RangeNode(null, $3, $2); + return new Range(null, $3, $2); }) ], Array: [ o("[ ]", function() { - return new ArrayNode([]); + return new ArrayLiteral([]); }), o("[ ArgList OptComma ]", function() { - return new ArrayNode($2); + return new ArrayLiteral($2); }) ], ArgList: [ @@ -354,13 +354,13 @@ ], Try: [ o("TRY Block", function() { - return new TryNode($2); + return new Try($2); }), o("TRY Block Catch", function() { - return new TryNode($2, $3[0], $3[1]); + return new Try($2, $3[0], $3[1]); }), o("TRY Block FINALLY Block", function() { - return new TryNode($2, null, null, $4); + return new Try($2, null, null, $4); }), o("TRY Block Catch FINALLY Block", function() { - return new TryNode($2, $3[0], $3[1], $5); + return new Try($2, $3[0], $3[1], $5); }) ], Catch: [ @@ -370,29 +370,29 @@ ], Throw: [ o("THROW Expression", function() { - return new ThrowNode($2); + return new Throw($2); }) ], Parenthetical: [ o("( Line )", function() { - return new ParentheticalNode($2); + return new Parenthetical($2); }), o("( )", function() { - return new ParentheticalNode(new LiteralNode('')); + return new Parenthetical(new Literal('')); }) ], WhileSource: [ o("WHILE Expression", function() { - return new WhileNode($2); + return new While($2); }), o("WHILE Expression WHEN Expression", function() { - return new WhileNode($2, { + return new While($2, { guard: $4 }); }), o("UNTIL Expression", function() { - return new WhileNode($2, { + return new While($2, { invert: true }); }), o("UNTIL Expression WHEN Expression", function() { - return new WhileNode($2, { + return new While($2, { invert: true, guard: $4 }); @@ -411,24 +411,24 @@ ], Loop: [ o("LOOP Block", function() { - return new WhileNode(new LiteralNode('true')).addBody($2); + return new While(new Literal('true')).addBody($2); }), o("LOOP Expression", function() { - return new WhileNode(new LiteralNode('true')).addBody(Expressions.wrap([$2])); + return new While(new Literal('true')).addBody(Expressions.wrap([$2])); }) ], For: [ o("Statement ForBody", function() { - return new ForNode($1, $2, $2.vars[0], $2.vars[1]); + return new For($1, $2, $2.vars[0], $2.vars[1]); }), o("Expression ForBody", function() { - return new ForNode($1, $2, $2.vars[0], $2.vars[1]); + return new For($1, $2, $2.vars[0], $2.vars[1]); }), o("ForBody Block", function() { - return new ForNode($2, $1, $1.vars[0], $1.vars[1]); + return new For($2, $1, $1.vars[0], $1.vars[1]); }) ], ForBody: [ o("FOR Range", function() { return { - source: new ValueNode($2), + source: new Value($2), vars: [] }; }), o("ForStart ForSource", function() { @@ -447,9 +447,9 @@ ], ForValue: [ o("Identifier"), o("Array", function() { - return new ValueNode($1); + return new Value($1); }), o("Object", function() { - return new ValueNode($1); + return new Value($1); }) ], ForVariables: [ @@ -501,13 +501,13 @@ ], Switch: [ o("SWITCH Expression INDENT Whens OUTDENT", function() { - return new SwitchNode($2, $4); + return new Switch($2, $4); }), o("SWITCH Expression INDENT Whens ELSE Block OUTDENT", function() { - return new SwitchNode($2, $4, $6); + return new Switch($2, $4, $6); }), o("SWITCH INDENT Whens OUTDENT", function() { - return new SwitchNode(null, $3); + return new Switch(null, $3); }), o("SWITCH INDENT Whens ELSE Block OUTDENT", function() { - return new SwitchNode(null, $3, $5); + return new Switch(null, $3, $5); }) ], Whens: [ @@ -524,33 +524,33 @@ ], IfBlock: [ o("IF Expression Block", function() { - return new IfNode($2, $3); + return new If($2, $3); }), o("UNLESS Expression Block", function() { - return new IfNode($2, $3, { + return new If($2, $3, { invert: true }); }), o("IfBlock ELSE IF Expression Block", function() { - return $1.addElse(new IfNode($4, $5)); + return $1.addElse(new If($4, $5)); }), o("IfBlock ELSE Block", function() { return $1.addElse($3); }) ], If: [ o("IfBlock"), o("Statement POST_IF Expression", function() { - return new IfNode($3, Expressions.wrap([$1]), { + return new If($3, Expressions.wrap([$1]), { statement: true }); }), o("Expression POST_IF Expression", function() { - return new IfNode($3, Expressions.wrap([$1]), { + return new If($3, Expressions.wrap([$1]), { statement: true }); }), o("Statement POST_UNLESS Expression", function() { - return new IfNode($3, Expressions.wrap([$1]), { + return new If($3, Expressions.wrap([$1]), { statement: true, invert: true }); }), o("Expression POST_UNLESS Expression", function() { - return new IfNode($3, Expressions.wrap([$1]), { + return new If($3, Expressions.wrap([$1]), { statement: true, invert: true }); @@ -558,47 +558,47 @@ ], Operation: [ o("UNARY Expression", function() { - return new OpNode($1, $2); + return new Op($1, $2); }), o("- Expression", function() { - return new OpNode('-', $2); + return new Op('-', $2); }, { prec: 'UNARY' }), o("+ Expression", function() { - return new OpNode('+', $2); + return new Op('+', $2); }, { prec: 'UNARY' }), o("-- Expression", function() { - return new OpNode('--', $2); + return new Op('--', $2); }), o("++ Expression", function() { - return new OpNode('++', $2); + return new Op('++', $2); }), o("Expression --", function() { - return new OpNode('--', $1, null, true); + return new Op('--', $1, null, true); }), o("Expression ++", function() { - return new OpNode('++', $1, null, true); + return new Op('++', $1, null, true); }), o("Expression ? Expression", function() { - return new OpNode('?', $1, $3); + return new Op('?', $1, $3); }), o("Expression + Expression", function() { - return new OpNode('+', $1, $3); + return new Op('+', $1, $3); }), o("Expression - Expression", function() { - return new OpNode('-', $1, $3); + return new Op('-', $1, $3); }), o("Expression == Expression", function() { - return new OpNode('==', $1, $3); + return new Op('==', $1, $3); }), o("Expression != Expression", function() { - return new OpNode('!=', $1, $3); + return new Op('!=', $1, $3); }), o("Expression MATH Expression", function() { - return new OpNode($2, $1, $3); + return new Op($2, $1, $3); }), o("Expression SHIFT Expression", function() { - return new OpNode($2, $1, $3); + return new Op($2, $1, $3); }), o("Expression COMPARE Expression", function() { - return new OpNode($2, $1, $3); + return new Op($2, $1, $3); }), o("Expression LOGIC Expression", function() { - return new OpNode($2, $1, $3); + return new Op($2, $1, $3); }), o("Value COMPOUND_ASSIGN Expression", function() { - return new OpNode($2, $1, $3); + return new Op($2, $1, $3); }), o("Value COMPOUND_ASSIGN INDENT Expression OUTDENT", function() { - return new OpNode($2, $1, $4); + return new Op($2, $1, $4); }), o("Expression RELATION Expression", function() { - return $2.charAt(0) === '!' ? ($2 === '!in' ? new OpNode('!', new InNode($1, $3)) : new OpNode('!', new ParentheticalNode(new OpNode($2.slice(1), $1, $3)))) : ($2 === 'in' ? new InNode($1, $3) : new OpNode($2, $1, $3)); + return $2.charAt(0) === '!' ? ($2 === '!in' ? new Op('!', new In($1, $3)) : new Op('!', new Parenthetical(new Op($2.slice(1), $1, $3)))) : ($2 === 'in' ? new In($1, $3) : new Op($2, $1, $3)); }) ] }; diff --git a/lib/nodes.js b/lib/nodes.js index 6e3184d9..92e03c07 100644 --- a/lib/nodes.js +++ b/lib/nodes.js @@ -1,5 +1,5 @@ (function() { - var AccessorNode, ArrayNode, AssignNode, BaseNode, CallNode, ClassNode, ClosureNode, CodeNode, CommentNode, ExistenceNode, Expressions, ExtendsNode, ForNode, IDENTIFIER, IS_STRING, IfNode, InNode, IndexNode, LiteralNode, NO, NUMBER, ObjectNode, OpNode, ParamNode, ParentheticalNode, PushNode, RangeNode, ReturnNode, SIMPLENUM, Scope, SliceNode, SplatNode, SwitchNode, TAB, THIS, TRAILING_WHITESPACE, ThrowNode, TryNode, UTILITIES, ValueNode, WhileNode, YES, _ref, compact, del, ends, flatten, include, indexOf, last, literal, merge, starts, utility; + var Accessor, ArrayLiteral, Assign, Base, Call, Class, Closure, Code, Comment, Existence, Expressions, Extends, For, IDENTIFIER, IS_STRING, If, In, Index, Literal, NO, NUMBER, ObjectLiteral, Op, Param, Parenthetical, Push, Range, Return, SIMPLENUM, Scope, Slice, Splat, Switch, TAB, THIS, TRAILING_WHITESPACE, Throw, Try, UTILITIES, Value, While, YES, _ref, compact, del, ends, flatten, include, indexOf, last, literal, merge, starts, utility; var __extends = function(child, parent) { var ctor = function() {}; ctor.prototype = parent.prototype; @@ -19,35 +19,35 @@ THIS = function() { return this; }; - exports.BaseNode = (function() { - BaseNode = (function() { - return function BaseNode() { + exports.Base = (function() { + Base = (function() { + return function Base() { this.tags = {}; return this; }; })(); - BaseNode.prototype.compile = function(o) { + Base.prototype.compile = function(o) { var closure, code, top; this.options = o ? merge(o) : {}; this.tab = o.indent; top = this.topSensitive() ? this.options.top : del(this.options, 'top'); - closure = this.isStatement(o) && !this.isPureStatement() && !top && !this.options.asStatement && !(this instanceof CommentNode) && !this.containsPureStatement(); + closure = this.isStatement(o) && !this.isPureStatement() && !top && !this.options.asStatement && !(this instanceof Comment) && !this.containsPureStatement(); code = closure ? this.compileClosure(this.options) : this.compileNode(this.options); return code; }; - BaseNode.prototype.compileClosure = function(o) { + Base.prototype.compileClosure = function(o) { this.tab = o.indent; o.sharedScope = o.scope; - return ClosureNode.wrap(this).compile(o); + return Closure.wrap(this).compile(o); }; - BaseNode.prototype.compileReference = function(o, options) { + Base.prototype.compileReference = function(o, options) { var _len, compiled, i, node, pair, reference; pair = (function() { if (!(this.isComplex())) { return [this, this]; } else { reference = literal(o.scope.freeVariable('ref')); - compiled = new AssignNode(reference, this); + compiled = new Assign(reference, this); return [compiled, reference]; } }).call(this); @@ -59,7 +59,7 @@ } return pair; }; - BaseNode.prototype.idt = function(tabs) { + Base.prototype.idt = function(tabs) { var idt, num; idt = this.tab || ''; num = (tabs || 0) + 1; @@ -68,10 +68,10 @@ } return idt; }; - BaseNode.prototype.makeReturn = function() { - return new ReturnNode(this); + Base.prototype.makeReturn = function() { + return new Return(this); }; - BaseNode.prototype.contains = function(block) { + Base.prototype.contains = function(block) { var contains; contains = false; this.traverseChildren(false, function(node) { @@ -82,20 +82,20 @@ }); return contains; }; - BaseNode.prototype.containsType = function(type) { + Base.prototype.containsType = function(type) { return this instanceof type || this.contains(function(node) { return node instanceof type; }); }; - BaseNode.prototype.containsPureStatement = function() { + Base.prototype.containsPureStatement = function() { return this.isPureStatement() || this.contains(function(node) { return node.isPureStatement(); }); }; - BaseNode.prototype.traverse = function(block) { + Base.prototype.traverse = function(block) { return this.traverseChildren(true, block); }; - BaseNode.prototype.toString = function(idt, override) { + Base.prototype.toString = function(idt, override) { var _i, _len, _ref2, _result, child, children, klass; idt || (idt = ''); children = (function() { @@ -109,7 +109,7 @@ klass = override || this.constructor.name + (this.soakNode || this.exist ? '?' : ''); return '\n' + idt + klass + children; }; - BaseNode.prototype.eachChild = function(func) { + Base.prototype.eachChild = function(func) { var _i, _j, _len, _len2, _ref2, _ref3, _result, attr, child; if (!(this.children)) { return; @@ -129,7 +129,7 @@ } return _result; }; - BaseNode.prototype.collectChildren = function() { + Base.prototype.collectChildren = function() { var nodes; nodes = []; this.eachChild(function(node) { @@ -137,21 +137,21 @@ }); return nodes; }; - BaseNode.prototype.traverseChildren = function(crossScope, func) { + Base.prototype.traverseChildren = function(crossScope, func) { return this.eachChild(function(child) { if (func(child) === false) { return false; } - return child instanceof BaseNode && (crossScope || !(child instanceof CodeNode)) ? child.traverseChildren(crossScope, func) : undefined; + return child instanceof Base && (crossScope || !(child instanceof Code)) ? child.traverseChildren(crossScope, func) : undefined; }); }; - BaseNode.prototype.children = []; - BaseNode.prototype.unwrap = THIS; - BaseNode.prototype.isStatement = NO; - BaseNode.prototype.isPureStatement = NO; - BaseNode.prototype.isComplex = YES; - BaseNode.prototype.topSensitive = NO; - return BaseNode; + Base.prototype.children = []; + Base.prototype.unwrap = THIS; + Base.prototype.isStatement = NO; + Base.prototype.isPureStatement = NO; + Base.prototype.isComplex = YES; + Base.prototype.topSensitive = NO; + return Base; })(); exports.Expressions = (function() { Expressions = (function() { @@ -161,7 +161,7 @@ return this; }; })(); - __extends(Expressions, BaseNode); + __extends(Expressions, Base); Expressions.prototype.children = ['expressions']; Expressions.prototype.isStatement = YES; Expressions.prototype.push = function(node) { @@ -181,10 +181,10 @@ Expressions.prototype.makeReturn = function() { var end, idx; end = this.expressions[(idx = this.expressions.length - 1)]; - if (end instanceof CommentNode) { + if (end instanceof Comment) { end = this.expressions[idx -= 1]; } - if (end && !(end instanceof ReturnNode)) { + if (end && !(end instanceof Return)) { this.expressions[idx] = end.makeReturn(); } return this; @@ -239,61 +239,61 @@ } return new Expressions(nodes); }; - exports.LiteralNode = (function() { - LiteralNode = (function() { - return function LiteralNode(_arg) { + exports.Literal = (function() { + Literal = (function() { + return function Literal(_arg) { this.value = _arg; - LiteralNode.__super__.constructor.call(this); + Literal.__super__.constructor.call(this); return this; }; })(); - __extends(LiteralNode, BaseNode); - LiteralNode.prototype.makeReturn = function() { - return this.isStatement() ? this : LiteralNode.__super__.makeReturn.call(this); + __extends(Literal, Base); + Literal.prototype.makeReturn = function() { + return this.isStatement() ? this : Literal.__super__.makeReturn.call(this); }; - LiteralNode.prototype.isStatement = function() { + Literal.prototype.isStatement = function() { var _ref2; return ('break' === (_ref2 = this.value) || 'continue' === _ref2 || 'debugger' === _ref2); }; - LiteralNode.prototype.isPureStatement = LiteralNode.prototype.isStatement; - LiteralNode.prototype.isComplex = NO; - LiteralNode.prototype.isReserved = function() { + Literal.prototype.isPureStatement = Literal.prototype.isStatement; + Literal.prototype.isComplex = NO; + Literal.prototype.isReserved = function() { return !!this.value.reserved; }; - LiteralNode.prototype.compileNode = function(o) { + Literal.prototype.compileNode = function(o) { var end, idt, val; idt = this.isStatement(o) ? this.idt() : ''; end = this.isStatement(o) ? ';' : ''; val = this.isReserved() ? ("\"" + (this.value) + "\"") : this.value; return idt + val + end; }; - LiteralNode.prototype.toString = function() { + Literal.prototype.toString = function() { return ' "' + this.value + '"'; }; - return LiteralNode; + return Literal; })(); - exports.ReturnNode = (function() { - ReturnNode = (function() { - return function ReturnNode(_arg) { + exports.Return = (function() { + Return = (function() { + return function Return(_arg) { this.expression = _arg; - ReturnNode.__super__.constructor.call(this); + Return.__super__.constructor.call(this); return this; }; })(); - __extends(ReturnNode, BaseNode); - ReturnNode.prototype.isStatement = YES; - ReturnNode.prototype.isPureStatement = YES; - ReturnNode.prototype.children = ['expression']; - ReturnNode.prototype.makeReturn = THIS; - ReturnNode.prototype.compile = function(o) { + __extends(Return, Base); + Return.prototype.isStatement = YES; + Return.prototype.isPureStatement = YES; + Return.prototype.children = ['expression']; + Return.prototype.makeReturn = THIS; + Return.prototype.compile = function(o) { var _ref2, expr; expr = (((_ref2 = this.expression) != null) ? _ref2.makeReturn() : undefined); - if (expr && (!(expr instanceof ReturnNode))) { + if (expr && (!(expr instanceof Return))) { return expr.compile(o); } - return ReturnNode.__super__.compile.call(this, o); + return Return.__super__.compile.call(this, o); }; - ReturnNode.prototype.compileNode = function(o) { + Return.prototype.compileNode = function(o) { var expr; expr = ''; if (this.expression) { @@ -304,14 +304,14 @@ } return "" + (this.tab) + "return" + expr + ";"; }; - return ReturnNode; + return Return; })(); - exports.ValueNode = (function() { - ValueNode = (function() { - return function ValueNode(_arg, _arg2, tag) { + exports.Value = (function() { + Value = (function() { + return function Value(_arg, _arg2, tag) { this.properties = _arg2; this.base = _arg; - ValueNode.__super__.constructor.call(this); + Value.__super__.constructor.call(this); this.properties || (this.properties = []); if (tag) { this.tags[tag] = true; @@ -319,64 +319,64 @@ return this; }; })(); - __extends(ValueNode, BaseNode); - ValueNode.prototype.children = ['base', 'properties']; - ValueNode.prototype.push = function(prop) { + __extends(Value, Base); + Value.prototype.children = ['base', 'properties']; + Value.prototype.push = function(prop) { this.properties.push(prop); return this; }; - ValueNode.prototype.hasProperties = function() { + Value.prototype.hasProperties = function() { return !!this.properties.length; }; - ValueNode.prototype.isArray = function() { - return this.base instanceof ArrayNode && !this.properties.length; + Value.prototype.isArray = function() { + return this.base instanceof ArrayLiteral && !this.properties.length; }; - ValueNode.prototype.isObject = function() { - return this.base instanceof ObjectNode && !this.properties.length; + Value.prototype.isObject = function() { + return this.base instanceof ObjectLiteral && !this.properties.length; }; - ValueNode.prototype.isSplice = function() { - return last(this.properties) instanceof SliceNode; + Value.prototype.isSplice = function() { + return last(this.properties) instanceof Slice; }; - ValueNode.prototype.isComplex = function() { + Value.prototype.isComplex = function() { return this.base.isComplex() || this.hasProperties(); }; - ValueNode.prototype.makeReturn = function() { - return this.properties.length ? ValueNode.__super__.makeReturn.call(this) : this.base.makeReturn(); + Value.prototype.makeReturn = function() { + return this.properties.length ? Value.__super__.makeReturn.call(this) : this.base.makeReturn(); }; - ValueNode.prototype.unwrap = function() { + Value.prototype.unwrap = function() { return this.properties.length ? this : this.base; }; - ValueNode.prototype.isStatement = function(o) { + Value.prototype.isStatement = function(o) { return this.base.isStatement(o) && !this.properties.length; }; - ValueNode.prototype.isNumber = function() { - return this.base instanceof LiteralNode && NUMBER.test(this.base.value); + Value.prototype.isNumber = function() { + return this.base instanceof Literal && NUMBER.test(this.base.value); }; - ValueNode.prototype.cacheReference = function(o) { + Value.prototype.cacheReference = function(o) { var base, bref, name, nref; name = last(this.properties); if (!this.base.isComplex() && this.properties.length < 2 && !((name != null) ? name.isComplex() : undefined)) { return [this, this]; } - base = new ValueNode(this.base, this.properties.slice(0, -1)); + base = new Value(this.base, this.properties.slice(0, -1)); if (base.isComplex()) { bref = literal(o.scope.freeVariable('base')); - base = new ValueNode(new ParentheticalNode(new AssignNode(bref, base))); + base = new Value(new Parenthetical(new Assign(bref, base))); } if (!(name)) { return [base, bref]; } if (name.isComplex()) { nref = literal(o.scope.freeVariable('name')); - name = new IndexNode(new AssignNode(nref, name.index)); - nref = new IndexNode(nref); + name = new Index(new Assign(nref, name.index)); + nref = new Index(nref); } - return [base.push(name), new ValueNode(bref || base.base, [nref || name])]; + return [base.push(name), new Value(bref || base.base, [nref || name])]; }; - ValueNode.prototype.compile = function(o) { - return !o.top || this.properties.length ? ValueNode.__super__.compile.call(this, o) : this.base.compile(o); + Value.prototype.compile = function(o) { + return !o.top || this.properties.length ? Value.__super__.compile.call(this, o) : this.base.compile(o); }; - ValueNode.prototype.compileNode = function(o) { + Value.prototype.compileNode = function(o) { var _i, _len, code, ex, prop, props; if (ex = this.unfoldSoak(o)) { return ex.compile(o); @@ -386,7 +386,7 @@ this.base.parenthetical = true; } code = this.base.compile(o); - if (props[0] instanceof AccessorNode && this.isNumber() || o.top && this.base instanceof ObjectNode) { + if (props[0] instanceof Accessor && this.isNumber() || o.top && this.base instanceof ObjectLiteral) { code = ("(" + code + ")"); } for (_i = 0, _len = props.length; _i < _len; _i++) { @@ -395,7 +395,7 @@ } return code; }; - ValueNode.prototype.unfoldSoak = function(o) { + Value.prototype.unfoldSoak = function(o) { var _len, _ref2, fst, i, ifn, prop, ref, snd; if (this.base.soakNode) { Array.prototype.push.apply(this.base.body.properties, this.properties); @@ -406,14 +406,14 @@ prop = _ref2[i]; if (prop.soakNode) { prop.soakNode = false; - fst = new ValueNode(this.base, this.properties.slice(0, i)); - snd = new ValueNode(this.base, this.properties.slice(i)); + fst = new Value(this.base, this.properties.slice(0, i)); + snd = new Value(this.base, this.properties.slice(i)); if (fst.isComplex()) { ref = literal(o.scope.freeVariable('ref')); - fst = new ParentheticalNode(new AssignNode(ref, fst)); + fst = new Parenthetical(new Assign(ref, fst)); snd.base = ref; } - ifn = new IfNode(new ExistenceNode(fst), snd, { + ifn = new If(new Existence(fst), snd, { operation: true }); ifn.soakNode = true; @@ -422,45 +422,45 @@ } return null; }; - ValueNode.unfoldSoak = function(o, parent, name) { + Value.unfoldSoak = function(o, parent, name) { var ifnode, node; node = parent[name]; - if (node instanceof IfNode && node.soakNode) { + if (node instanceof If && node.soakNode) { ifnode = node; - } else if (node instanceof ValueNode) { + } else if (node instanceof Value) { ifnode = node.unfoldSoak(o); } if (!(ifnode)) { return; } parent[name] = ifnode.body; - ifnode.body = new ValueNode(parent); + ifnode.body = new Value(parent); return ifnode; }; - return ValueNode; + return Value; }).call(this); - exports.CommentNode = (function() { - CommentNode = (function() { - return function CommentNode(_arg) { + exports.Comment = (function() { + Comment = (function() { + return function Comment(_arg) { this.comment = _arg; - CommentNode.__super__.constructor.call(this); + Comment.__super__.constructor.call(this); return this; }; })(); - __extends(CommentNode, BaseNode); - CommentNode.prototype.isStatement = YES; - CommentNode.prototype.makeReturn = THIS; - CommentNode.prototype.compileNode = function(o) { + __extends(Comment, Base); + Comment.prototype.isStatement = YES; + Comment.prototype.makeReturn = THIS; + Comment.prototype.compileNode = function(o) { return this.tab + '/*' + this.comment.replace(/\n/g, '\n' + this.tab) + '*/'; }; - return CommentNode; + return Comment; })(); - exports.CallNode = (function() { - CallNode = (function() { - return function CallNode(variable, _arg, _arg2) { + exports.Call = (function() { + Call = (function() { + return function Call(variable, _arg, _arg2) { this.exist = _arg2; this.args = _arg; - CallNode.__super__.constructor.call(this); + Call.__super__.constructor.call(this); this.isNew = false; this.isSuper = variable === 'super'; this.variable = this.isSuper ? null : variable; @@ -468,19 +468,19 @@ return this; }; })(); - __extends(CallNode, BaseNode); - CallNode.prototype.children = ['variable', 'args']; - CallNode.prototype.compileSplatArguments = function(o) { - return SplatNode.compileSplattedArray(this.args, o); + __extends(Call, Base); + Call.prototype.children = ['variable', 'args']; + Call.prototype.compileSplatArguments = function(o) { + return Splat.compileSplattedArray(this.args, o); }; - CallNode.prototype.newInstance = function() { + Call.prototype.newInstance = function() { this.isNew = true; return this; }; - CallNode.prototype.prefix = function() { + Call.prototype.prefix = function() { return this.isNew ? 'new ' : ''; }; - CallNode.prototype.superReference = function(o) { + Call.prototype.superReference = function(o) { var method, name; method = o.scope.method; if (!(method)) { @@ -492,21 +492,21 @@ } return method.klass ? ("" + (method.klass) + ".__super__." + name) : ("" + name + ".__super__.constructor"); }; - CallNode.prototype.unfoldSoak = function(o) { + Call.prototype.unfoldSoak = function(o) { var _i, _len, _ref2, call, list, node; call = this; list = []; while (true) { - if (call.variable instanceof CallNode) { + if (call.variable instanceof Call) { list.push(call); call = call.variable; continue; } - if (!(call.variable instanceof ValueNode)) { + if (!(call.variable instanceof Value)) { break; } list.push(call); - if (!((call = call.variable.base) instanceof CallNode)) { + if (!((call = call.variable.base) instanceof Call)) { break; } } @@ -514,31 +514,31 @@ for (_i = 0, _len = _ref2.length; _i < _len; _i++) { call = _ref2[_i]; if (node) { - if (call.variable instanceof CallNode) { + if (call.variable instanceof Call) { call.variable = node; } else { call.variable.base = node; } } - node = ValueNode.unfoldSoak(o, call, 'variable'); + node = Value.unfoldSoak(o, call, 'variable'); } return node; }; - CallNode.prototype.compileNode = function(o) { + Call.prototype.compileNode = function(o) { var _i, _j, _len, _len2, _ref2, _ref3, _ref4, _result, arg, args, left, node, rite, val; if (node = this.unfoldSoak(o)) { return node.compile(o); } if (this.exist) { if (val = this.variable) { - if (!(val instanceof ValueNode)) { - val = new ValueNode(val); + if (!(val instanceof Value)) { + val = new Value(val); } _ref2 = val.cacheReference(o), left = _ref2[0], rite = _ref2[1]; - rite = new CallNode(rite, this.args); + rite = new Call(rite, this.args); } else { left = literal(this.superReference(o)); - rite = new CallNode(new ValueNode(left), this.args); + rite = new Call(new Value(left), this.args); rite.isNew = this.isNew; } left = ("typeof " + (left.compile(o)) + " !== \"function\""); @@ -548,7 +548,7 @@ _ref3 = this.args; for (_i = 0, _len = _ref3.length; _i < _len; _i++) { arg = _ref3[_i]; - if (arg instanceof SplatNode) { + if (arg instanceof Splat) { return this.compileSplat(o); } } @@ -562,18 +562,18 @@ }).call(this).join(', '); return this.isSuper ? this.compileSuper(args, o) : ("" + (this.prefix()) + (this.variable.compile(o)) + "(" + args + ")"); }; - CallNode.prototype.compileSuper = function(args, o) { + Call.prototype.compileSuper = function(args, o) { return "" + (this.superReference(o)) + ".call(this" + (args.length ? ', ' : '') + args + ")"; }; - CallNode.prototype.compileSplat = function(o) { + Call.prototype.compileSplat = function(o) { var _i, _len, _ref2, arg, argvar, base, call, ctor, fun, idt, name, ref, result, splatargs; splatargs = this.compileSplatArguments(o); if (this.isSuper) { return ("" + (this.superReference(o)) + ".apply(this, " + splatargs + ")"); } if (!(this.isNew)) { - if (!((base = this.variable) instanceof ValueNode)) { - base = new ValueNode(base); + if (!((base = this.variable) instanceof Value)) { + base = new Value(base); } if ((name = base.properties.pop()) && base.isComplex()) { ref = o.scope.freeVariable('this'); @@ -588,7 +588,7 @@ } call = 'call(this)'; argvar = function(node) { - return node instanceof LiteralNode && node.value === 'arguments'; + return node instanceof Literal && node.value === 'arguments'; }; _ref2 = this.args; for (_i = 0, _len = _ref2.length; _i < _len; _i++) { @@ -603,82 +603,82 @@ result = o.scope.freeVariable('result'); return "(function() {\n" + (idt = this.idt(1)) + "var ctor = function() {};\n" + idt + (utility('extends')) + "(ctor, " + ctor + " = " + (this.variable.compile(o)) + ");\n" + idt + "return typeof (" + result + " = " + ctor + ".apply(" + ref + " = new ctor, " + splatargs + ")) === \"object\" ? " + result + " : " + ref + ";\n" + (this.tab) + "})." + call; }; - return CallNode; + return Call; })(); - exports.ExtendsNode = (function() { - ExtendsNode = (function() { - return function ExtendsNode(_arg, _arg2) { + exports.Extends = (function() { + Extends = (function() { + return function Extends(_arg, _arg2) { this.parent = _arg2; this.child = _arg; - ExtendsNode.__super__.constructor.call(this); + Extends.__super__.constructor.call(this); return this; }; })(); - __extends(ExtendsNode, BaseNode); - ExtendsNode.prototype.children = ['child', 'parent']; - ExtendsNode.prototype.compileNode = function(o) { + __extends(Extends, Base); + Extends.prototype.children = ['child', 'parent']; + Extends.prototype.compileNode = function(o) { var ref; - ref = new ValueNode(literal(utility('extends'))); - return (new CallNode(ref, [this.child, this.parent])).compile(o); + ref = new Value(literal(utility('extends'))); + return (new Call(ref, [this.child, this.parent])).compile(o); }; - return ExtendsNode; + return Extends; })(); - exports.AccessorNode = (function() { - AccessorNode = (function() { - return function AccessorNode(_arg, tag) { + exports.Accessor = (function() { + Accessor = (function() { + return function Accessor(_arg, tag) { this.name = _arg; - AccessorNode.__super__.constructor.call(this); + Accessor.__super__.constructor.call(this); this.prototype = tag === 'prototype' ? '.prototype' : ''; this.soakNode = tag === 'soak'; return this; }; })(); - __extends(AccessorNode, BaseNode); - AccessorNode.prototype.children = ['name']; - AccessorNode.prototype.compileNode = function(o) { + __extends(Accessor, Base); + Accessor.prototype.children = ['name']; + Accessor.prototype.compileNode = function(o) { var name, namePart; name = this.name.compile(o); namePart = name.match(IS_STRING) ? ("[" + name + "]") : ("." + name); return this.prototype + namePart; }; - AccessorNode.prototype.isComplex = NO; - return AccessorNode; + Accessor.prototype.isComplex = NO; + return Accessor; })(); - exports.IndexNode = (function() { - IndexNode = (function() { - return function IndexNode(_arg) { + exports.Index = (function() { + Index = (function() { + return function Index(_arg) { this.index = _arg; - IndexNode.__super__.constructor.call(this); + Index.__super__.constructor.call(this); return this; }; })(); - __extends(IndexNode, BaseNode); - IndexNode.prototype.children = ['index']; - IndexNode.prototype.compileNode = function(o) { + __extends(Index, Base); + Index.prototype.children = ['index']; + Index.prototype.compileNode = function(o) { var idx, prefix; idx = this.index.compile(o); prefix = this.proto ? '.prototype' : ''; return "" + prefix + "[" + idx + "]"; }; - IndexNode.prototype.isComplex = function() { + Index.prototype.isComplex = function() { return this.index.isComplex(); }; - return IndexNode; + return Index; })(); - exports.RangeNode = (function() { - RangeNode = (function() { - return function RangeNode(_arg, _arg2, tag) { + exports.Range = (function() { + Range = (function() { + return function Range(_arg, _arg2, tag) { this.to = _arg2; this.from = _arg; - RangeNode.__super__.constructor.call(this); + Range.__super__.constructor.call(this); this.exclusive = tag === 'exclusive'; this.equals = this.exclusive ? '' : '='; return this; }; })(); - __extends(RangeNode, BaseNode); - RangeNode.prototype.children = ['from', 'to']; - RangeNode.prototype.compileVariables = function(o) { + __extends(Range, Base); + Range.prototype.children = ['from', 'to']; + Range.prototype.compileVariables = function(o) { var _ref2, _ref3, _ref4, parts; o = merge(o, { top: true @@ -699,7 +699,7 @@ } return parts.length ? ("" + (parts.join('; ')) + "; ") : ''; }; - RangeNode.prototype.compileNode = function(o) { + Range.prototype.compileNode = function(o) { var compare, idx, incr, intro, step, stepPart, vars; if (!(o.index)) { return this.compileArray(o); @@ -716,7 +716,7 @@ incr = step ? ("" + idx + " += " + stepPart) : ("" + intro + " += " + stepPart + " : " + idx + " -= " + stepPart + ")"); return "" + vars + "; " + compare + "; " + incr; }; - RangeNode.prototype.compileSimple = function(o) { + Range.prototype.compileSimple = function(o) { var _ref2, from, idx, step, to; _ref2 = [+this.fromNum, +this.toNum], from = _ref2[0], to = _ref2[1]; idx = del(o, 'index'); @@ -724,7 +724,7 @@ step && (step = ("" + idx + " += " + (step.compile(o)))); return from <= to ? ("" + idx + " = " + from + "; " + idx + " <" + (this.equals) + " " + to + "; " + (step || ("" + idx + "++"))) : ("" + idx + " = " + from + "; " + idx + " >" + (this.equals) + " " + to + "; " + (step || ("" + idx + "--"))); }; - RangeNode.prototype.compileArray = function(o) { + Range.prototype.compileArray = function(o) { var _i, _ref2, _ref3, _result, body, clause, i, idt, post, pre, range, result, vars; idt = this.idt(1); vars = this.compileVariables(merge(o, { @@ -754,19 +754,19 @@ post = ("{ " + result + ".push(" + i + "); }\n" + idt + "return " + result + ";\n" + (o.indent)); return "(function() {" + pre + "\n" + idt + "for (" + body + ")" + post + "}).call(this)"; }; - return RangeNode; + return Range; })(); - exports.SliceNode = (function() { - SliceNode = (function() { - return function SliceNode(_arg) { + exports.Slice = (function() { + Slice = (function() { + return function Slice(_arg) { this.range = _arg; - SliceNode.__super__.constructor.call(this); + Slice.__super__.constructor.call(this); return this; }; })(); - __extends(SliceNode, BaseNode); - SliceNode.prototype.children = ['range']; - SliceNode.prototype.compileNode = function(o) { + __extends(Slice, Base); + Slice.prototype.children = ['range']; + Slice.prototype.compileNode = function(o) { var from, to; from = this.range.from ? this.range.from.compile(o) : '0'; to = this.range.to ? this.range.to.compile(o) : ''; @@ -776,20 +776,20 @@ } return ".slice(" + from + to + ")"; }; - return SliceNode; + return Slice; })(); - exports.ObjectNode = (function() { - ObjectNode = (function() { - return function ObjectNode(props) { - ObjectNode.__super__.constructor.call(this); + exports.ObjectLiteral = (function() { + ObjectLiteral = (function() { + return function ObjectLiteral(props) { + ObjectLiteral.__super__.constructor.call(this); this.objects = (this.properties = props || []); return this; }; })(); - __extends(ObjectNode, BaseNode); - ObjectNode.prototype.children = ['properties']; - ObjectNode.prototype.topSensitive = YES; - ObjectNode.prototype.compileNode = function(o) { + __extends(ObjectLiteral, Base); + ObjectLiteral.prototype.children = ['properties']; + ObjectLiteral.prototype.topSensitive = YES; + ObjectLiteral.prototype.compileNode = function(o) { var _i, _len, _ref2, _result, i, indent, join, lastNoncom, nonComments, obj, prop, props, top; top = del(o, 'top'); o.indent = this.idt(1); @@ -797,7 +797,7 @@ _result = []; _ref2 = this.properties; for (_i = 0, _len = _ref2.length; _i < _len; _i++) { prop = _ref2[_i]; - if (!(prop instanceof CommentNode)) { + if (!(prop instanceof Comment)) { _result.push(prop); } } @@ -810,17 +810,17 @@ prop = _ref2[i]; _result.push((function() { join = ",\n"; - if ((prop === lastNoncom) || (prop instanceof CommentNode)) { + if ((prop === lastNoncom) || (prop instanceof Comment)) { join = "\n"; } if (i === this.properties.length - 1) { join = ''; } - indent = prop instanceof CommentNode ? '' : this.idt(1); - if (prop instanceof ValueNode && prop.tags["this"]) { - prop = new AssignNode(prop.properties[0].name, prop, 'object'); - } else if (!(prop instanceof AssignNode) && !(prop instanceof CommentNode)) { - prop = new AssignNode(prop, prop, 'object'); + indent = prop instanceof Comment ? '' : this.idt(1); + if (prop instanceof Value && prop.tags["this"]) { + prop = new Assign(prop.properties[0].name, prop, 'object'); + } else if (!(prop instanceof Assign) && !(prop instanceof Comment)) { + prop = new Assign(prop, prop, 'object'); } return indent + prop.compile(o) + join; }).call(this)); @@ -831,23 +831,23 @@ obj = '{' + (props ? '\n' + props + '\n' + this.idt() : '') + '}'; return top ? ("(" + obj + ")") : obj; }; - return ObjectNode; + return ObjectLiteral; })(); - exports.ArrayNode = (function() { - ArrayNode = (function() { - return function ArrayNode(_arg) { + exports.ArrayLiteral = (function() { + ArrayLiteral = (function() { + return function ArrayLiteral(_arg) { this.objects = _arg; - ArrayNode.__super__.constructor.call(this); + ArrayLiteral.__super__.constructor.call(this); this.objects || (this.objects = []); return this; }; })(); - __extends(ArrayNode, BaseNode); - ArrayNode.prototype.children = ['objects']; - ArrayNode.prototype.compileSplatLiteral = function(o) { - return SplatNode.compileSplattedArray(this.objects, o); + __extends(ArrayLiteral, Base); + ArrayLiteral.prototype.children = ['objects']; + ArrayLiteral.prototype.compileSplatLiteral = function(o) { + return Splat.compileSplattedArray(this.objects, o); }; - ArrayNode.prototype.compileNode = function(o) { + ArrayLiteral.prototype.compileNode = function(o) { var _len, _ref2, code, i, obj, objects; o.indent = this.idt(1); objects = []; @@ -855,9 +855,9 @@ for (i = 0, _len = _ref2.length; i < _len; i++) { obj = _ref2[i]; code = obj.compile(o); - if (obj instanceof SplatNode) { + if (obj instanceof Splat) { return this.compileSplatLiteral(o); - } else if (obj instanceof CommentNode) { + } else if (obj instanceof Comment) { objects.push("\n" + code + "\n" + (o.indent)); } else if (i === this.objects.length - 1) { objects.push(code); @@ -868,69 +868,69 @@ objects = objects.join(''); return indexOf(objects, '\n') >= 0 ? ("[\n" + (this.idt(1)) + objects + "\n" + (this.tab) + "]") : ("[" + objects + "]"); }; - return ArrayNode; + return ArrayLiteral; })(); - exports.ClassNode = (function() { - ClassNode = (function() { - return function ClassNode(variable, _arg, _arg2) { + exports.Class = (function() { + Class = (function() { + return function Class(variable, _arg, _arg2) { this.properties = _arg2; this.parent = _arg; - ClassNode.__super__.constructor.call(this); + Class.__super__.constructor.call(this); this.variable = variable === '__temp__' ? literal(variable) : variable; this.properties || (this.properties = []); this.returns = false; return this; }; })(); - __extends(ClassNode, BaseNode); - ClassNode.prototype.children = ['variable', 'parent', 'properties']; - ClassNode.prototype.isStatement = YES; - ClassNode.prototype.makeReturn = function() { + __extends(Class, Base); + Class.prototype.children = ['variable', 'parent', 'properties']; + Class.prototype.isStatement = YES; + Class.prototype.makeReturn = function() { this.returns = true; return this; }; - ClassNode.prototype.compileNode = function(o) { + Class.prototype.compileNode = function(o) { var _i, _len, _ref2, _ref3, _ref4, access, applied, apply, className, constScope, construct, constructor, extension, func, me, pname, prop, props, pvar, ref, returns, val, variable; variable = this.variable; if (variable.value === '__temp__') { variable = literal(o.scope.freeVariable('ctor')); } - extension = this.parent && new ExtendsNode(variable, this.parent); + extension = this.parent && new Extends(variable, this.parent); props = new Expressions; o.top = true; me = null; className = variable.compile(o); constScope = null; if (this.parent) { - applied = new ValueNode(this.parent, [new AccessorNode(literal('apply'))]); - constructor = new CodeNode([], new Expressions([new CallNode(applied, [literal('this'), literal('arguments')])])); + applied = new Value(this.parent, [new Accessor(literal('apply'))]); + constructor = new Code([], new Expressions([new Call(applied, [literal('this'), literal('arguments')])])); } else { - constructor = new CodeNode; + constructor = new Code; } _ref2 = this.properties; for (_i = 0, _len = _ref2.length; _i < _len; _i++) { prop = _ref2[_i]; _ref3 = [prop.variable, prop.value], pvar = _ref3[0], func = _ref3[1]; if (pvar && pvar.base.value === 'constructor') { - if (!(func instanceof CodeNode)) { + if (!(func instanceof Code)) { _ref4 = func.compileReference(o), func = _ref4[0], ref = _ref4[1]; if (func !== ref) { props.push(func); } - apply = new CallNode(new ValueNode(ref, [new AccessorNode(literal('apply'))]), [literal('this'), literal('arguments')]); - func = new CodeNode([], new Expressions([apply])); + apply = new Call(new Value(ref, [new Accessor(literal('apply'))]), [literal('this'), literal('arguments')]); + func = new Code([], new Expressions([apply])); } if (func.bound) { throw new Error("cannot define a constructor as a bound function."); } func.name = className; - func.body.push(new ReturnNode(literal('this'))); - variable = new ValueNode(variable); + func.body.push(new Return(literal('this'))); + variable = new Value(variable); variable.namespaced = include(func.name, '.'); constructor = func; continue; } - if (func instanceof CodeNode && func.bound) { + if (func instanceof Code && func.bound) { if (prop.context === 'this') { func.context = className; } else { @@ -939,15 +939,15 @@ me || (me = constScope.freeVariable('this')); pname = pvar.compile(o); if (constructor.body.empty()) { - constructor.body.push(new ReturnNode(literal('this'))); + constructor.body.push(new Return(literal('this'))); } constructor.body.unshift(literal("this." + pname + " = function(){ return " + className + ".prototype." + pname + ".apply(" + me + ", arguments); }")); } } if (pvar) { - access = prop.context === 'this' ? pvar.base.properties[0] : new AccessorNode(pvar, 'prototype'); - val = new ValueNode(variable, [access]); - prop = new AssignNode(val, func); + access = prop.context === 'this' ? pvar.base.properties[0] : new Accessor(pvar, 'prototype'); + val = new Value(variable, [access]); + prop = new Assign(val, func); } props.push(prop); } @@ -955,34 +955,34 @@ if (me) { constructor.body.unshift(literal("" + me + " = this")); } - construct = this.idt() + new AssignNode(variable, constructor).compile(merge(o, { + construct = this.idt() + new Assign(variable, constructor).compile(merge(o, { sharedScope: constScope })) + ';'; props = !props.empty() ? '\n' + props.compile(o) : ''; extension = extension ? '\n' + this.idt() + extension.compile(o) + ';' : ''; - returns = this.returns ? '\n' + new ReturnNode(variable).compile(o) : ''; + returns = this.returns ? '\n' + new Return(variable).compile(o) : ''; return construct + extension + props + returns; }; - return ClassNode; + return Class; })(); - exports.AssignNode = (function() { - AssignNode = (function() { - return function AssignNode(_arg, _arg2, _arg3) { + exports.Assign = (function() { + Assign = (function() { + return function Assign(_arg, _arg2, _arg3) { this.context = _arg3; this.value = _arg2; this.variable = _arg; - AssignNode.__super__.constructor.call(this); + Assign.__super__.constructor.call(this); return this; }; })(); - __extends(AssignNode, BaseNode); - AssignNode.prototype.METHOD_DEF = /^(?:(\S+)\.prototype\.)?([$A-Za-z_][$\w]*)$/; - AssignNode.prototype.children = ['variable', 'value']; - AssignNode.prototype.topSensitive = YES; - AssignNode.prototype.isValue = function() { - return this.variable instanceof ValueNode; + __extends(Assign, Base); + Assign.prototype.METHOD_DEF = /^(?:(\S+)\.prototype\.)?([$A-Za-z_][$\w]*)$/; + Assign.prototype.children = ['variable', 'value']; + Assign.prototype.topSensitive = YES; + Assign.prototype.isValue = function() { + return this.variable instanceof Value; }; - AssignNode.prototype.compileNode = function(o) { + Assign.prototype.compileNode = function(o) { var isValue, match, name, node, stmt, top, val; if (isValue = this.isValue()) { if (this.variable.isArray() || this.variable.isObject()) { @@ -991,14 +991,14 @@ if (this.variable.isSplice()) { return this.compileSplice(o); } - if (node = ValueNode.unfoldSoak(o, this, 'variable')) { + if (node = Value.unfoldSoak(o, this, 'variable')) { return node.compile(o); } } top = del(o, 'top'); stmt = del(o, 'asStatement'); name = this.variable.compile(o); - if (this.value instanceof CodeNode && (match = this.METHOD_DEF.exec(name))) { + if (this.value instanceof Code && (match = this.METHOD_DEF.exec(name))) { this.value.name = match[2]; this.value.klass = match[1]; } @@ -1015,28 +1015,28 @@ } return top || this.parenthetical ? val : ("(" + val + ")"); }; - AssignNode.prototype.compilePatternMatch = function(o) { + Assign.prototype.compilePatternMatch = function(o) { var _len, _ref2, _ref3, accessClass, assigns, code, i, idx, isObject, obj, objects, olength, otop, splat, top, val, valVar, value; if ((value = this.value).isStatement(o)) { - value = ClosureNode.wrap(value); + value = Closure.wrap(value); } objects = this.variable.base.objects; if (!(olength = objects.length)) { return value.compile(o); } isObject = this.variable.isObject(); - if (o.top && olength === 1 && !((obj = objects[0]) instanceof SplatNode)) { - if (obj instanceof AssignNode) { + if (o.top && olength === 1 && !((obj = objects[0]) instanceof Splat)) { + if (obj instanceof Assign) { _ref2 = obj, idx = _ref2.variable.base, obj = _ref2.value; } else { idx = isObject ? (obj.tags["this"] ? obj.properties[0].name : obj) : literal(0); } - if (!(value instanceof ValueNode)) { - value = new ValueNode(value); + if (!(value instanceof Value)) { + value = new Value(value); } - accessClass = IDENTIFIER.test(idx.value) ? AccessorNode : IndexNode; + accessClass = IDENTIFIER.test(idx.value) ? Accessor : Index; value.properties.push(new accessClass(idx)); - return new AssignNode(obj, value).compile(o); + return new Assign(obj, value).compile(o); } top = del(o, 'top'); otop = merge(o, { @@ -1049,26 +1049,26 @@ obj = objects[i]; idx = i; if (isObject) { - if (obj instanceof AssignNode) { + if (obj instanceof Assign) { _ref3 = [obj.value, obj.variable.base], obj = _ref3[0], idx = _ref3[1]; } else { idx = obj.tags["this"] ? obj.properties[0].name : obj; } } - if (!(obj instanceof ValueNode || obj instanceof SplatNode)) { + if (!(obj instanceof Value || obj instanceof Splat)) { throw new Error('pattern matching must use only identifiers on the left-hand side.'); } - accessClass = isObject && IDENTIFIER.test(idx.value) ? AccessorNode : IndexNode; - if (!splat && obj instanceof SplatNode) { + accessClass = isObject && IDENTIFIER.test(idx.value) ? Accessor : Index; + if (!splat && obj instanceof Splat) { val = literal(obj.compileValue(o, valVar, i, olength - i - 1)); splat = true; } else { if (typeof idx !== 'object') { idx = literal(splat ? ("" + valVar + ".length - " + (olength - idx)) : idx); } - val = new ValueNode(literal(valVar), [new accessClass(idx)]); + val = new Value(literal(valVar), [new accessClass(idx)]); } - assigns.push(new AssignNode(obj, val).compile(otop)); + assigns.push(new Assign(obj, val).compile(otop)); } if (!(top)) { assigns.push(valVar); @@ -1076,7 +1076,7 @@ code = assigns.join(', '); return top || this.parenthetical ? code : ("(" + code + ")"); }; - AssignNode.prototype.compileSplice = function(o) { + Assign.prototype.compileSplice = function(o) { var from, name, plus, range, ref, to, val; range = this.variable.properties.pop().range; name = this.variable.compile(o); @@ -1087,14 +1087,14 @@ val = this.value.compile(o); return "([].splice.apply(" + name + ", [" + from + ", " + to + "].concat(" + ref + " = " + val + ")), " + ref + ")"; }; - return AssignNode; + return Assign; })(); - exports.CodeNode = (function() { - CodeNode = (function() { - return function CodeNode(_arg, _arg2, tag) { + exports.Code = (function() { + Code = (function() { + return function Code(_arg, _arg2, tag) { this.body = _arg2; this.params = _arg; - CodeNode.__super__.constructor.call(this); + Code.__super__.constructor.call(this); this.params || (this.params = []); this.body || (this.body = new Expressions); this.bound = tag === 'boundfunc'; @@ -1104,9 +1104,9 @@ return this; }; })(); - __extends(CodeNode, BaseNode); - CodeNode.prototype.children = ['params', 'body']; - CodeNode.prototype.compileNode = function(o) { + __extends(Code, Base); + Code.prototype.children = ['params', 'body']; + Code.prototype.compileNode = function(o) { var _i, _len, _len2, _ref2, _ref3, _result, close, code, empty, func, i, open, param, params, sharedScope, splat, top, value; sharedScope = del(o, 'sharedScope'); top = del(o, 'top'); @@ -1123,7 +1123,7 @@ param = _ref2[i]; if (splat) { if (param.attach) { - param.assign = new AssignNode(new ValueNode(literal('this'), [new AccessorNode(param.value)])); + param.assign = new Assign(new Value(literal('this'), [new Accessor(param.value)])); this.body.expressions.splice(splat.index + 1, 0, param.assign); } splat.trailings.push(param); @@ -1131,10 +1131,10 @@ if (param.attach) { value = param.value; _ref3 = [literal(o.scope.freeVariable('arg')), param.splat], param = _ref3[0], param.splat = _ref3[1]; - this.body.unshift(new AssignNode(new ValueNode(literal('this'), [new AccessorNode(value)]), param)); + this.body.unshift(new Assign(new Value(literal('this'), [new Accessor(value)]), param)); } if (param.splat) { - splat = new SplatNode(param.value); + splat = new Splat(param.value); splat.index = i; splat.trailings = []; splat.arglength = this.params.length; @@ -1173,29 +1173,29 @@ } return top ? ("(" + func + ")") : func; }; - CodeNode.prototype.topSensitive = YES; - CodeNode.prototype.traverseChildren = function(crossScope, func) { - return crossScope ? CodeNode.__super__.traverseChildren.call(this, crossScope, func) : undefined; + Code.prototype.topSensitive = YES; + Code.prototype.traverseChildren = function(crossScope, func) { + return crossScope ? Code.__super__.traverseChildren.call(this, crossScope, func) : undefined; }; - return CodeNode; + return Code; })(); - exports.ParamNode = (function() { - ParamNode = (function() { - return function ParamNode(_arg, _arg2, _arg3) { + exports.Param = (function() { + Param = (function() { + return function Param(_arg, _arg2, _arg3) { this.splat = _arg3; this.attach = _arg2; this.name = _arg; - ParamNode.__super__.constructor.call(this); + Param.__super__.constructor.call(this); this.value = literal(this.name); return this; }; })(); - __extends(ParamNode, BaseNode); - ParamNode.prototype.children = ['name']; - ParamNode.prototype.compileNode = function(o) { + __extends(Param, Base); + Param.prototype.children = ['name']; + Param.prototype.compileNode = function(o) { return this.value.compile(o); }; - ParamNode.prototype.toString = function() { + Param.prototype.toString = function() { var name; name = this.name; if (this.attach) { @@ -1206,12 +1206,12 @@ } return literal(name).toString(); }; - return ParamNode; + return Param; })(); - exports.SplatNode = (function() { - SplatNode = (function() { - return function SplatNode(name) { - SplatNode.__super__.constructor.call(this); + exports.Splat = (function() { + Splat = (function() { + return function Splat(name) { + Splat.__super__.constructor.call(this); if (!(name.compile)) { name = literal(name); } @@ -1219,12 +1219,12 @@ return this; }; })(); - __extends(SplatNode, BaseNode); - SplatNode.prototype.children = ['name']; - SplatNode.prototype.compileNode = function(o) { + __extends(Splat, Base); + Splat.prototype.children = ['name']; + Splat.prototype.compileNode = function(o) { return (this.index != null) ? this.compileParam(o) : this.name.compile(o); }; - SplatNode.prototype.compileParam = function(o) { + Splat.prototype.compileParam = function(o) { var _len, _ref2, assign, end, idx, len, name, pos, trailing, variadic; name = this.name.compile(o); o.scope.find(name); @@ -1249,12 +1249,12 @@ } return "" + name + " = " + (utility('slice')) + ".call(arguments, " + (this.index) + end + ")"; }; - SplatNode.prototype.compileValue = function(o, name, index, trailings) { + Splat.prototype.compileValue = function(o, name, index, trailings) { var trail; trail = trailings ? (", " + name + ".length - " + trailings) : ''; return "" + (utility('slice')) + ".call(" + name + ", " + index + trail + ")"; }; - SplatNode.compileSplattedArray = function(list, o) { + Splat.compileSplattedArray = function(list, o) { var _len, arg, args, code, end, i, prev; args = []; end = -1; @@ -1262,7 +1262,7 @@ arg = list[i]; code = arg.compile(o); prev = args[end]; - if (!(arg instanceof SplatNode)) { + if (!(arg instanceof Splat)) { if (prev && starts(prev, '[') && ends(prev, ']')) { args[end] = ("" + (prev.slice(0, -1)) + ", " + code + "]"); continue; @@ -1277,36 +1277,36 @@ } return args.join(''); }; - return SplatNode; + return Splat; }).call(this); - exports.WhileNode = (function() { - WhileNode = (function() { - return function WhileNode(condition, opts) { - WhileNode.__super__.constructor.call(this); + exports.While = (function() { + While = (function() { + return function While(condition, opts) { + While.__super__.constructor.call(this); if (((opts != null) ? opts.invert : undefined)) { - if (condition instanceof OpNode) { - condition = new ParentheticalNode(condition); + if (condition instanceof Op) { + condition = new Parenthetical(condition); } - condition = new OpNode('!', condition); + condition = new Op('!', condition); } this.condition = condition; this.guard = ((opts != null) ? opts.guard : undefined); return this; }; })(); - __extends(WhileNode, BaseNode); - WhileNode.prototype.children = ['condition', 'guard', 'body']; - WhileNode.prototype.isStatement = YES; - WhileNode.prototype.addBody = function(body) { + __extends(While, Base); + While.prototype.children = ['condition', 'guard', 'body']; + While.prototype.isStatement = YES; + While.prototype.addBody = function(body) { this.body = body; return this; }; - WhileNode.prototype.makeReturn = function() { + While.prototype.makeReturn = function() { this.returns = true; return this; }; - WhileNode.prototype.topSensitive = YES; - WhileNode.prototype.compileNode = function(o) { + While.prototype.topSensitive = YES; + While.prototype.compileNode = function(o) { var cond, post, pre, rvar, set, top; top = del(o, 'top') && !this.returns; o.indent = this.idt(1); @@ -1318,15 +1318,15 @@ rvar = o.scope.freeVariable('result'); set = ("" + (this.tab) + rvar + " = [];\n"); if (this.body) { - this.body = PushNode.wrap(rvar, this.body); + this.body = Push.wrap(rvar, this.body); } } pre = ("" + set + (this.tab) + "while (" + cond + ")"); if (this.guard) { - this.body = Expressions.wrap([new IfNode(this.guard, this.body)]); + this.body = Expressions.wrap([new If(this.guard, this.body)]); } if (this.returns) { - post = '\n' + new ReturnNode(literal(rvar)).compile(merge(o, { + post = '\n' + new Return(literal(rvar)).compile(merge(o, { indent: this.idt() })); } else { @@ -1334,20 +1334,20 @@ } return "" + pre + " {\n" + (this.body.compile(o)) + "\n" + (this.tab) + "}" + post; }; - return WhileNode; + return While; })(); - exports.OpNode = (function() { - OpNode = (function() { - return function OpNode(_arg, _arg2, _arg3, flip) { + exports.Op = (function() { + Op = (function() { + return function Op(_arg, _arg2, _arg3, flip) { this.second = _arg3; this.first = _arg2; this.operator = _arg; - OpNode.__super__.constructor.call(this); + Op.__super__.constructor.call(this); this.operator = this.CONVERSIONS[this.operator] || this.operator; this.flip = !!flip; - if (this.first instanceof ValueNode && this.first.base instanceof ObjectNode) { - this.first = new ParentheticalNode(this.first); - } else if (this.operator === 'new' && this.first instanceof CallNode) { + if (this.first instanceof Value && this.first.base instanceof ObjectLiteral) { + this.first = new Parenthetical(this.first); + } else if (this.operator === 'new' && this.first instanceof Call) { return this.first.newInstance(); } this.first.tags.operation = true; @@ -1357,49 +1357,49 @@ return this; }; })(); - __extends(OpNode, BaseNode); - OpNode.prototype.CONVERSIONS = { + __extends(Op, Base); + Op.prototype.CONVERSIONS = { '==': '===', '!=': '!==', of: 'in' }; - OpNode.prototype.INVERSIONS = { + Op.prototype.INVERSIONS = { '!==': '===', '===': '!==' }; - OpNode.prototype.CHAINABLE = ['<', '>', '>=', '<=', '===', '!==']; - OpNode.prototype.ASSIGNMENT = ['||=', '&&=', '?=']; - OpNode.prototype.PREFIX_OPERATORS = ['new', 'typeof', 'delete']; - OpNode.prototype.children = ['first', 'second']; - OpNode.prototype.isUnary = function() { + Op.prototype.CHAINABLE = ['<', '>', '>=', '<=', '===', '!==']; + Op.prototype.ASSIGNMENT = ['||=', '&&=', '?=']; + Op.prototype.PREFIX_OPERATORS = ['new', 'typeof', 'delete']; + Op.prototype.children = ['first', 'second']; + Op.prototype.isUnary = function() { return !this.second; }; - OpNode.prototype.isInvertible = function() { + Op.prototype.isInvertible = function() { var _ref2; - return (('===' === (_ref2 = this.operator) || '!==' === _ref2)) && !(this.first instanceof OpNode) && !(this.second instanceof OpNode); + return (('===' === (_ref2 = this.operator) || '!==' === _ref2)) && !(this.first instanceof Op) && !(this.second instanceof Op); }; - OpNode.prototype.isComplex = function() { + Op.prototype.isComplex = function() { return this.operator !== '!' || this.first.isComplex(); }; - OpNode.prototype.isMutator = function() { + Op.prototype.isMutator = function() { var _ref2; return ends(this.operator, '=') && !('===' === (_ref2 = this.operator) || '!==' === _ref2); }; - OpNode.prototype.isChainable = function() { + Op.prototype.isChainable = function() { return include(this.CHAINABLE, this.operator); }; - OpNode.prototype.invert = function() { + Op.prototype.invert = function() { return (this.operator = this.INVERSIONS[this.operator]); }; - OpNode.prototype.toString = function(idt) { - return OpNode.__super__.toString.call(this, idt, this.constructor.name + ' ' + this.operator); + Op.prototype.toString = function(idt) { + return Op.__super__.toString.call(this, idt, this.constructor.name + ' ' + this.operator); }; - OpNode.prototype.compileNode = function(o) { + Op.prototype.compileNode = function(o) { var node; - if (node = ValueNode.unfoldSoak(o, this, 'first')) { + if (node = Value.unfoldSoak(o, this, 'first')) { return node.compile(o); } - if (this.isChainable() && this.first.unwrap() instanceof OpNode && this.first.unwrap().isChainable()) { + if (this.isChainable() && this.first.unwrap() instanceof Op && this.first.unwrap().isChainable()) { return this.compileChain(o); } if (indexOf(this.ASSIGNMENT, this.operator) >= 0) { @@ -1411,39 +1411,39 @@ if (this.operator === '?') { return this.compileExistence(o); } - if (this.first instanceof OpNode && this.first.isMutator()) { - this.first = new ParentheticalNode(this.first); + if (this.first instanceof Op && this.first.isMutator()) { + this.first = new Parenthetical(this.first); } - if (this.second instanceof OpNode && this.second.isMutator()) { - this.second = new ParentheticalNode(this.second); + if (this.second instanceof Op && this.second.isMutator()) { + this.second = new Parenthetical(this.second); } return [this.first.compile(o), this.operator, this.second.compile(o)].join(' '); }; - OpNode.prototype.compileChain = function(o) { + Op.prototype.compileChain = function(o) { var _ref2, _ref3, first, second, shared; shared = this.first.unwrap().second; _ref2 = shared.compileReference(o), this.first.second = _ref2[0], shared = _ref2[1]; _ref3 = [this.first.compile(o), this.second.compile(o), shared.compile(o)], first = _ref3[0], second = _ref3[1], shared = _ref3[2]; return "(" + first + ") && (" + shared + " " + (this.operator) + " " + second + ")"; }; - OpNode.prototype.compileAssignment = function(o) { + Op.prototype.compileAssignment = function(o) { var _ref2, left, rite; _ref2 = this.first.cacheReference(o), left = _ref2[0], rite = _ref2[1]; - rite = new AssignNode(rite, this.second); - return new OpNode(this.operator.slice(0, -1), left, rite).compile(o); + rite = new Assign(rite, this.second); + return new Op(this.operator.slice(0, -1), left, rite).compile(o); }; - OpNode.prototype.compileExistence = function(o) { + Op.prototype.compileExistence = function(o) { var fst, ref; if (this.first.isComplex()) { ref = o.scope.freeVariable('ref'); - fst = new ParentheticalNode(new AssignNode(literal(ref), this.first)); + fst = new Parenthetical(new Assign(literal(ref), this.first)); } else { fst = this.first; ref = fst.compile(o); } - return new ExistenceNode(fst).compile(o) + (" ? " + ref + " : " + (this.second.compile(o))); + return new Existence(fst).compile(o) + (" ? " + ref + " : " + (this.second.compile(o))); }; - OpNode.prototype.compileUnary = function(o) { + Op.prototype.compileUnary = function(o) { var parts, space; space = indexOf(this.PREFIX_OPERATORS, this.operator) >= 0 ? ' ' : ''; parts = [this.operator, space, this.first.compile(o)]; @@ -1452,30 +1452,30 @@ } return parts.join(''); }; - return OpNode; + return Op; })(); - exports.InNode = (function() { - InNode = (function() { - return function InNode(_arg, _arg2) { + exports.In = (function() { + In = (function() { + return function In(_arg, _arg2) { this.array = _arg2; this.object = _arg; - InNode.__super__.constructor.call(this); + In.__super__.constructor.call(this); return this; }; })(); - __extends(InNode, BaseNode); - InNode.prototype.children = ['object', 'array']; - InNode.prototype.isArray = function() { - return this.array instanceof ValueNode && this.array.isArray(); + __extends(In, Base); + In.prototype.children = ['object', 'array']; + In.prototype.isArray = function() { + return this.array instanceof Value && this.array.isArray(); }; - InNode.prototype.compileNode = function(o) { + In.prototype.compileNode = function(o) { var _ref2; _ref2 = this.object.compileReference(o, { precompile: true }), this.obj1 = _ref2[0], this.obj2 = _ref2[1]; return this.isArray() ? this.compileOrTest(o) : this.compileLoopTest(o); }; - InNode.prototype.compileOrTest = function(o) { + In.prototype.compileOrTest = function(o) { var _len, _ref2, _result, i, item, tests; tests = (function() { _result = []; _ref2 = this.array.base.objects; @@ -1487,7 +1487,7 @@ }).call(this); return "(" + (tests.join(' || ')) + ")"; }; - InNode.prototype.compileLoopTest = function(o) { + In.prototype.compileLoopTest = function(o) { var _ref2, _ref3, i, l, prefix; _ref2 = this.array.compileReference(o, { precompile: true @@ -1496,23 +1496,23 @@ prefix = this.obj1 !== this.obj2 ? this.obj1 + '; ' : ''; return "(function(){ " + prefix + "for (var " + i + "=0, " + l + "=" + (this.arr1) + ".length; " + i + "<" + l + "; " + i + "++) { if (" + (this.arr2) + "[" + i + "] === " + (this.obj2) + ") return true; } return false; }).call(this)"; }; - return InNode; + return In; })(); - exports.TryNode = (function() { - TryNode = (function() { - return function TryNode(_arg, _arg2, _arg3, _arg4) { + exports.Try = (function() { + Try = (function() { + return function Try(_arg, _arg2, _arg3, _arg4) { this.ensure = _arg4; this.recovery = _arg3; this.error = _arg2; this.attempt = _arg; - TryNode.__super__.constructor.call(this); + Try.__super__.constructor.call(this); return this; }; })(); - __extends(TryNode, BaseNode); - TryNode.prototype.children = ['attempt', 'recovery', 'ensure']; - TryNode.prototype.isStatement = YES; - TryNode.prototype.makeReturn = function() { + __extends(Try, Base); + Try.prototype.children = ['attempt', 'recovery', 'ensure']; + Try.prototype.isStatement = YES; + Try.prototype.makeReturn = function() { if (this.attempt) { this.attempt = this.attempt.makeReturn(); } @@ -1521,7 +1521,7 @@ } return this; }; - TryNode.prototype.compileNode = function(o) { + Try.prototype.compileNode = function(o) { var attemptPart, catchPart, errorPart, finallyPart; o.indent = this.idt(1); o.top = true; @@ -1531,64 +1531,64 @@ finallyPart = (this.ensure || '') && ' finally {\n' + this.ensure.compile(merge(o)) + ("\n" + (this.tab) + "}"); return "" + (this.tab) + "try {\n" + attemptPart + "\n" + (this.tab) + "}" + catchPart + finallyPart; }; - return TryNode; + return Try; })(); - exports.ThrowNode = (function() { - ThrowNode = (function() { - return function ThrowNode(_arg) { + exports.Throw = (function() { + Throw = (function() { + return function Throw(_arg) { this.expression = _arg; - ThrowNode.__super__.constructor.call(this); + Throw.__super__.constructor.call(this); return this; }; })(); - __extends(ThrowNode, BaseNode); - ThrowNode.prototype.children = ['expression']; - ThrowNode.prototype.isStatement = YES; - ThrowNode.prototype.makeReturn = THIS; - ThrowNode.prototype.compileNode = function(o) { + __extends(Throw, Base); + Throw.prototype.children = ['expression']; + Throw.prototype.isStatement = YES; + Throw.prototype.makeReturn = THIS; + Throw.prototype.compileNode = function(o) { return "" + (this.tab) + "throw " + (this.expression.compile(o)) + ";"; }; - return ThrowNode; + return Throw; })(); - exports.ExistenceNode = (function() { - ExistenceNode = (function() { - return function ExistenceNode(_arg) { + exports.Existence = (function() { + Existence = (function() { + return function Existence(_arg) { this.expression = _arg; - ExistenceNode.__super__.constructor.call(this); + Existence.__super__.constructor.call(this); return this; }; })(); - __extends(ExistenceNode, BaseNode); - ExistenceNode.prototype.children = ['expression']; - ExistenceNode.prototype.compileNode = function(o) { + __extends(Existence, Base); + Existence.prototype.children = ['expression']; + Existence.prototype.compileNode = function(o) { var code; code = this.expression.compile(o); code = IDENTIFIER.test(code) && !o.scope.check(code) ? ("typeof " + code + " !== \"undefined\" && " + code + " !== null") : ("" + code + " != null"); return this.parenthetical ? code : ("(" + code + ")"); }; - return ExistenceNode; + return Existence; })(); - exports.ParentheticalNode = (function() { - ParentheticalNode = (function() { - return function ParentheticalNode(_arg) { + exports.Parenthetical = (function() { + Parenthetical = (function() { + return function Parenthetical(_arg) { this.expression = _arg; - ParentheticalNode.__super__.constructor.call(this); + Parenthetical.__super__.constructor.call(this); return this; }; })(); - __extends(ParentheticalNode, BaseNode); - ParentheticalNode.prototype.children = ['expression']; - ParentheticalNode.prototype.isStatement = function(o) { + __extends(Parenthetical, Base); + Parenthetical.prototype.children = ['expression']; + Parenthetical.prototype.isStatement = function(o) { return this.expression.isStatement(o); }; - ParentheticalNode.prototype.isComplex = function() { + Parenthetical.prototype.isComplex = function() { return this.expression.isComplex(); }; - ParentheticalNode.prototype.topSensitive = YES; - ParentheticalNode.prototype.makeReturn = function() { + Parenthetical.prototype.topSensitive = YES; + Parenthetical.prototype.makeReturn = function() { return this.expression.makeReturn(); }; - ParentheticalNode.prototype.compileNode = function(o) { + Parenthetical.prototype.compileNode = function(o) { var code, top; top = del(o, 'top'); this.expression.parenthetical = true; @@ -1601,16 +1601,16 @@ } return "(" + code + ")"; }; - return ParentheticalNode; + return Parenthetical; })(); - exports.ForNode = (function() { - ForNode = (function() { - return function ForNode(_arg, source, _arg2, _arg3) { + exports.For = (function() { + For = (function() { + return function For(_arg, source, _arg2, _arg3) { var _ref2; this.index = _arg3; this.name = _arg2; this.body = _arg; - ForNode.__super__.constructor.call(this); + For.__super__.constructor.call(this); this.index || (this.index = null); this.source = source.source; this.guard = source.guard; @@ -1620,38 +1620,38 @@ if (this.object) { _ref2 = [this.index, this.name], this.name = _ref2[0], this.index = _ref2[1]; } - this.pattern = this.name instanceof ValueNode; - if (this.index instanceof ValueNode) { + this.pattern = this.name instanceof Value; + if (this.index instanceof Value) { throw new Error('index cannot be a pattern matching expression'); } this.returns = false; return this; }; })(); - __extends(ForNode, BaseNode); - ForNode.prototype.children = ['body', 'source', 'guard']; - ForNode.prototype.isStatement = YES; - ForNode.prototype.topSensitive = YES; - ForNode.prototype.makeReturn = function() { + __extends(For, Base); + For.prototype.children = ['body', 'source', 'guard']; + For.prototype.isStatement = YES; + For.prototype.topSensitive = YES; + For.prototype.makeReturn = function() { this.returns = true; return this; }; - ForNode.prototype.compileReturnValue = function(val, o) { + For.prototype.compileReturnValue = function(val, o) { if (this.returns) { - return '\n' + new ReturnNode(literal(val)).compile(o); + return '\n' + new Return(literal(val)).compile(o); } if (val) { return '\n' + val; } return ''; }; - ForNode.prototype.compileNode = function(o) { + For.prototype.compileNode = function(o) { var _ref2, body, codeInBody, forPart, guardPart, idt1, index, ivar, lvar, name, namePart, range, returnResult, rvar, scope, source, sourcePart, stepPart, svar, topLevel, varPart, vars; topLevel = del(o, 'top') && !this.returns; - range = this.source instanceof ValueNode && this.source.base instanceof RangeNode && !this.source.properties.length; + range = this.source instanceof Value && this.source.base instanceof Range && !this.source.properties.length; source = range ? this.source.base : this.source; codeInBody = this.body.contains(function(node) { - return node instanceof CodeNode; + return node instanceof Code; }); scope = o.scope; name = this.name && this.name.compile(o); @@ -1690,7 +1690,7 @@ precompile: true }), sourcePart = _ref2[0], svar = _ref2[1]; sourcePart = sourcePart === svar ? '' : ("" + sourcePart + ";"); - namePart = this.pattern ? new AssignNode(this.name, literal("" + svar + "[" + ivar + "]")).compile(merge(o, { + namePart = this.pattern ? new Assign(this.name, literal("" + svar + "[" + ivar + "]")).compile(merge(o, { top: true })) : (name ? ("" + name + " = " + svar + "[" + ivar + "]") : undefined); if (!(this.object)) { @@ -1703,10 +1703,10 @@ sourcePart = sourcePart ? ("" + (this.tab) + sourcePart + "\n" + (this.tab)) : this.tab; returnResult = this.compileReturnValue(rvar, o); if (!(topLevel)) { - body = PushNode.wrap(rvar, body); + body = Push.wrap(rvar, body); } if (this.guard) { - body = Expressions.wrap([new IfNode(this.guard, body)]); + body = Expressions.wrap([new If(this.guard, body)]); } if (codeInBody) { if (range) { @@ -1718,7 +1718,7 @@ if (index) { body.unshift(literal("var " + index + " = " + ivar)); } - body = ClosureNode.wrap(body, true); + body = Closure.wrap(body, true); } else { if (namePart) { varPart = ("" + idt1 + namePart + ";\n"); @@ -1737,24 +1737,24 @@ vars = range ? name : ("" + name + ", " + ivar); return "" + sourcePart + "for (" + forPart + ") {" + guardPart + "\n" + varPart + body + "\n" + (this.tab) + "}" + returnResult; }; - return ForNode; + return For; })(); - exports.SwitchNode = (function() { - SwitchNode = (function() { - return function SwitchNode(_arg, _arg2, _arg3) { + exports.Switch = (function() { + Switch = (function() { + return function Switch(_arg, _arg2, _arg3) { this.otherwise = _arg3; this.cases = _arg2; this.subject = _arg; - SwitchNode.__super__.constructor.call(this); + Switch.__super__.constructor.call(this); this.tags.subjectless = !this.subject; this.subject || (this.subject = literal('true')); return this; }; })(); - __extends(SwitchNode, BaseNode); - SwitchNode.prototype.children = ['subject', 'cases', 'otherwise']; - SwitchNode.prototype.isStatement = YES; - SwitchNode.prototype.makeReturn = function() { + __extends(Switch, Base); + Switch.prototype.children = ['subject', 'cases', 'otherwise']; + Switch.prototype.isStatement = YES; + Switch.prototype.makeReturn = function() { var _i, _len, _ref2, pair; _ref2 = this.cases; for (_i = 0, _len = _ref2.length; _i < _len; _i++) { @@ -1766,7 +1766,7 @@ } return this; }; - SwitchNode.prototype.compileNode = function(o) { + Switch.prototype.compileNode = function(o) { var _i, _j, _len, _len2, _ref2, _ref3, _ref4, block, code, condition, conditions, exprs, idt, pair; idt = (o.indent = this.idt(2)); o.top = true; @@ -1780,12 +1780,12 @@ for (_j = 0, _len2 = _ref4.length; _j < _len2; _j++) { condition = _ref4[_j]; if (this.tags.subjectless) { - condition = new OpNode('!!', new ParentheticalNode(condition)); + condition = new Op('!!', new Parenthetical(condition)); } code += ("\n" + (this.idt(1)) + "case " + (condition.compile(o)) + ":"); } code += ("\n" + (block.compile(o))); - if (!(last(exprs) instanceof ReturnNode)) { + if (!(last(exprs) instanceof Return)) { code += ("\n" + idt + "break;"); } } @@ -1795,20 +1795,20 @@ code += ("\n" + (this.tab) + "}"); return code; }; - return SwitchNode; + return Switch; })(); - exports.IfNode = (function() { - IfNode = (function() { - return function IfNode(_arg, _arg2, _arg3) { + exports.If = (function() { + If = (function() { + return function If(_arg, _arg2, _arg3) { this.tags = _arg3; this.body = _arg2; this.condition = _arg; this.tags || (this.tags = {}); if (this.tags.invert) { - if (this.condition instanceof OpNode && this.condition.isInvertible()) { + if (this.condition instanceof Op && this.condition.isInvertible()) { this.condition.invert(); } else { - this.condition = new OpNode('!', new ParentheticalNode(this.condition)); + this.condition = new Op('!', new Parenthetical(this.condition)); } } this.elseBody = null; @@ -1816,30 +1816,30 @@ return this; }; })(); - __extends(IfNode, BaseNode); - IfNode.prototype.children = ['condition', 'body', 'elseBody', 'assigner']; - IfNode.prototype.topSensitive = YES; - IfNode.prototype.bodyNode = function() { + __extends(If, Base); + If.prototype.children = ['condition', 'body', 'elseBody', 'assigner']; + If.prototype.topSensitive = YES; + If.prototype.bodyNode = function() { var _ref2; return (((_ref2 = this.body) != null) ? _ref2.unwrap() : undefined); }; - IfNode.prototype.elseBodyNode = function() { + If.prototype.elseBodyNode = function() { var _ref2; return (((_ref2 = this.elseBody) != null) ? _ref2.unwrap() : undefined); }; - IfNode.prototype.addElse = function(elseBody, statement) { + If.prototype.addElse = function(elseBody, statement) { if (this.isChain) { this.elseBodyNode().addElse(elseBody, statement); } else { - this.isChain = elseBody instanceof IfNode; + this.isChain = elseBody instanceof If; this.elseBody = this.ensureExpressions(elseBody); } return this; }; - IfNode.prototype.isStatement = function(o) { + If.prototype.isStatement = function(o) { return this.statement || (this.statement = !!((o && o.top) || this.bodyNode().isStatement(o) || (this.elseBody && this.elseBodyNode().isStatement(o)))); }; - IfNode.prototype.compileCondition = function(o) { + If.prototype.compileCondition = function(o) { var _i, _len, _result, cond, conditions; conditions = flatten([this.condition]); if (conditions.length === 1) { @@ -1854,22 +1854,22 @@ return _result; })().join(' || '); }; - IfNode.prototype.compileNode = function(o) { + If.prototype.compileNode = function(o) { return this.isStatement(o) ? this.compileStatement(o) : this.compileExpression(o); }; - IfNode.prototype.makeReturn = function() { + If.prototype.makeReturn = function() { if (this.isStatement()) { this.body && (this.body = this.ensureExpressions(this.body.makeReturn())); this.elseBody && (this.elseBody = this.ensureExpressions(this.elseBody.makeReturn())); return this; } else { - return new ReturnNode(this); + return new Return(this); } }; - IfNode.prototype.ensureExpressions = function(node) { + If.prototype.ensureExpressions = function(node) { return node instanceof Expressions ? node : new Expressions([node]); }; - IfNode.prototype.compileStatement = function(o) { + If.prototype.compileStatement = function(o) { var body, child, comDent, condO, elsePart, ifDent, ifPart, top; top = del(o, 'top'); child = del(o, 'chainChild'); @@ -1889,7 +1889,7 @@ })) : (" else {\n" + (this.elseBody.compile(o)) + "\n" + (this.tab) + "}"); return "" + ifPart + elsePart; }; - IfNode.prototype.compileExpression = function(o) { + If.prototype.compileExpression = function(o) { var code, elsePart, ifPart; this.bodyNode().tags.operation = (this.condition.tags.operation = true); if (this.elseBody) { @@ -1900,23 +1900,23 @@ code = ("" + ifPart + " : " + elsePart); return this.tags.operation ? ("(" + code + ")") : code; }; - return IfNode; + return If; })(); - PushNode = { + Push = { wrap: function(name, expressions) { if (expressions.empty() || expressions.containsPureStatement()) { return expressions; } - return Expressions.wrap([new CallNode(new ValueNode(literal(name), [new AccessorNode(literal('push'))]), [expressions.unwrap()])]); + return Expressions.wrap([new Call(new Value(literal(name), [new Accessor(literal('push'))]), [expressions.unwrap()])]); } }; - ClosureNode = { + Closure = { wrap: function(expressions, statement) { var args, call, func, mentionsArgs, meth; if (expressions.containsPureStatement()) { return expressions; } - func = new ParentheticalNode(new CodeNode([], Expressions.wrap([expressions]))); + func = new Parenthetical(new Code([], Expressions.wrap([expressions]))); args = []; if ((mentionsArgs = expressions.contains(this.literalArgs)) || (expressions.contains(this.literalThis))) { meth = literal(mentionsArgs ? 'apply' : 'call'); @@ -1924,16 +1924,16 @@ if (mentionsArgs) { args.push(literal('arguments')); } - func = new ValueNode(func, [new AccessorNode(meth)]); + func = new Value(func, [new Accessor(meth)]); } - call = new CallNode(func, args); + call = new Call(func, args); return statement ? Expressions.wrap([call]) : call; }, literalArgs: function(node) { - return node instanceof LiteralNode && node.value === 'arguments'; + return node instanceof Literal && node.value === 'arguments'; }, literalThis: function(node) { - return node instanceof LiteralNode && node.value === 'this' || node instanceof CodeNode && node.bound; + return node instanceof Literal && node.value === 'this' || node instanceof Code && node.bound; } }; UTILITIES = { @@ -1949,7 +1949,7 @@ SIMPLENUM = /^-?\d+$/; IS_STRING = /^['"]/; literal = function(name) { - return new LiteralNode(name); + return new Literal(name); }; utility = function(name) { var ref; diff --git a/lib/parser.js b/lib/parser.js index 23e7cdba..d905eb4f 100755 --- a/lib/parser.js +++ b/lib/parser.js @@ -31,11 +31,11 @@ case 10:this.$ = $$[$0-1+1-1]; break; case 11:this.$ = $$[$0-1+1-1]; break; -case 12:this.$ = new yy.LiteralNode($$[$0-1+1-1]); +case 12:this.$ = new yy.Literal($$[$0-1+1-1]); break; -case 13:this.$ = new yy.LiteralNode($$[$0-1+1-1]); +case 13:this.$ = new yy.Literal($$[$0-1+1-1]); break; -case 14:this.$ = new yy.LiteralNode($$[$0-1+1-1]); +case 14:this.$ = new yy.Literal($$[$0-1+1-1]); break; case 15:this.$ = $$[$0-1+1-1]; break; @@ -71,61 +71,61 @@ case 30:this.$ = new yy.Expressions; break; case 31:this.$ = yy.Expressions.wrap([$$[$0-2+2-1]]); break; -case 32:this.$ = new yy.LiteralNode($$[$0-1+1-1]); +case 32:this.$ = new yy.Literal($$[$0-1+1-1]); break; -case 33:this.$ = new yy.LiteralNode($$[$0-1+1-1]); +case 33:this.$ = new yy.Literal($$[$0-1+1-1]); break; -case 34:this.$ = new yy.LiteralNode($$[$0-1+1-1]); +case 34:this.$ = new yy.Literal($$[$0-1+1-1]); break; case 35:this.$ = $$[$0-1+1-1]; break; -case 36:this.$ = new yy.LiteralNode($$[$0-1+1-1]); +case 36:this.$ = new yy.Literal($$[$0-1+1-1]); break; -case 37:this.$ = new yy.LiteralNode($$[$0-1+1-1]); +case 37:this.$ = new yy.Literal($$[$0-1+1-1]); break; -case 38:this.$ = new yy.LiteralNode(true); +case 38:this.$ = new yy.Literal(true); break; -case 39:this.$ = new yy.LiteralNode(false); +case 39:this.$ = new yy.Literal(false); break; -case 40:this.$ = new yy.LiteralNode(true); +case 40:this.$ = new yy.Literal(true); break; -case 41:this.$ = new yy.LiteralNode(false); +case 41:this.$ = new yy.Literal(false); break; -case 42:this.$ = new yy.LiteralNode(true); +case 42:this.$ = new yy.Literal(true); break; -case 43:this.$ = new yy.LiteralNode(false); +case 43:this.$ = new yy.Literal(false); break; -case 44:this.$ = new yy.AssignNode($$[$0-3+1-1], $$[$0-3+3-1]); +case 44:this.$ = new yy.Assign($$[$0-3+1-1], $$[$0-3+3-1]); break; -case 45:this.$ = new yy.AssignNode($$[$0-5+1-1], $$[$0-5+4-1]); +case 45:this.$ = new yy.Assign($$[$0-5+1-1], $$[$0-5+4-1]); break; -case 46:this.$ = new yy.ValueNode($$[$0-1+1-1]); +case 46:this.$ = new yy.Value($$[$0-1+1-1]); break; case 47:this.$ = $$[$0-1+1-1]; break; case 48:this.$ = $$[$0-1+1-1]; break; -case 49:this.$ = new yy.AssignNode(new yy.ValueNode($$[$0-3+1-1]), $$[$0-3+3-1], 'object'); +case 49:this.$ = new yy.Assign(new yy.Value($$[$0-3+1-1]), $$[$0-3+3-1], 'object'); break; -case 50:this.$ = new yy.AssignNode(new yy.ValueNode($$[$0-3+1-1]), $$[$0-3+3-1], 'object'); +case 50:this.$ = new yy.Assign(new yy.Value($$[$0-3+1-1]), $$[$0-3+3-1], 'object'); break; -case 51:this.$ = new yy.AssignNode(new yy.ValueNode($$[$0-5+1-1]), $$[$0-5+4-1], 'object'); +case 51:this.$ = new yy.Assign(new yy.Value($$[$0-5+1-1]), $$[$0-5+4-1], 'object'); break; -case 52:this.$ = new yy.AssignNode(new yy.ValueNode($$[$0-5+1-1]), $$[$0-5+4-1], 'object'); +case 52:this.$ = new yy.Assign(new yy.Value($$[$0-5+1-1]), $$[$0-5+4-1], 'object'); break; case 53:this.$ = $$[$0-1+1-1]; break; -case 54:this.$ = new yy.ReturnNode($$[$0-2+2-1]); +case 54:this.$ = new yy.Return($$[$0-2+2-1]); break; -case 55:this.$ = new yy.ReturnNode; +case 55:this.$ = new yy.Return; break; -case 56:this.$ = new yy.CommentNode($$[$0-1+1-1]); +case 56:this.$ = new yy.Comment($$[$0-1+1-1]); break; -case 57:this.$ = new yy.ExistenceNode($$[$0-2+1-1]); +case 57:this.$ = new yy.Existence($$[$0-2+1-1]); break; -case 58:this.$ = new yy.CodeNode($$[$0-5+2-1], $$[$0-5+5-1], $$[$0-5+4-1]); +case 58:this.$ = new yy.Code($$[$0-5+2-1], $$[$0-5+5-1], $$[$0-5+4-1]); break; -case 59:this.$ = new yy.CodeNode([], $$[$0-2+2-1], $$[$0-2+1-1]); +case 59:this.$ = new yy.Code([], $$[$0-2+2-1], $$[$0-2+1-1]); break; case 60:this.$ = 'func'; break; @@ -141,55 +141,55 @@ case 65:this.$ = [$$[$0-1+1-1]]; break; case 66:this.$ = $$[$0-3+1-1].concat([$$[$0-3+3-1]]); break; -case 67:this.$ = new yy.LiteralNode($$[$0-1+1-1]); +case 67:this.$ = new yy.Literal($$[$0-1+1-1]); break; -case 68:this.$ = new yy.ParamNode($$[$0-2+2-1], true); +case 68:this.$ = new yy.Param($$[$0-2+2-1], true); break; -case 69:this.$ = new yy.ParamNode($$[$0-4+1-1], false, true); +case 69:this.$ = new yy.Param($$[$0-4+1-1], false, true); break; -case 70:this.$ = new yy.ParamNode($$[$0-5+2-1], true, true); +case 70:this.$ = new yy.Param($$[$0-5+2-1], true, true); break; -case 71:this.$ = new yy.SplatNode($$[$0-4+1-1]); +case 71:this.$ = new yy.Splat($$[$0-4+1-1]); break; -case 72:this.$ = new yy.ValueNode($$[$0-1+1-1]); +case 72:this.$ = new yy.Value($$[$0-1+1-1]); break; case 73:this.$ = $$[$0-2+1-1].push($$[$0-2+2-1]); break; -case 74:this.$ = new yy.ValueNode($$[$0-2+1-1], [$$[$0-2+2-1]]); +case 74:this.$ = new yy.Value($$[$0-2+1-1], [$$[$0-2+2-1]]); break; case 75:this.$ = $$[$0-1+1-1]; break; case 76:this.$ = $$[$0-1+1-1]; break; -case 77:this.$ = new yy.ValueNode($$[$0-1+1-1]); +case 77:this.$ = new yy.Value($$[$0-1+1-1]); break; -case 78:this.$ = new yy.ValueNode($$[$0-1+1-1]); +case 78:this.$ = new yy.Value($$[$0-1+1-1]); break; case 79:this.$ = $$[$0-1+1-1]; break; -case 80:this.$ = new yy.ValueNode($$[$0-1+1-1]); +case 80:this.$ = new yy.Value($$[$0-1+1-1]); break; -case 81:this.$ = new yy.ValueNode($$[$0-1+1-1]); +case 81:this.$ = new yy.Value($$[$0-1+1-1]); break; -case 82:this.$ = new yy.ValueNode($$[$0-1+1-1]); +case 82:this.$ = new yy.Value($$[$0-1+1-1]); break; case 83:this.$ = $$[$0-1+1-1]; break; -case 84:this.$ = new yy.ValueNode(new yy.LiteralNode('null')); +case 84:this.$ = new yy.Value(new yy.Literal('null')); break; -case 85:this.$ = new yy.AccessorNode($$[$0-2+2-1]); +case 85:this.$ = new yy.Accessor($$[$0-2+2-1]); break; -case 86:this.$ = new yy.AccessorNode($$[$0-2+2-1], 'prototype'); +case 86:this.$ = new yy.Accessor($$[$0-2+2-1], 'prototype'); break; -case 87:this.$ = new yy.AccessorNode(new yy.LiteralNode('prototype')); +case 87:this.$ = new yy.Accessor(new yy.Literal('prototype')); break; -case 88:this.$ = new yy.AccessorNode($$[$0-2+2-1], 'soak'); +case 88:this.$ = new yy.Accessor($$[$0-2+2-1], 'soak'); break; case 89:this.$ = $$[$0-1+1-1]; break; -case 90:this.$ = new yy.SliceNode($$[$0-1+1-1]); +case 90:this.$ = new yy.Slice($$[$0-1+1-1]); break; -case 91:this.$ = new yy.IndexNode($$[$0-3+2-1]); +case 91:this.$ = new yy.Index($$[$0-3+2-1]); break; case 92:this.$ = (function () { $$[$0-2+2-1].soakNode = true; @@ -201,7 +201,7 @@ case 93:this.$ = (function () { return $$[$0-2+2-1]; }()); break; -case 94:this.$ = new yy.ObjectNode($$[$0-4+2-1]); +case 94:this.$ = new yy.ObjectLiteral($$[$0-4+2-1]); break; case 95:this.$ = []; break; @@ -213,27 +213,27 @@ case 98:this.$ = $$[$0-4+1-1].concat([$$[$0-4+4-1]]); break; case 99:this.$ = $$[$0-6+1-1].concat($$[$0-6+4-1]); break; -case 100:this.$ = new yy.ClassNode($$[$0-2+2-1]); +case 100:this.$ = new yy.Class($$[$0-2+2-1]); break; -case 101:this.$ = new yy.ClassNode($$[$0-4+2-1], $$[$0-4+4-1]); +case 101:this.$ = new yy.Class($$[$0-4+2-1], $$[$0-4+4-1]); break; -case 102:this.$ = new yy.ClassNode($$[$0-5+2-1], null, $$[$0-5+4-1]); +case 102:this.$ = new yy.Class($$[$0-5+2-1], null, $$[$0-5+4-1]); break; -case 103:this.$ = new yy.ClassNode($$[$0-7+2-1], $$[$0-7+4-1], $$[$0-7+6-1]); +case 103:this.$ = new yy.Class($$[$0-7+2-1], $$[$0-7+4-1], $$[$0-7+6-1]); break; -case 104:this.$ = new yy.ClassNode('__temp__', null, $$[$0-4+3-1]); +case 104:this.$ = new yy.Class('__temp__', null, $$[$0-4+3-1]); break; -case 105:this.$ = new yy.ClassNode('__temp__', null, new yy.Expressions); +case 105:this.$ = new yy.Class('__temp__', null, new yy.Expressions); break; -case 106:this.$ = new yy.ClassNode('__temp__', $$[$0-3+3-1], new yy.Expressions); +case 106:this.$ = new yy.Class('__temp__', $$[$0-3+3-1], new yy.Expressions); break; -case 107:this.$ = new yy.ClassNode('__temp__', $$[$0-6+3-1], $$[$0-6+5-1]); +case 107:this.$ = new yy.Class('__temp__', $$[$0-6+3-1], $$[$0-6+5-1]); break; case 108:this.$ = $$[$0-1+1-1]; break; -case 109:this.$ = new yy.AssignNode(new yy.ValueNode($$[$0-3+1-1]), $$[$0-3+3-1], 'this'); +case 109:this.$ = new yy.Assign(new yy.Value($$[$0-3+1-1]), $$[$0-3+3-1], 'this'); break; -case 110:this.$ = new yy.AssignNode(new yy.ValueNode($$[$0-5+1-1]), $$[$0-5+4-1], 'this'); +case 110:this.$ = new yy.Assign(new yy.Value($$[$0-5+1-1]), $$[$0-5+4-1], 'this'); break; case 111:this.$ = []; break; @@ -243,15 +243,15 @@ case 113:this.$ = $$[$0-3+1-1].concat($$[$0-3+3-1]); break; case 114:this.$ = $$[$0-3+2-1]; break; -case 115:this.$ = new yy.ExtendsNode($$[$0-3+1-1], $$[$0-3+3-1]); +case 115:this.$ = new yy.Extends($$[$0-3+1-1], $$[$0-3+3-1]); break; -case 116:this.$ = new yy.CallNode($$[$0-3+1-1], $$[$0-3+3-1], $$[$0-3+2-1]); +case 116:this.$ = new yy.Call($$[$0-3+1-1], $$[$0-3+3-1], $$[$0-3+2-1]); break; -case 117:this.$ = new yy.CallNode($$[$0-3+1-1], $$[$0-3+3-1], $$[$0-3+2-1]); +case 117:this.$ = new yy.Call($$[$0-3+1-1], $$[$0-3+3-1], $$[$0-3+2-1]); break; -case 118:this.$ = new yy.CallNode('super', [new yy.SplatNode(new yy.LiteralNode('arguments'))]); +case 118:this.$ = new yy.Call('super', [new yy.Splat(new yy.Literal('arguments'))]); break; -case 119:this.$ = new yy.CallNode('super', $$[$0-2+2-1]); +case 119:this.$ = new yy.Call('super', $$[$0-2+2-1]); break; case 120:this.$ = false; break; @@ -261,27 +261,27 @@ case 122:this.$ = []; break; case 123:this.$ = $$[$0-4+2-1]; break; -case 124:this.$ = new yy.ValueNode(new yy.LiteralNode('this')); +case 124:this.$ = new yy.Value(new yy.Literal('this')); break; -case 125:this.$ = new yy.ValueNode(new yy.LiteralNode('this')); +case 125:this.$ = new yy.Value(new yy.Literal('this')); break; case 126:this.$ = 'inclusive'; break; case 127:this.$ = 'exclusive'; break; -case 128:this.$ = new yy.ValueNode(new yy.LiteralNode('this'), [new yy.AccessorNode($$[$0-2+2-1])], 'this'); +case 128:this.$ = new yy.Value(new yy.Literal('this'), [new yy.Accessor($$[$0-2+2-1])], 'this'); break; -case 129:this.$ = new yy.RangeNode($$[$0-5+2-1], $$[$0-5+4-1], $$[$0-5+3-1]); +case 129:this.$ = new yy.Range($$[$0-5+2-1], $$[$0-5+4-1], $$[$0-5+3-1]); break; -case 130:this.$ = new yy.RangeNode($$[$0-5+2-1], $$[$0-5+4-1], $$[$0-5+3-1]); +case 130:this.$ = new yy.Range($$[$0-5+2-1], $$[$0-5+4-1], $$[$0-5+3-1]); break; -case 131:this.$ = new yy.RangeNode($$[$0-4+2-1], null, $$[$0-4+3-1]); +case 131:this.$ = new yy.Range($$[$0-4+2-1], null, $$[$0-4+3-1]); break; -case 132:this.$ = new yy.RangeNode(null, $$[$0-4+3-1], $$[$0-4+2-1]); +case 132:this.$ = new yy.Range(null, $$[$0-4+3-1], $$[$0-4+2-1]); break; -case 133:this.$ = new yy.ArrayNode([]); +case 133:this.$ = new yy.ArrayLiteral([]); break; -case 134:this.$ = new yy.ArrayNode($$[$0-4+2-1]); +case 134:this.$ = new yy.ArrayLiteral($$[$0-4+2-1]); break; case 135:this.$ = [$$[$0-1+1-1]]; break; @@ -301,33 +301,33 @@ case 142:this.$ = $$[$0-1+1-1]; break; case 143:this.$ = $$[$0-3+1-1] instanceof Array ? $$[$0-3+1-1].concat([$$[$0-3+3-1]]) : [$$[$0-3+1-1]].concat([$$[$0-3+3-1]]); break; -case 144:this.$ = new yy.TryNode($$[$0-2+2-1]); +case 144:this.$ = new yy.Try($$[$0-2+2-1]); break; -case 145:this.$ = new yy.TryNode($$[$0-3+2-1], $$[$0-3+3-1][0], $$[$0-3+3-1][1]); +case 145:this.$ = new yy.Try($$[$0-3+2-1], $$[$0-3+3-1][0], $$[$0-3+3-1][1]); break; -case 146:this.$ = new yy.TryNode($$[$0-4+2-1], null, null, $$[$0-4+4-1]); +case 146:this.$ = new yy.Try($$[$0-4+2-1], null, null, $$[$0-4+4-1]); break; -case 147:this.$ = new yy.TryNode($$[$0-5+2-1], $$[$0-5+3-1][0], $$[$0-5+3-1][1], $$[$0-5+5-1]); +case 147:this.$ = new yy.Try($$[$0-5+2-1], $$[$0-5+3-1][0], $$[$0-5+3-1][1], $$[$0-5+5-1]); break; case 148:this.$ = [$$[$0-3+2-1], $$[$0-3+3-1]]; break; -case 149:this.$ = new yy.ThrowNode($$[$0-2+2-1]); +case 149:this.$ = new yy.Throw($$[$0-2+2-1]); break; -case 150:this.$ = new yy.ParentheticalNode($$[$0-3+2-1]); +case 150:this.$ = new yy.Parenthetical($$[$0-3+2-1]); break; -case 151:this.$ = new yy.ParentheticalNode(new yy.LiteralNode('')); +case 151:this.$ = new yy.Parenthetical(new yy.Literal('')); break; -case 152:this.$ = new yy.WhileNode($$[$0-2+2-1]); +case 152:this.$ = new yy.While($$[$0-2+2-1]); break; -case 153:this.$ = new yy.WhileNode($$[$0-4+2-1], { +case 153:this.$ = new yy.While($$[$0-4+2-1], { guard: $$[$0-4+4-1] }); break; -case 154:this.$ = new yy.WhileNode($$[$0-2+2-1], { +case 154:this.$ = new yy.While($$[$0-2+2-1], { invert: true }); break; -case 155:this.$ = new yy.WhileNode($$[$0-4+2-1], { +case 155:this.$ = new yy.While($$[$0-4+2-1], { invert: true, guard: $$[$0-4+4-1] }); @@ -340,18 +340,18 @@ case 158:this.$ = $$[$0-2+2-1].addBody(yy.Expressions.wrap([$$[$0-2+1-1]])); break; case 159:this.$ = $$[$0-1+1-1]; break; -case 160:this.$ = new yy.WhileNode(new yy.LiteralNode('true')).addBody($$[$0-2+2-1]); +case 160:this.$ = new yy.While(new yy.Literal('true')).addBody($$[$0-2+2-1]); break; -case 161:this.$ = new yy.WhileNode(new yy.LiteralNode('true')).addBody(yy.Expressions.wrap([$$[$0-2+2-1]])); +case 161:this.$ = new yy.While(new yy.Literal('true')).addBody(yy.Expressions.wrap([$$[$0-2+2-1]])); break; -case 162:this.$ = new yy.ForNode($$[$0-2+1-1], $$[$0-2+2-1], $$[$0-2+2-1].vars[0], $$[$0-2+2-1].vars[1]); +case 162:this.$ = new yy.For($$[$0-2+1-1], $$[$0-2+2-1], $$[$0-2+2-1].vars[0], $$[$0-2+2-1].vars[1]); break; -case 163:this.$ = new yy.ForNode($$[$0-2+1-1], $$[$0-2+2-1], $$[$0-2+2-1].vars[0], $$[$0-2+2-1].vars[1]); +case 163:this.$ = new yy.For($$[$0-2+1-1], $$[$0-2+2-1], $$[$0-2+2-1].vars[0], $$[$0-2+2-1].vars[1]); break; -case 164:this.$ = new yy.ForNode($$[$0-2+2-1], $$[$0-2+1-1], $$[$0-2+1-1].vars[0], $$[$0-2+1-1].vars[1]); +case 164:this.$ = new yy.For($$[$0-2+2-1], $$[$0-2+1-1], $$[$0-2+1-1].vars[0], $$[$0-2+1-1].vars[1]); break; case 165:this.$ = { - source: new yy.ValueNode($$[$0-2+2-1]), + source: new yy.Value($$[$0-2+2-1]), vars: [] }; break; @@ -370,9 +370,9 @@ case 168:this.$ = (function () { break; case 169:this.$ = $$[$0-1+1-1]; break; -case 170:this.$ = new yy.ValueNode($$[$0-1+1-1]); +case 170:this.$ = new yy.Value($$[$0-1+1-1]); break; -case 171:this.$ = new yy.ValueNode($$[$0-1+1-1]); +case 171:this.$ = new yy.Value($$[$0-1+1-1]); break; case 172:this.$ = [$$[$0-1+1-1]]; break; @@ -415,13 +415,13 @@ case 180:this.$ = { guard: $$[$0-6+6-1] }; break; -case 181:this.$ = new yy.SwitchNode($$[$0-5+2-1], $$[$0-5+4-1]); +case 181:this.$ = new yy.Switch($$[$0-5+2-1], $$[$0-5+4-1]); break; -case 182:this.$ = new yy.SwitchNode($$[$0-7+2-1], $$[$0-7+4-1], $$[$0-7+6-1]); +case 182:this.$ = new yy.Switch($$[$0-7+2-1], $$[$0-7+4-1], $$[$0-7+6-1]); break; -case 183:this.$ = new yy.SwitchNode(null, $$[$0-4+3-1]); +case 183:this.$ = new yy.Switch(null, $$[$0-4+3-1]); break; -case 184:this.$ = new yy.SwitchNode(null, $$[$0-6+3-1], $$[$0-6+5-1]); +case 184:this.$ = new yy.Switch(null, $$[$0-6+3-1], $$[$0-6+5-1]); break; case 185:this.$ = $$[$0-1+1-1]; break; @@ -431,73 +431,73 @@ case 187:this.$ = [[$$[$0-3+2-1], $$[$0-3+3-1]]]; break; case 188:this.$ = [[$$[$0-4+2-1], $$[$0-4+3-1]]]; break; -case 189:this.$ = new yy.IfNode($$[$0-3+2-1], $$[$0-3+3-1]); +case 189:this.$ = new yy.If($$[$0-3+2-1], $$[$0-3+3-1]); break; -case 190:this.$ = new yy.IfNode($$[$0-3+2-1], $$[$0-3+3-1], { +case 190:this.$ = new yy.If($$[$0-3+2-1], $$[$0-3+3-1], { invert: true }); break; -case 191:this.$ = $$[$0-5+1-1].addElse(new yy.IfNode($$[$0-5+4-1], $$[$0-5+5-1])); +case 191:this.$ = $$[$0-5+1-1].addElse(new yy.If($$[$0-5+4-1], $$[$0-5+5-1])); break; case 192:this.$ = $$[$0-3+1-1].addElse($$[$0-3+3-1]); break; case 193:this.$ = $$[$0-1+1-1]; break; -case 194:this.$ = new yy.IfNode($$[$0-3+3-1], yy.Expressions.wrap([$$[$0-3+1-1]]), { +case 194:this.$ = new yy.If($$[$0-3+3-1], yy.Expressions.wrap([$$[$0-3+1-1]]), { statement: true }); break; -case 195:this.$ = new yy.IfNode($$[$0-3+3-1], yy.Expressions.wrap([$$[$0-3+1-1]]), { +case 195:this.$ = new yy.If($$[$0-3+3-1], yy.Expressions.wrap([$$[$0-3+1-1]]), { statement: true }); break; -case 196:this.$ = new yy.IfNode($$[$0-3+3-1], yy.Expressions.wrap([$$[$0-3+1-1]]), { +case 196:this.$ = new yy.If($$[$0-3+3-1], yy.Expressions.wrap([$$[$0-3+1-1]]), { statement: true, invert: true }); break; -case 197:this.$ = new yy.IfNode($$[$0-3+3-1], yy.Expressions.wrap([$$[$0-3+1-1]]), { +case 197:this.$ = new yy.If($$[$0-3+3-1], yy.Expressions.wrap([$$[$0-3+1-1]]), { statement: true, invert: true }); break; -case 198:this.$ = new yy.OpNode($$[$0-2+1-1], $$[$0-2+2-1]); +case 198:this.$ = new yy.Op($$[$0-2+1-1], $$[$0-2+2-1]); break; -case 199:this.$ = new yy.OpNode('-', $$[$0-2+2-1]); +case 199:this.$ = new yy.Op('-', $$[$0-2+2-1]); break; -case 200:this.$ = new yy.OpNode('+', $$[$0-2+2-1]); +case 200:this.$ = new yy.Op('+', $$[$0-2+2-1]); break; -case 201:this.$ = new yy.OpNode('--', $$[$0-2+2-1]); +case 201:this.$ = new yy.Op('--', $$[$0-2+2-1]); break; -case 202:this.$ = new yy.OpNode('++', $$[$0-2+2-1]); +case 202:this.$ = new yy.Op('++', $$[$0-2+2-1]); break; -case 203:this.$ = new yy.OpNode('--', $$[$0-2+1-1], null, true); +case 203:this.$ = new yy.Op('--', $$[$0-2+1-1], null, true); break; -case 204:this.$ = new yy.OpNode('++', $$[$0-2+1-1], null, true); +case 204:this.$ = new yy.Op('++', $$[$0-2+1-1], null, true); break; -case 205:this.$ = new yy.OpNode('?', $$[$0-3+1-1], $$[$0-3+3-1]); +case 205:this.$ = new yy.Op('?', $$[$0-3+1-1], $$[$0-3+3-1]); break; -case 206:this.$ = new yy.OpNode('+', $$[$0-3+1-1], $$[$0-3+3-1]); +case 206:this.$ = new yy.Op('+', $$[$0-3+1-1], $$[$0-3+3-1]); break; -case 207:this.$ = new yy.OpNode('-', $$[$0-3+1-1], $$[$0-3+3-1]); +case 207:this.$ = new yy.Op('-', $$[$0-3+1-1], $$[$0-3+3-1]); break; -case 208:this.$ = new yy.OpNode('==', $$[$0-3+1-1], $$[$0-3+3-1]); +case 208:this.$ = new yy.Op('==', $$[$0-3+1-1], $$[$0-3+3-1]); break; -case 209:this.$ = new yy.OpNode('!=', $$[$0-3+1-1], $$[$0-3+3-1]); +case 209:this.$ = new yy.Op('!=', $$[$0-3+1-1], $$[$0-3+3-1]); break; -case 210:this.$ = new yy.OpNode($$[$0-3+2-1], $$[$0-3+1-1], $$[$0-3+3-1]); +case 210:this.$ = new yy.Op($$[$0-3+2-1], $$[$0-3+1-1], $$[$0-3+3-1]); break; -case 211:this.$ = new yy.OpNode($$[$0-3+2-1], $$[$0-3+1-1], $$[$0-3+3-1]); +case 211:this.$ = new yy.Op($$[$0-3+2-1], $$[$0-3+1-1], $$[$0-3+3-1]); break; -case 212:this.$ = new yy.OpNode($$[$0-3+2-1], $$[$0-3+1-1], $$[$0-3+3-1]); +case 212:this.$ = new yy.Op($$[$0-3+2-1], $$[$0-3+1-1], $$[$0-3+3-1]); break; -case 213:this.$ = new yy.OpNode($$[$0-3+2-1], $$[$0-3+1-1], $$[$0-3+3-1]); +case 213:this.$ = new yy.Op($$[$0-3+2-1], $$[$0-3+1-1], $$[$0-3+3-1]); break; -case 214:this.$ = new yy.OpNode($$[$0-3+2-1], $$[$0-3+1-1], $$[$0-3+3-1]); +case 214:this.$ = new yy.Op($$[$0-3+2-1], $$[$0-3+1-1], $$[$0-3+3-1]); break; -case 215:this.$ = new yy.OpNode($$[$0-5+2-1], $$[$0-5+1-1], $$[$0-5+4-1]); +case 215:this.$ = new yy.Op($$[$0-5+2-1], $$[$0-5+1-1], $$[$0-5+4-1]); break; -case 216:this.$ = $$[$0-3+2-1].charAt(0) === '!' ? ($$[$0-3+2-1] === '!in' ? new yy.OpNode('!', new yy.InNode($$[$0-3+1-1], $$[$0-3+3-1])) : new yy.OpNode('!', new yy.ParentheticalNode(new yy.OpNode($$[$0-3+2-1].slice(1), $$[$0-3+1-1], $$[$0-3+3-1])))) : ($$[$0-3+2-1] === 'in' ? new yy.InNode($$[$0-3+1-1], $$[$0-3+3-1]) : new yy.OpNode($$[$0-3+2-1], $$[$0-3+1-1], $$[$0-3+3-1])); +case 216:this.$ = $$[$0-3+2-1].charAt(0) === '!' ? ($$[$0-3+2-1] === '!in' ? new yy.Op('!', new yy.In($$[$0-3+1-1], $$[$0-3+3-1])) : new yy.Op('!', new yy.Parenthetical(new yy.Op($$[$0-3+2-1].slice(1), $$[$0-3+1-1], $$[$0-3+3-1])))) : ($$[$0-3+2-1] === 'in' ? new yy.In($$[$0-3+1-1], $$[$0-3+3-1]) : new yy.Op($$[$0-3+2-1], $$[$0-3+1-1], $$[$0-3+3-1])); break; } }, diff --git a/src/grammar.coffee b/src/grammar.coffee index fcde7773..6eab0265 100644 --- a/src/grammar.coffee +++ b/src/grammar.coffee @@ -33,7 +33,7 @@ unwrap = /function\s*\(\)\s*\{\s*return\s*([\s\S]*);\s*\}/ o = (patternString, action, options) -> return [patternString, '$$ = $1;', options] unless action action = if match = (action + '').match(unwrap) then match[1] else "(#{action}())" - action = action.replace /\b(?:[A-Z][a-z]+Node|Expressions)\b/g, 'yy.$&' + action = action.replace(/\bnew (\w+)\b/g, 'new yy.$1').replace(/Expressions\.wrap/g, 'yy.Expressions.wrap'); [patternString, "$$ = #{action};", options] # Grammatical Rules @@ -77,9 +77,9 @@ grammar = Statement: [ o "Return" o "Throw" - o "BREAK", -> new LiteralNode $1 - o "CONTINUE", -> new LiteralNode $1 - o "DEBUGGER", -> new LiteralNode $1 + o "BREAK", -> new Literal $1 + o "CONTINUE", -> new Literal $1 + o "DEBUGGER", -> new Literal $1 ] # All the different types of expressions in our language. The basic unit of @@ -114,71 +114,71 @@ grammar = # A literal identifier, a variable name or property. Identifier: [ - o "IDENTIFIER", -> new LiteralNode $1 + o "IDENTIFIER", -> new Literal $1 ] # Alphanumerics are separated from the other **Literal** matchers because # they can also serve as keys in object literals. AlphaNumeric: [ - o "NUMBER", -> new LiteralNode $1 - o "STRING", -> new LiteralNode $1 + o "NUMBER", -> new Literal $1 + o "STRING", -> new Literal $1 ] # All of our immediate values. These can (in general), be passed straight # through and printed to JavaScript. Literal: [ o "AlphaNumeric" - o "JS", -> new LiteralNode $1 - o "REGEX", -> new LiteralNode $1 - o "TRUE", -> new LiteralNode true - o "FALSE", -> new LiteralNode false - o "YES", -> new LiteralNode true - o "NO", -> new LiteralNode false - o "ON", -> new LiteralNode true - o "OFF", -> new LiteralNode false + o "JS", -> new Literal $1 + o "REGEX", -> new Literal $1 + o "TRUE", -> new Literal true + o "FALSE", -> new Literal false + o "YES", -> new Literal true + o "NO", -> new Literal false + o "ON", -> new Literal true + o "OFF", -> new Literal false ] # Assignment of a variable, property, or index to a value. Assign: [ - o "Assignable = Expression", -> new AssignNode $1, $3 - o "Assignable = INDENT Expression OUTDENT", -> new AssignNode $1, $4 + o "Assignable = Expression", -> new Assign $1, $3 + o "Assignable = INDENT Expression OUTDENT", -> new Assign $1, $4 ] # Assignment when it happens within an object literal. The difference from # the ordinary **Assign** is that these allow numbers and strings as keys. AssignObj: [ - o "Identifier", -> new ValueNode $1 + o "Identifier", -> new Value $1 o "AlphaNumeric" o "ThisProperty" - o "Identifier : Expression", -> new AssignNode new ValueNode($1), $3, 'object' - o "AlphaNumeric : Expression", -> new AssignNode new ValueNode($1), $3, 'object' - o "Identifier : INDENT Expression OUTDENT", -> new AssignNode new ValueNode($1), $4, 'object' - o "AlphaNumeric : INDENT Expression OUTDENT", -> new AssignNode new ValueNode($1), $4, 'object' + o "Identifier : Expression", -> new Assign new Value($1), $3, 'object' + o "AlphaNumeric : Expression", -> new Assign new Value($1), $3, 'object' + o "Identifier : INDENT Expression OUTDENT", -> new Assign new Value($1), $4, 'object' + o "AlphaNumeric : INDENT Expression OUTDENT", -> new Assign new Value($1), $4, 'object' o "Comment" ] # A return statement from a function body. Return: [ - o "RETURN Expression", -> new ReturnNode $2 - o "RETURN", -> new ReturnNode + o "RETURN Expression", -> new Return $2 + o "RETURN", -> new Return ] # A block comment. Comment: [ - o "HERECOMMENT", -> new CommentNode $1 + o "HERECOMMENT", -> new Comment $1 ] # [The existential operator](http://jashkenas.github.com/coffee-script/#existence). Existence: [ - o "Expression ?", -> new ExistenceNode $1 + o "Expression ?", -> new Existence $1 ] # The **Code** node is the function literal. It's defined by an indented block # of **Expressions** preceded by a function arrow, with an optional parameter # list. Code: [ - o "PARAM_START ParamList PARAM_END FuncGlyph Block", -> new CodeNode $2, $5, $4 - o "FuncGlyph Block", -> new CodeNode [], $2, $1 + o "PARAM_START ParamList PARAM_END FuncGlyph Block", -> new Code $2, $5, $4 + o "FuncGlyph Block", -> new Code [], $2, $1 ] # CoffeeScript has two different symbols for functions. `->` is for ordinary @@ -204,64 +204,64 @@ grammar = # A single parameter in a function definition can be ordinary, or a splat # that hoovers up the remaining arguments. Param: [ - o "PARAM", -> new LiteralNode $1 - o "@ PARAM", -> new ParamNode $2, true - o "PARAM . . .", -> new ParamNode $1, false, true - o "@ PARAM . . .", -> new ParamNode $2, true, true + o "PARAM", -> new Literal $1 + o "@ PARAM", -> new Param $2, true + o "PARAM . . .", -> new Param $1, false, true + o "@ PARAM . . .", -> new Param $2, true, true ] # A splat that occurs outside of a parameter list. Splat: [ - o "Expression . . .", -> new SplatNode $1 + o "Expression . . .", -> new Splat $1 ] # Variables and properties that can be assigned to. SimpleAssignable: [ - o "Identifier", -> new ValueNode $1 + o "Identifier", -> new Value $1 o "Value Accessor", -> $1.push $2 - o "Invocation Accessor", -> new ValueNode $1, [$2] + o "Invocation Accessor", -> new Value $1, [$2] o "ThisProperty" ] # Everything that can be assigned to. Assignable: [ o "SimpleAssignable" - o "Array", -> new ValueNode $1 - o "Object", -> new ValueNode $1 + o "Array", -> new Value $1 + o "Object", -> new Value $1 ] # The types of things that can be treated as values -- assigned to, invoked # as functions, indexed into, named as a class, etc. Value: [ o "Assignable" - o "Literal", -> new ValueNode $1 - o "Parenthetical", -> new ValueNode $1 - o "Range", -> new ValueNode $1 + o "Literal", -> new Value $1 + o "Parenthetical", -> new Value $1 + o "Range", -> new Value $1 o "This" - o "NULL", -> new ValueNode new LiteralNode 'null' + o "NULL", -> new Value new Literal 'null' ] # The general group of accessors into an object, by property, by prototype # or by array index or slice. Accessor: [ - o "PROPERTY_ACCESS Identifier", -> new AccessorNode $2 - o "PROTOTYPE_ACCESS Identifier", -> new AccessorNode $2, 'prototype' - o "::", -> new AccessorNode(new LiteralNode('prototype')) - o "SOAK_ACCESS Identifier", -> new AccessorNode $2, 'soak' + o "PROPERTY_ACCESS Identifier", -> new Accessor $2 + o "PROTOTYPE_ACCESS Identifier", -> new Accessor $2, 'prototype' + o "::", -> new Accessor(new Literal('prototype')) + o "SOAK_ACCESS Identifier", -> new Accessor $2, 'soak' o "Index" - o "Slice", -> new SliceNode $1 + o "Slice", -> new Slice $1 ] # Indexing into an object or array using bracket notation. Index: [ - o "INDEX_START Expression INDEX_END", -> new IndexNode $2 + o "INDEX_START Expression INDEX_END", -> new Index $2 o "INDEX_SOAK Index", -> $2.soakNode = yes; $2 o "INDEX_PROTO Index", -> $2.proto = yes; $2 ] # In CoffeeScript, an object literal is simply a list of assignments. Object: [ - o "{ AssignList OptComma }", -> new ObjectNode $2 + o "{ AssignList OptComma }", -> new ObjectLiteral $2 ] # Assignment of properties within an object literal can be separated by @@ -277,21 +277,21 @@ grammar = # Class definitions have optional bodies of prototype property assignments, # and optional references to the superclass. Class: [ - o "CLASS SimpleAssignable", -> new ClassNode $2 - o "CLASS SimpleAssignable EXTENDS Value", -> new ClassNode $2, $4 - o "CLASS SimpleAssignable INDENT ClassBody OUTDENT", -> new ClassNode $2, null, $4 - o "CLASS SimpleAssignable EXTENDS Value INDENT ClassBody OUTDENT", -> new ClassNode $2, $4, $6 - o "CLASS INDENT ClassBody OUTDENT", -> new ClassNode '__temp__', null, $3 - o "CLASS", -> new ClassNode '__temp__', null, new Expressions - o "CLASS EXTENDS Value", -> new ClassNode '__temp__', $3, new Expressions - o "CLASS EXTENDS Value INDENT ClassBody OUTDENT", -> new ClassNode '__temp__', $3, $5 + o "CLASS SimpleAssignable", -> new Class $2 + o "CLASS SimpleAssignable EXTENDS Value", -> new Class $2, $4 + o "CLASS SimpleAssignable INDENT ClassBody OUTDENT", -> new Class $2, null, $4 + o "CLASS SimpleAssignable EXTENDS Value INDENT ClassBody OUTDENT", -> new Class $2, $4, $6 + o "CLASS INDENT ClassBody OUTDENT", -> new Class '__temp__', null, $3 + o "CLASS", -> new Class '__temp__', null, new Expressions + o "CLASS EXTENDS Value", -> new Class '__temp__', $3, new Expressions + o "CLASS EXTENDS Value INDENT ClassBody OUTDENT", -> new Class '__temp__', $3, $5 ] # Assignments that can happen directly inside a class declaration. ClassAssign: [ o "AssignObj", -> $1 - o "ThisProperty : Expression", -> new AssignNode new ValueNode($1), $3, 'this' - o "ThisProperty : INDENT Expression OUTDENT", -> new AssignNode new ValueNode($1), $4, 'this' + o "ThisProperty : Expression", -> new Assign new Value($1), $3, 'this' + o "ThisProperty : INDENT Expression OUTDENT", -> new Assign new Value($1), $4, 'this' ] # A list of assignments to a class. @@ -305,15 +305,15 @@ grammar = # Extending an object by setting its prototype chain to reference a parent # object. Extends: [ - o "SimpleAssignable EXTENDS Value", -> new ExtendsNode $1, $3 + o "SimpleAssignable EXTENDS Value", -> new Extends $1, $3 ] # Ordinary function invocation, or a chained series of calls. Invocation: [ - o "Value OptFuncExist Arguments", -> new CallNode $1, $3, $2 - o "Invocation OptFuncExist Arguments", -> new CallNode $1, $3, $2 - o "SUPER", -> new CallNode 'super', [new SplatNode(new LiteralNode('arguments'))] - o "SUPER Arguments", -> new CallNode 'super', $2 + o "Value OptFuncExist Arguments", -> new Call $1, $3, $2 + o "Invocation OptFuncExist Arguments", -> new Call $1, $3, $2 + o "SUPER", -> new Call 'super', [new Splat(new Literal('arguments'))] + o "SUPER Arguments", -> new Call 'super', $2 ] # An optional existence check on a function. @@ -330,8 +330,8 @@ grammar = # A reference to the *this* current object. This: [ - o "THIS", -> new ValueNode new LiteralNode 'this' - o "@", -> new ValueNode new LiteralNode 'this' + o "THIS", -> new Value new Literal 'this' + o "@", -> new Value new Literal 'this' ] RangeDots: [ @@ -341,25 +341,25 @@ grammar = # A reference to a property on *this*. ThisProperty: [ - o "@ Identifier", -> new ValueNode new LiteralNode('this'), [new AccessorNode($2)], 'this' + o "@ Identifier", -> new Value new Literal('this'), [new Accessor($2)], 'this' ] # The CoffeeScript range literal. Range: [ - o "[ Expression RangeDots Expression ]", -> new RangeNode $2, $4, $3 + o "[ Expression RangeDots Expression ]", -> new Range $2, $4, $3 ] # The slice literal. Slice: [ - o "INDEX_START Expression RangeDots Expression INDEX_END", -> new RangeNode $2, $4, $3 - o "INDEX_START Expression RangeDots INDEX_END", -> new RangeNode $2, null, $3 - o "INDEX_START RangeDots Expression INDEX_END", -> new RangeNode null, $3, $2 + o "INDEX_START Expression RangeDots Expression INDEX_END", -> new Range $2, $4, $3 + o "INDEX_START Expression RangeDots INDEX_END", -> new Range $2, null, $3 + o "INDEX_START RangeDots Expression INDEX_END", -> new Range null, $3, $2 ] # The array literal. Array: [ - o "[ ]", -> new ArrayNode [] - o "[ ArgList OptComma ]", -> new ArrayNode $2 + o "[ ]", -> new ArrayLiteral [] + o "[ ArgList OptComma ]", -> new ArrayLiteral $2 ] # The **ArgList** is both the list of objects passed into a function call, @@ -390,10 +390,10 @@ grammar = # The variants of *try/catch/finally* exception handling blocks. Try: [ - o "TRY Block", -> new TryNode $2 - o "TRY Block Catch", -> new TryNode $2, $3[0], $3[1] - o "TRY Block FINALLY Block", -> new TryNode $2, null, null, $4 - o "TRY Block Catch FINALLY Block", -> new TryNode $2, $3[0], $3[1], $5 + o "TRY Block", -> new Try $2 + o "TRY Block Catch", -> new Try $2, $3[0], $3[1] + o "TRY Block FINALLY Block", -> new Try $2, null, null, $4 + o "TRY Block Catch FINALLY Block", -> new Try $2, $3[0], $3[1], $5 ] # A catch clause names its error and runs a block of code. @@ -403,7 +403,7 @@ grammar = # Throw an exception object. Throw: [ - o "THROW Expression", -> new ThrowNode $2 + o "THROW Expression", -> new Throw $2 ] # Parenthetical expressions. Note that the **Parenthetical** is a **Value**, @@ -411,16 +411,16 @@ grammar = # where only values are accepted, wrapping it in parentheses will always do # the trick. Parenthetical: [ - o "( Line )", -> new ParentheticalNode $2 - o "( )", -> new ParentheticalNode new LiteralNode '' + o "( Line )", -> new Parenthetical $2 + o "( )", -> new Parenthetical new Literal '' ] # The condition portion of a while loop. WhileSource: [ - o "WHILE Expression", -> new WhileNode $2 - o "WHILE Expression WHEN Expression", -> new WhileNode $2, guard: $4 - o "UNTIL Expression", -> new WhileNode $2, invert: true - o "UNTIL Expression WHEN Expression", -> new WhileNode $2, invert: true, guard: $4 + o "WHILE Expression", -> new While $2 + o "WHILE Expression WHEN Expression", -> new While $2, guard: $4 + o "UNTIL Expression", -> new While $2, invert: true + o "UNTIL Expression WHEN Expression", -> new While $2, invert: true, guard: $4 ] # The while loop can either be normal, with a block of expressions to execute, @@ -433,21 +433,21 @@ grammar = ] Loop: [ - o "LOOP Block", -> new WhileNode(new LiteralNode 'true').addBody $2 - o "LOOP Expression", -> new WhileNode(new LiteralNode 'true').addBody Expressions.wrap [$2] + o "LOOP Block", -> new While(new Literal 'true').addBody $2 + o "LOOP Expression", -> new While(new Literal 'true').addBody Expressions.wrap [$2] ] # Array, object, and range comprehensions, at the most generic level. # Comprehensions can either be normal, with a block of expressions to execute, # or postfix, with a single expression. For: [ - o "Statement ForBody", -> new ForNode $1, $2, $2.vars[0], $2.vars[1] - o "Expression ForBody", -> new ForNode $1, $2, $2.vars[0], $2.vars[1] - o "ForBody Block", -> new ForNode $2, $1, $1.vars[0], $1.vars[1] + o "Statement ForBody", -> new For $1, $2, $2.vars[0], $2.vars[1] + o "Expression ForBody", -> new For $1, $2, $2.vars[0], $2.vars[1] + o "ForBody Block", -> new For $2, $1, $1.vars[0], $1.vars[1] ] ForBody: [ - o "FOR Range", -> source: new ValueNode($2), vars: [] + o "FOR Range", -> source: new Value($2), vars: [] o "ForStart ForSource", -> $2.raw = $1.raw; $2.vars = $1; $2 ] @@ -460,8 +460,8 @@ grammar = # enables support for pattern matching. ForValue: [ o "Identifier" - o "Array", -> new ValueNode $1 - o "Object", -> new ValueNode $1 + o "Array", -> new Value $1 + o "Object", -> new Value $1 ] # An array or range comprehension has variables for the current element and @@ -486,10 +486,10 @@ grammar = ] Switch: [ - o "SWITCH Expression INDENT Whens OUTDENT", -> new SwitchNode $2, $4 - o "SWITCH Expression INDENT Whens ELSE Block OUTDENT", -> new SwitchNode $2, $4, $6 - o "SWITCH INDENT Whens OUTDENT", -> new SwitchNode null, $3 - o "SWITCH INDENT Whens ELSE Block OUTDENT", -> new SwitchNode null, $3, $5 + o "SWITCH Expression INDENT Whens OUTDENT", -> new Switch $2, $4 + o "SWITCH Expression INDENT Whens ELSE Block OUTDENT", -> new Switch $2, $4, $6 + o "SWITCH INDENT Whens OUTDENT", -> new Switch null, $3 + o "SWITCH INDENT Whens ELSE Block OUTDENT", -> new Switch null, $3, $5 ] Whens: [ @@ -507,9 +507,9 @@ grammar = # if-related rules are broken up along these lines in order to avoid # ambiguity. IfBlock: [ - o "IF Expression Block", -> new IfNode $2, $3 - o "UNLESS Expression Block", -> new IfNode $2, $3, invert: true - o "IfBlock ELSE IF Expression Block", -> $1.addElse new IfNode $4, $5 + o "IF Expression Block", -> new If $2, $3 + o "UNLESS Expression Block", -> new If $2, $3, invert: true + o "IfBlock ELSE IF Expression Block", -> $1.addElse new If $4, $5 o "IfBlock ELSE Block", -> $1.addElse $3 ] @@ -517,10 +517,10 @@ grammar = # *if* and *unless*. If: [ o "IfBlock" - o "Statement POST_IF Expression", -> new IfNode $3, Expressions.wrap([$1]), statement: true - o "Expression POST_IF Expression", -> new IfNode $3, Expressions.wrap([$1]), statement: true - o "Statement POST_UNLESS Expression", -> new IfNode $3, Expressions.wrap([$1]), statement: true, invert: true - o "Expression POST_UNLESS Expression", -> new IfNode $3, Expressions.wrap([$1]), statement: true, invert: true + o "Statement POST_IF Expression", -> new If $3, Expressions.wrap([$1]), statement: true + o "Expression POST_IF Expression", -> new If $3, Expressions.wrap([$1]), statement: true + o "Statement POST_UNLESS Expression", -> new If $3, Expressions.wrap([$1]), statement: true, invert: true + o "Expression POST_UNLESS Expression", -> new If $3, Expressions.wrap([$1]), statement: true, invert: true ] # Arithmetic and logical operators, working on one or more operands. @@ -530,36 +530,36 @@ grammar = # -type rule, but in order to make the precedence binding possible, separate # rules are necessary. Operation: [ - o "UNARY Expression", -> new OpNode $1, $2 - o("- Expression", (-> new OpNode('-', $2)), {prec: 'UNARY'}) - o("+ Expression", (-> new OpNode('+', $2)), {prec: 'UNARY'}) + o "UNARY Expression", -> new Op $1, $2 + o("- Expression", (-> new Op('-', $2)), {prec: 'UNARY'}) + o("+ Expression", (-> new Op('+', $2)), {prec: 'UNARY'}) - o "-- Expression", -> new OpNode '--', $2 - o "++ Expression", -> new OpNode '++', $2 - o "Expression --", -> new OpNode '--', $1, null, true - o "Expression ++", -> new OpNode '++', $1, null, true + o "-- Expression", -> new Op '--', $2 + o "++ Expression", -> new Op '++', $2 + o "Expression --", -> new Op '--', $1, null, true + o "Expression ++", -> new Op '++', $1, null, true - o "Expression ? Expression", -> new OpNode '?', $1, $3 - o "Expression + Expression", -> new OpNode '+', $1, $3 - o "Expression - Expression", -> new OpNode '-', $1, $3 - o "Expression == Expression", -> new OpNode '==', $1, $3 - o "Expression != Expression", -> new OpNode '!=', $1, $3 + o "Expression ? Expression", -> new Op '?', $1, $3 + o "Expression + Expression", -> new Op '+', $1, $3 + o "Expression - Expression", -> new Op '-', $1, $3 + o "Expression == Expression", -> new Op '==', $1, $3 + o "Expression != Expression", -> new Op '!=', $1, $3 - o "Expression MATH Expression", -> new OpNode $2, $1, $3 - o "Expression SHIFT Expression", -> new OpNode $2, $1, $3 - o "Expression COMPARE Expression", -> new OpNode $2, $1, $3 - o "Expression LOGIC Expression", -> new OpNode $2, $1, $3 - o "Value COMPOUND_ASSIGN Expression", -> new OpNode $2, $1, $3 - o "Value COMPOUND_ASSIGN INDENT Expression OUTDENT", -> new OpNode $2, $1, $4 + o "Expression MATH Expression", -> new Op $2, $1, $3 + o "Expression SHIFT Expression", -> new Op $2, $1, $3 + o "Expression COMPARE Expression", -> new Op $2, $1, $3 + o "Expression LOGIC Expression", -> new Op $2, $1, $3 + o "Value COMPOUND_ASSIGN Expression", -> new Op $2, $1, $3 + o "Value COMPOUND_ASSIGN INDENT Expression OUTDENT", -> new Op $2, $1, $4 o "Expression RELATION Expression", -> if $2.charAt(0) is '!' if $2 is '!in' - new OpNode '!', new InNode $1, $3 + new Op '!', new In $1, $3 else - new OpNode '!', new ParentheticalNode new OpNode $2[1..], $1, $3 + new Op '!', new Parenthetical new Op $2[1..], $1, $3 else - if $2 is 'in' then new InNode $1, $3 else new OpNode $2, $1, $3 + if $2 is 'in' then new In $1, $3 else new Op $2, $1, $3 ] diff --git a/src/helpers.coffee b/src/helpers.coffee index 272a8c11..4d201deb 100644 --- a/src/helpers.coffee +++ b/src/helpers.coffee @@ -38,7 +38,7 @@ exports.count = (string, letter) -> num # Merge objects, returning a fresh copy with attributes from both sides. -# Used every time `BaseNode#compile` is called, to allow properties in the +# Used every time `Base#compile` is called, to allow properties in the # options hash to propagate down the tree without polluting other branches. exports.merge = (options, overrides) -> extend (extend {}, options), overrides diff --git a/src/nodes.coffee b/src/nodes.coffee index 66476ae7..cc30d327 100644 --- a/src/nodes.coffee +++ b/src/nodes.coffee @@ -13,9 +13,9 @@ YES = -> yes NO = -> no THIS = -> this -#### BaseNode +#### Base -# The **BaseNode** is the abstract base class for all nodes in the syntax tree. +# The **Base** is the abstract base class for all nodes in the syntax tree. # Each subclass implements the `compileNode` method, which performs the # code generation for that node. To compile a node to JavaScript, # call `compile` on it, which wraps `compileNode` in some generic extra smarts, @@ -24,7 +24,7 @@ THIS = -> this # the environment from higher in the tree (such as if a returned value is # being requested by the surrounding function), information about the current # scope, and indentation level. -exports.BaseNode = class BaseNode +exports.Base = class Base constructor: -> @tags = {} @@ -44,7 +44,7 @@ exports.BaseNode = class BaseNode @tab = o.indent top = if @topSensitive() then @options.top else del @options, 'top' closure = @isStatement(o) and not @isPureStatement() and not top and - not @options.asStatement and this not instanceof CommentNode and + not @options.asStatement and this not instanceof Comment and not @containsPureStatement() code = if closure then @compileClosure(@options) else @compileNode(@options) code @@ -54,7 +54,7 @@ exports.BaseNode = class BaseNode compileClosure: (o) -> @tab = o.indent o.sharedScope = o.scope - ClosureNode.wrap(this).compile o + Closure.wrap(this).compile o # If the code generation wishes to use the result of a complex expression # in multiple places, ensure that the expression is only ever evaluated once, @@ -64,7 +64,7 @@ exports.BaseNode = class BaseNode [this, this] else reference = literal o.scope.freeVariable 'ref' - compiled = new AssignNode reference, this + compiled = new Assign reference, this [compiled, reference] (pair[i] = node.compile o) for node, i in pair if options?.precompile pair @@ -78,9 +78,9 @@ exports.BaseNode = class BaseNode # Construct a node that returns the current node's result. # Note that this is overridden for smarter behavior for - # many statement nodes (eg IfNode, ForNode)... + # many statement nodes (eg If, For)... makeReturn: -> - new ReturnNode this + new Return this # Does this node, or any of its children, contain a node of a certain kind? # Recursively traverses down the *children* of the nodes, yielding to a block @@ -128,8 +128,8 @@ exports.BaseNode = class BaseNode traverseChildren: (crossScope, func) -> @eachChild (child) -> return false if func(child) is false - if child instanceof BaseNode and - (crossScope or child not instanceof CodeNode) + if child instanceof Base and + (crossScope or child not instanceof Code) child.traverseChildren crossScope, func # Default implementations of the common node properties and methods. Nodes @@ -147,7 +147,7 @@ exports.BaseNode = class BaseNode # The expressions body is the list of expressions that forms the body of an # indented block of code -- the implementation of a function, a clause in an # `if`, `switch`, or `try`, and so on... -exports.Expressions = class Expressions extends BaseNode +exports.Expressions = class Expressions extends Base children: ['expressions'] isStatement: YES @@ -179,8 +179,8 @@ exports.Expressions = class Expressions extends BaseNode # ensures that the final expression is returned. makeReturn: -> end = @expressions[idx = @expressions.length - 1] - end = @expressions[idx -= 1] if end instanceof CommentNode - if end and end not instanceof ReturnNode + end = @expressions[idx -= 1] if end instanceof Comment + if end and end not instanceof Return @expressions[idx] = end.makeReturn() this @@ -231,12 +231,12 @@ Expressions.wrap = (nodes) -> return nodes[0] if nodes.length is 1 and nodes[0] instanceof Expressions new Expressions(nodes) -#### LiteralNode +#### Literal # Literals are static values that can be passed through directly into # JavaScript without translation, such as: strings, numbers, # `true`, `false`, `null`... -exports.LiteralNode = class LiteralNode extends BaseNode +exports.Literal = class Literal extends Base constructor: (@value) -> super() @@ -248,7 +248,7 @@ exports.LiteralNode = class LiteralNode extends BaseNode # meaning when wrapped in a closure. isStatement: -> @value in ['break', 'continue', 'debugger'] - isPureStatement: LiteralNode::isStatement + isPureStatement: Literal::isStatement isComplex: NO @@ -263,11 +263,11 @@ exports.LiteralNode = class LiteralNode extends BaseNode toString: -> ' "' + @value + '"' -#### ReturnNode +#### Return # A `return` is a *pureStatement* -- wrapping it in a closure wouldn't # make sense. -exports.ReturnNode = class ReturnNode extends BaseNode +exports.Return = class Return extends Base isStatement: YES isPureStatement: YES @@ -280,7 +280,7 @@ exports.ReturnNode = class ReturnNode extends BaseNode compile: (o) -> expr = @expression?.makeReturn() - return expr.compile o if expr and (expr not instanceof ReturnNode) + return expr.compile o if expr and (expr not instanceof Return) super o compileNode: (o) -> @@ -290,15 +290,15 @@ exports.ReturnNode = class ReturnNode extends BaseNode expr = ' ' + @expression.compile(o) "#{@tab}return#{expr};" -#### ValueNode +#### Value # A value, variable or literal or parenthesized, indexed or dotted into, # or vanilla. -exports.ValueNode = class ValueNode extends BaseNode +exports.Value = class Value extends Base children: ['base', 'properties'] - # A **ValueNode** has a base and a list of property accesses. + # A **Value** has a base and a list of property accesses. constructor: (@base, @properties, tag) -> super() @properties or= [] @@ -315,13 +315,13 @@ exports.ValueNode = class ValueNode extends BaseNode # Some boolean checks for the benefit of other nodes. isArray: -> - @base instanceof ArrayNode and not @properties.length + @base instanceof ArrayLiteral and not @properties.length isObject: -> - @base instanceof ObjectNode and not @properties.length + @base instanceof ObjectLiteral and not @properties.length isSplice: -> - last(@properties) instanceof SliceNode + last(@properties) instanceof Slice isComplex: -> @base.isComplex() or @hasProperties() @@ -340,7 +340,7 @@ exports.ValueNode = class ValueNode extends BaseNode @base.isStatement(o) and not @properties.length isNumber: -> - @base instanceof LiteralNode and NUMBER.test @base.value + @base instanceof Literal and NUMBER.test @base.value # A reference has base part (`this` value) and name part. # We cache them separately for compiling complex expressions. @@ -350,16 +350,16 @@ exports.ValueNode = class ValueNode extends BaseNode if not @base.isComplex() and @properties.length < 2 and not name?.isComplex() return [this, this] # `a` `a.b` - base = new ValueNode @base, @properties.slice 0, -1 + base = new Value @base, @properties.slice 0, -1 if base.isComplex() # `a().b` bref = literal o.scope.freeVariable 'base' - base = new ValueNode new ParentheticalNode new AssignNode bref, base + base = new Value new Parenthetical new Assign bref, base return [base, bref] unless name # `a()` if name.isComplex() # `a[b()]` nref = literal o.scope.freeVariable 'name' - name = new IndexNode new AssignNode nref, name.index - nref = new IndexNode nref - [base.push(name), new ValueNode(bref or base.base, [nref or name])] + name = new Index new Assign nref, name.index + nref = new Index nref + [base.push(name), new Value(bref or base.base, [nref or name])] # Override compile to unwrap the value when possible. compile: (o) -> @@ -374,47 +374,47 @@ exports.ValueNode = class ValueNode extends BaseNode props = @properties @base.parenthetical = yes if @parenthetical and not props.length code = @base.compile o - if props[0] instanceof AccessorNode and @isNumber() or - o.top and @base instanceof ObjectNode + if props[0] instanceof Accessor and @isNumber() or + o.top and @base instanceof ObjectLiteral code = "(#{code})" (code += prop.compile o) for prop in props return code - # Unfold a soak into an `IfNode`: `a?.b` -> `a.b if a?` + # Unfold a soak into an `If`: `a?.b` -> `a.b if a?` unfoldSoak: (o) -> if @base.soakNode Array::push.apply @base.body.properties, @properties return @base for prop, i in @properties when prop.soakNode prop.soakNode = off - fst = new ValueNode @base, @properties.slice 0, i - snd = new ValueNode @base, @properties.slice i + fst = new Value @base, @properties.slice 0, i + snd = new Value @base, @properties.slice i if fst.isComplex() ref = literal o.scope.freeVariable 'ref' - fst = new ParentheticalNode new AssignNode ref, fst + fst = new Parenthetical new Assign ref, fst snd.base = ref - ifn = new IfNode new ExistenceNode(fst), snd, operation: yes + ifn = new If new Existence(fst), snd, operation: yes ifn.soakNode = on return ifn null - # Unfold a node's child if soak, then tuck the node under created `IfNode` + # Unfold a node's child if soak, then tuck the node under created `If` @unfoldSoak: (o, parent, name) -> node = parent[name] - if node instanceof IfNode and node.soakNode + if node instanceof If and node.soakNode ifnode = node - else if node instanceof ValueNode + else if node instanceof Value ifnode = node.unfoldSoak o return unless ifnode parent[name] = ifnode.body - ifnode.body = new ValueNode parent + ifnode.body = new Value parent ifnode -#### CommentNode +#### Comment # CoffeeScript passes through block comments as JavaScript block comments # at the same position. -exports.CommentNode = class CommentNode extends BaseNode +exports.Comment = class Comment extends Base isStatement: YES @@ -426,11 +426,11 @@ exports.CommentNode = class CommentNode extends BaseNode compileNode: (o) -> @tab + '/*' + @comment.replace(/\n/g, '\n' + @tab) + '*/' -#### CallNode +#### Call # Node for a function invocation. Takes care of converting `super()` calls into # calls against the prototype's function of the same name. -exports.CallNode = class CallNode extends BaseNode +exports.Call = class Call extends Base children: ['variable', 'args'] @@ -442,7 +442,7 @@ exports.CallNode = class CallNode extends BaseNode @args or= [] compileSplatArguments: (o) -> - SplatNode.compileSplattedArray @args, o + Splat.compileSplattedArray @args, o # Tag this invocation as creating a new instance. newInstance: -> @@ -468,20 +468,20 @@ exports.CallNode = class CallNode extends BaseNode call = this list = [] loop - if call.variable instanceof CallNode + if call.variable instanceof Call list.push call call = call.variable continue - break unless call.variable instanceof ValueNode + break unless call.variable instanceof Value list.push call - break unless (call = call.variable.base) instanceof CallNode + break unless (call = call.variable.base) instanceof Call for call in list.reverse() if node - if call.variable instanceof CallNode + if call.variable instanceof Call call.variable = node else call.variable.base = node - node = ValueNode.unfoldSoak o, call, 'variable' + node = Value.unfoldSoak o, call, 'variable' node # Compile a vanilla function call. @@ -489,17 +489,17 @@ exports.CallNode = class CallNode extends BaseNode return node.compile o if node = @unfoldSoak o if @exist if val = @variable - val = new ValueNode val unless val instanceof ValueNode + val = new Value val unless val instanceof Value [left, rite] = val.cacheReference o - rite = new CallNode rite, @args + rite = new Call rite, @args else left = literal @superReference o - rite = new CallNode new ValueNode(left), @args + rite = new Call new Value(left), @args rite.isNew = @isNew left = "typeof #{ left.compile o } !== \"function\"" rite = rite.compile o return "(#{left} ? undefined : #{rite})" - for arg in @args when arg instanceof SplatNode + for arg in @args when arg instanceof Splat return @compileSplat o args = ((arg.parenthetical = on) and arg.compile o for arg in @args).join ', ' if @isSuper @@ -520,7 +520,7 @@ exports.CallNode = class CallNode extends BaseNode splatargs = @compileSplatArguments o return "#{ @superReference o }.apply(this, #{splatargs})" if @isSuper unless @isNew - base = new ValueNode base unless (base = @variable) instanceof ValueNode + base = new Value base unless (base = @variable) instanceof Value if (name = base.properties.pop()) and base.isComplex() ref = o.scope.freeVariable 'this' fun = "(#{ref} = #{ base.compile o })#{ name.compile o }" @@ -529,7 +529,7 @@ exports.CallNode = class CallNode extends BaseNode fun += name.compile o if name return "#{fun}.apply(#{ref}, #{splatargs})" call = 'call(this)' - argvar = (node) -> node instanceof LiteralNode and node.value is 'arguments' + argvar = (node) -> node instanceof Literal and node.value is 'arguments' for arg in @args when arg.contains argvar call = 'apply(this, arguments)' break @@ -544,12 +544,12 @@ exports.CallNode = class CallNode extends BaseNode #{@tab}}).#{call} """ -#### ExtendsNode +#### Extends # Node to extend an object's prototype with an ancestor object. # After `goog.inherits` from the # [Closure Library](http://closure-library.googlecode.com/svn/docs/closureGoogBase.js.html). -exports.ExtendsNode = class ExtendsNode extends BaseNode +exports.Extends = class Extends extends Base children: ['child', 'parent'] @@ -558,14 +558,14 @@ exports.ExtendsNode = class ExtendsNode extends BaseNode # Hooks one constructor into another's prototype chain. compileNode: (o) -> - ref = new ValueNode literal utility 'extends' - (new CallNode ref, [@child, @parent]).compile o + ref = new Value literal utility 'extends' + (new Call ref, [@child, @parent]).compile o -#### AccessorNode +#### Accessor # A `.` accessor into a property of a value, or the `::` shorthand for # an accessor into the object's prototype. -exports.AccessorNode = class AccessorNode extends BaseNode +exports.Accessor = class Accessor extends Base children: ['name'] @@ -581,10 +581,10 @@ exports.AccessorNode = class AccessorNode extends BaseNode isComplex: NO -#### IndexNode +#### Index # A `[ ... ]` indexed accessor into an array or object. -exports.IndexNode = class IndexNode extends BaseNode +exports.Index = class Index extends Base children: ['index'] @@ -598,12 +598,12 @@ exports.IndexNode = class IndexNode extends BaseNode isComplex: -> @index.isComplex() -#### RangeNode +#### Range # A range literal. Ranges can be used to extract portions (slices) of arrays, # to specify a range for comprehensions, or as a value, to be expanded into the # corresponding array of integers at runtime. -exports.RangeNode = class RangeNode extends BaseNode +exports.Range = class Range extends Base children: ['from', 'to'] @@ -669,12 +669,12 @@ exports.RangeNode = class RangeNode extends BaseNode post = "{ #{result}.push(#{i}); }\n#{idt}return #{result};\n#{o.indent}" "(function() {#{pre}\n#{idt}for (#{body})#{post}}).call(this)" -#### SliceNode +#### Slice # An array slice literal. Unlike JavaScript's `Array#slice`, the second parameter # specifies the index of the end of the slice, just as the first parameter # is the index of the beginning. -exports.SliceNode = class SliceNode extends BaseNode +exports.Slice = class Slice extends Base children: ['range'] @@ -688,10 +688,10 @@ exports.SliceNode = class SliceNode extends BaseNode to = ', ' + to if to ".slice(#{from}#{to})" -#### ObjectNode +#### ObjectLiteral # An object literal, nothing fancy. -exports.ObjectNode = class ObjectNode extends BaseNode +exports.ObjectLiteral = class ObjectLiteral extends Base children: ['properties'] @@ -704,26 +704,26 @@ exports.ObjectNode = class ObjectNode extends BaseNode compileNode: (o) -> top = del o, 'top' o.indent = @idt 1 - nonComments = prop for prop in @properties when (prop not instanceof CommentNode) + nonComments = prop for prop in @properties when (prop not instanceof Comment) lastNoncom = last nonComments props = for prop, i in @properties join = ",\n" - join = "\n" if (prop is lastNoncom) or (prop instanceof CommentNode) + join = "\n" if (prop is lastNoncom) or (prop instanceof Comment) join = '' if i is @properties.length - 1 - indent = if prop instanceof CommentNode then '' else @idt 1 - if prop instanceof ValueNode and prop.tags.this - prop = new AssignNode prop.properties[0].name, prop, 'object' - else if prop not instanceof AssignNode and prop not instanceof CommentNode - prop = new AssignNode prop, prop, 'object' + indent = if prop instanceof Comment then '' else @idt 1 + if prop instanceof Value and prop.tags.this + prop = new Assign prop.properties[0].name, prop, 'object' + else if prop not instanceof Assign and prop not instanceof Comment + prop = new Assign prop, prop, 'object' indent + prop.compile(o) + join props = props.join('') obj = '{' + (if props then '\n' + props + '\n' + @idt() else '') + '}' if top then "(#{obj})" else obj -#### ArrayNode +#### ArrayLiteral # An array literal. -exports.ArrayNode = class ArrayNode extends BaseNode +exports.ArrayLiteral = class ArrayLiteral extends Base children: ['objects'] @@ -732,16 +732,16 @@ exports.ArrayNode = class ArrayNode extends BaseNode @objects or= [] compileSplatLiteral: (o) -> - SplatNode.compileSplattedArray @objects, o + Splat.compileSplattedArray @objects, o compileNode: (o) -> o.indent = @idt 1 objects = [] for obj, i in @objects code = obj.compile(o) - if obj instanceof SplatNode + if obj instanceof Splat return @compileSplatLiteral o - else if obj instanceof CommentNode + else if obj instanceof Comment objects.push "\n#{code}\n#{o.indent}" else if i is @objects.length - 1 objects.push code @@ -753,15 +753,15 @@ exports.ArrayNode = class ArrayNode extends BaseNode else "[#{objects}]" -#### ClassNode +#### Class # The CoffeeScript class definition. -exports.ClassNode = class ClassNode extends BaseNode +exports.Class = class Class extends Base children: ['variable', 'parent', 'properties'] isStatement: YES - # Initialize a **ClassNode** with its name, an optional superclass, and a + # Initialize a **Class** with its name, an optional superclass, and a # list of prototype property assignments. constructor: (variable, @parent, @properties) -> super() @@ -779,7 +779,7 @@ exports.ClassNode = class ClassNode extends BaseNode compileNode: (o) -> {variable} = this variable = literal o.scope.freeVariable 'ctor' if variable.value is '__temp__' - extension = @parent and new ExtendsNode variable, @parent + extension = @parent and new Extends variable, @parent props = new Expressions o.top = true me = null @@ -787,29 +787,29 @@ exports.ClassNode = class ClassNode extends BaseNode constScope = null if @parent - applied = new ValueNode(@parent, [new AccessorNode(literal('apply'))]) - constructor = new CodeNode([], new Expressions([ - new CallNode(applied, [literal('this'), literal('arguments')]) + applied = new Value(@parent, [new Accessor(literal('apply'))]) + constructor = new Code([], new Expressions([ + new Call(applied, [literal('this'), literal('arguments')]) ])) else - constructor = new CodeNode + constructor = new Code for prop in @properties [pvar, func] = [prop.variable, prop.value] if pvar and pvar.base.value is 'constructor' - if func not instanceof CodeNode + if func not instanceof Code [func, ref] = func.compileReference o props.push func if func isnt ref - apply = new CallNode(new ValueNode(ref, [new AccessorNode literal 'apply']), [literal('this'), literal('arguments')]) - func = new CodeNode [], new Expressions([apply]) + apply = new Call(new Value(ref, [new Accessor literal 'apply']), [literal('this'), literal('arguments')]) + func = new Code [], new Expressions([apply]) throw new Error "cannot define a constructor as a bound function." if func.bound func.name = className - func.body.push new ReturnNode literal 'this' - variable = new ValueNode variable + func.body.push new Return literal 'this' + variable = new Value variable variable.namespaced = include func.name, '.' constructor = func continue - if func instanceof CodeNode and func.bound + if func instanceof Code and func.bound if prop.context is 'this' func.context = className else @@ -817,27 +817,27 @@ exports.ClassNode = class ClassNode extends BaseNode constScope or= new Scope(o.scope, constructor.body, constructor) me or= constScope.freeVariable 'this' pname = pvar.compile(o) - constructor.body.push new ReturnNode literal 'this' if constructor.body.empty() + constructor.body.push new Return literal 'this' if constructor.body.empty() constructor.body.unshift literal "this.#{pname} = function(){ return #{className}.prototype.#{pname}.apply(#{me}, arguments); }" if pvar - access = if prop.context is 'this' then pvar.base.properties[0] else new AccessorNode(pvar, 'prototype') - val = new ValueNode variable, [access] - prop = new AssignNode(val, func) + access = if prop.context is 'this' then pvar.base.properties[0] else new Accessor(pvar, 'prototype') + val = new Value variable, [access] + prop = new Assign(val, func) props.push prop constructor.className = className.match /[\w\d\$_]+$/ constructor.body.unshift literal "#{me} = this" if me - construct = @idt() + new AssignNode(variable, constructor).compile(merge o, sharedScope: constScope) + ';' + construct = @idt() + new Assign(variable, constructor).compile(merge o, sharedScope: constScope) + ';' props = if !props.empty() then '\n' + props.compile(o) else '' extension = if extension then '\n' + @idt() + extension.compile(o) + ';' else '' - returns = if @returns then '\n' + new ReturnNode(variable).compile(o) else '' + returns = if @returns then '\n' + new Return(variable).compile(o) else '' construct + extension + props + returns -#### AssignNode +#### Assign -# The **AssignNode** is used to assign a local variable to value, or to set the +# The **Assign** is used to assign a local variable to value, or to set the # property of an object -- including within object literals. -exports.AssignNode = class AssignNode extends BaseNode +exports.Assign = class Assign extends Base # Matchers for detecting class/method names METHOD_DEF: /^(?:(\S+)\.prototype\.)?([$A-Za-z_][$\w]*)$/ @@ -850,7 +850,7 @@ exports.AssignNode = class AssignNode extends BaseNode topSensitive: YES isValue: -> - @variable instanceof ValueNode + @variable instanceof Value # Compile an assignment, delegating to `compilePatternMatch` or # `compileSplice` if appropriate. Keep track of the name of the base object @@ -860,11 +860,11 @@ exports.AssignNode = class AssignNode extends BaseNode if isValue = @isValue() return @compilePatternMatch(o) if @variable.isArray() or @variable.isObject() return @compileSplice(o) if @variable.isSplice() - return node.compile o if node = ValueNode.unfoldSoak o, this, 'variable' + return node.compile o if node = Value.unfoldSoak o, this, 'variable' top = del o, 'top' stmt = del o, 'asStatement' name = @variable.compile(o) - if @value instanceof CodeNode and match = @METHOD_DEF.exec name + if @value instanceof Code and match = @METHOD_DEF.exec name @value.name = match[2] @value.klass = match[1] val = @value.compile o @@ -879,22 +879,22 @@ exports.AssignNode = class AssignNode extends BaseNode # See the [ECMAScript Harmony Wiki](http://wiki.ecmascript.org/doku.php?id=harmony:destructuring) # for details. compilePatternMatch: (o) -> - if (value = @value).isStatement o then value = ClosureNode.wrap value + if (value = @value).isStatement o then value = Closure.wrap value {objects} = @variable.base return value.compile o unless olength = objects.length isObject = @variable.isObject() - if o.top and olength is 1 and (obj = objects[0]) not instanceof SplatNode + if o.top and olength is 1 and (obj = objects[0]) not instanceof Splat # Unroll simplest cases: `{v} = x` -> `v = x.v` - if obj instanceof AssignNode + if obj instanceof Assign {variable: {base: idx}, value: obj} = obj else idx = if isObject if obj.tags.this then obj.properties[0].name else obj else literal 0 - value = new ValueNode value unless value instanceof ValueNode - accessClass = if IDENTIFIER.test idx.value then AccessorNode else IndexNode + value = new Value value unless value instanceof Value + accessClass = if IDENTIFIER.test idx.value then Accessor else Index value.properties.push new accessClass idx - return new AssignNode(obj, value).compile o + return new Assign(obj, value).compile o top = del o, 'top' otop = merge o, top: yes valVar = o.scope.freeVariable 'ref' @@ -904,22 +904,22 @@ exports.AssignNode = class AssignNode extends BaseNode # A regular array pattern-match. idx = i if isObject - if obj instanceof AssignNode + if obj instanceof Assign # A regular object pattern-match. [obj, idx] = [obj.value, obj.variable.base] else # A shorthand `{a, b, @c} = val` pattern-match. idx = if obj.tags.this then obj.properties[0].name else obj - unless obj instanceof ValueNode or obj instanceof SplatNode + unless obj instanceof Value or obj instanceof Splat throw new Error 'pattern matching must use only identifiers on the left-hand side.' - accessClass = if isObject and IDENTIFIER.test(idx.value) then AccessorNode else IndexNode - if not splat and obj instanceof SplatNode + accessClass = if isObject and IDENTIFIER.test(idx.value) then Accessor else Index + if not splat and obj instanceof Splat val = literal obj.compileValue o, valVar, i, olength - i - 1 splat = true else idx = literal(if splat then "#{valVar}.length - #{olength - idx}" else idx) if typeof idx isnt 'object' - val = new ValueNode literal(valVar), [new accessClass idx] - assigns.push new AssignNode(obj, val).compile otop + val = new Value literal(valVar), [new accessClass idx] + assigns.push new Assign(obj, val).compile otop assigns.push valVar unless top code = assigns.join ', ' if top or @parenthetical then code else "(#{code})" @@ -936,12 +936,12 @@ exports.AssignNode = class AssignNode extends BaseNode val = @value.compile(o) "([].splice.apply(#{name}, [#{from}, #{to}].concat(#{ref} = #{val})), #{ref})" -#### CodeNode +#### Code # A function definition. This is the only node that creates a new Scope. -# When for the purposes of walking the contents of a function body, the CodeNode +# When for the purposes of walking the contents of a function body, the Code # has no *children* -- they're within the inner scope. -exports.CodeNode = class CodeNode extends BaseNode +exports.Code = class Code extends Base children: ['params', 'body'] @@ -971,16 +971,16 @@ exports.CodeNode = class CodeNode extends BaseNode for param, i in @params if splat if param.attach - param.assign = new AssignNode new ValueNode literal('this'), [new AccessorNode param.value] + param.assign = new Assign new Value literal('this'), [new Accessor param.value] @body.expressions.splice splat.index + 1, 0, param.assign splat.trailings.push param else if param.attach {value} = param [param, param.splat] = [literal(o.scope.freeVariable 'arg'), param.splat] - @body.unshift new AssignNode new ValueNode(literal('this'), [new AccessorNode value]), param + @body.unshift new Assign new Value(literal('this'), [new Accessor value]), param if param.splat - splat = new SplatNode param.value + splat = new Splat param.value splat.index = i splat.trailings = [] splat.arglength = @params.length @@ -1006,12 +1006,12 @@ exports.CodeNode = class CodeNode extends BaseNode # unless crossScope is true traverseChildren: (crossScope, func) -> super(crossScope, func) if crossScope -#### ParamNode +#### Param # A parameter in a function definition. Beyond a typical Javascript parameter, # these parameters can also attach themselves to the context of the function, # as well as be a splat, gathering up a group of parameters into an array. -exports.ParamNode = class ParamNode extends BaseNode +exports.Param = class Param extends Base children: ['name'] @@ -1028,11 +1028,11 @@ exports.ParamNode = class ParamNode extends BaseNode name += '...' if @splat literal(name).toString() -#### SplatNode +#### Splat # A splat, either as a parameter to a function, an argument to a call, # or as part of a destructuring assignment. -exports.SplatNode = class SplatNode extends BaseNode +exports.Splat = class Splat extends Base children: ['name'] @@ -1079,7 +1079,7 @@ exports.SplatNode = class SplatNode extends BaseNode for arg, i in list code = arg.compile o prev = args[end] - if arg not instanceof SplatNode + if arg not instanceof Splat if prev and starts(prev, '[') and ends(prev, ']') args[end] = "#{prev.slice 0, -1}, #{code}]" continue @@ -1090,12 +1090,12 @@ exports.SplatNode = class SplatNode extends BaseNode args[++end] = if i is 0 then code else ".concat(#{code})" args.join '' -#### WhileNode +#### While # A while loop, the only sort of low-level loop exposed by CoffeeScript. From # it, all other loops can be manufactured. Useful in cases where you need more # flexibility or more speed than a comprehension can provide. -exports.WhileNode = class WhileNode extends BaseNode +exports.While = class While extends Base children: ['condition', 'guard', 'body'] isStatement: YES @@ -1103,8 +1103,8 @@ exports.WhileNode = class WhileNode extends BaseNode constructor: (condition, opts) -> super() if opts?.invert - condition = new ParentheticalNode condition if condition instanceof OpNode - condition = new OpNode('!', condition) + condition = new Parenthetical condition if condition instanceof Op + condition = new Op('!', condition) @condition = condition @guard = opts?.guard @@ -1131,20 +1131,20 @@ exports.WhileNode = class WhileNode extends BaseNode unless top rvar = o.scope.freeVariable 'result' set = "#{@tab}#{rvar} = [];\n" - @body = PushNode.wrap(rvar, @body) if @body + @body = Push.wrap(rvar, @body) if @body pre = "#{set}#{@tab}while (#{cond})" - @body = Expressions.wrap([new IfNode(@guard, @body)]) if @guard + @body = Expressions.wrap([new If(@guard, @body)]) if @guard if @returns - post = '\n' + new ReturnNode(literal(rvar)).compile(merge(o, indent: @idt())) + post = '\n' + new Return(literal(rvar)).compile(merge(o, indent: @idt())) else post = '' "#{pre} {\n#{ @body.compile(o) }\n#{@tab}}#{post}" -#### OpNode +#### Op # Simple Arithmetic and logical operations. Performs some conversion from # CoffeeScript operations into their JavaScript equivalents. -exports.OpNode = class OpNode extends BaseNode +exports.Op = class Op extends Base # The map of conversions from CoffeeScript to JavaScript symbols. CONVERSIONS: @@ -1173,9 +1173,9 @@ exports.OpNode = class OpNode extends BaseNode super() @operator = @CONVERSIONS[@operator] or @operator @flip = !!flip - if @first instanceof ValueNode and @first.base instanceof ObjectNode - @first = new ParentheticalNode @first - else if @operator is 'new' and @first instanceof CallNode + if @first instanceof Value and @first.base instanceof ObjectLiteral + @first = new Parenthetical @first + else if @operator is 'new' and @first instanceof Call return @first.newInstance() @first.tags.operation = yes @second.tags.operation = yes if @second @@ -1185,7 +1185,7 @@ exports.OpNode = class OpNode extends BaseNode isInvertible: -> (@operator in ['===', '!==']) and - not (@first instanceof OpNode) and not (@second instanceof OpNode) + not (@first instanceof Op) and not (@second instanceof Op) isComplex: -> @operator isnt '!' or @first.isComplex() @@ -1202,13 +1202,13 @@ exports.OpNode = class OpNode extends BaseNode super(idt, @constructor.name + ' ' + @operator) compileNode: (o) -> - return node.compile o if node = ValueNode.unfoldSoak o, this, 'first' - return @compileChain(o) if @isChainable() and @first.unwrap() instanceof OpNode and @first.unwrap().isChainable() + return node.compile o if node = Value.unfoldSoak o, this, 'first' + return @compileChain(o) if @isChainable() and @first.unwrap() instanceof Op and @first.unwrap().isChainable() return @compileAssignment(o) if indexOf(@ASSIGNMENT, @operator) >= 0 return @compileUnary(o) if @isUnary() return @compileExistence(o) if @operator is '?' - @first = new ParentheticalNode(@first) if @first instanceof OpNode and @first.isMutator() - @second = new ParentheticalNode(@second) if @second instanceof OpNode and @second.isMutator() + @first = new Parenthetical(@first) if @first instanceof Op and @first.isMutator() + @second = new Parenthetical(@second) if @second instanceof Op and @second.isMutator() [@first.compile(o), @operator, @second.compile(o)].join ' ' # Mimic Python's chained comparisons when multiple comparison operators are @@ -1227,27 +1227,27 @@ exports.OpNode = class OpNode extends BaseNode # more than once. compileAssignment: (o) -> [left, rite] = @first.cacheReference o - rite = new AssignNode rite, @second - return new OpNode(@operator.slice(0, -1), left, rite).compile o + rite = new Assign rite, @second + return new Op(@operator.slice(0, -1), left, rite).compile o compileExistence: (o) -> if @first.isComplex() ref = o.scope.freeVariable 'ref' - fst = new ParentheticalNode new AssignNode literal(ref), @first + fst = new Parenthetical new Assign literal(ref), @first else fst = @first ref = fst.compile o - new ExistenceNode(fst).compile(o) + " ? #{ref} : #{ @second.compile o }" + new Existence(fst).compile(o) + " ? #{ref} : #{ @second.compile o }" - # Compile a unary **OpNode**. + # Compile a unary **Op**. compileUnary: (o) -> space = if indexOf(@PREFIX_OPERATORS, @operator) >= 0 then ' ' else '' parts = [@operator, space, @first.compile(o)] parts = parts.reverse() if @flip parts.join('') -#### InNode -exports.InNode = class InNode extends BaseNode +#### In +exports.In = class In extends Base children: ['object', 'array'] @@ -1255,7 +1255,7 @@ exports.InNode = class InNode extends BaseNode super() isArray: -> - @array instanceof ValueNode and @array.isArray() + @array instanceof Value and @array.isArray() compileNode: (o) -> [@obj1, @obj2] = @object.compileReference o, precompile: yes @@ -1272,10 +1272,10 @@ exports.InNode = class InNode extends BaseNode prefix = if @obj1 isnt @obj2 then @obj1 + '; ' else '' "(function(){ #{prefix}for (var #{i}=0, #{l}=#{@arr1}.length; #{i}<#{l}; #{i}++) { if (#{@arr2}[#{i}] === #{@obj2}) return true; } return false; }).call(this)" -#### TryNode +#### Try # A classic *try/catch/finally* block. -exports.TryNode = class TryNode extends BaseNode +exports.Try = class Try extends Base children: ['attempt', 'recovery', 'ensure'] isStatement: YES @@ -1301,10 +1301,10 @@ exports.TryNode = class TryNode extends BaseNode finallyPart = (@ensure or '') and ' finally {\n' + @ensure.compile(merge(o)) + "\n#{@tab}}" "#{@tab}try {\n#{attemptPart}\n#{@tab}}#{catchPart}#{finallyPart}" -#### ThrowNode +#### Throw # Simple node to throw an exception. -exports.ThrowNode = class ThrowNode extends BaseNode +exports.Throw = class Throw extends Base children: ['expression'] isStatement: YES @@ -1312,18 +1312,18 @@ exports.ThrowNode = class ThrowNode extends BaseNode constructor: (@expression) -> super() - # A **ThrowNode** is already a return, of sorts... + # A **Throw** is already a return, of sorts... makeReturn: THIS compileNode: (o) -> "#{@tab}throw #{@expression.compile(o)};" -#### ExistenceNode +#### Existence # Checks a variable for existence -- not *null* and not *undefined*. This is # similar to `.nil?` in Ruby, and avoids having to consult a JavaScript truth # table. -exports.ExistenceNode = class ExistenceNode extends BaseNode +exports.Existence = class Existence extends Base children: ['expression'] @@ -1338,14 +1338,14 @@ exports.ExistenceNode = class ExistenceNode extends BaseNode "#{code} != null" if @parenthetical then code else "(#{code})" -#### ParentheticalNode +#### Parenthetical # An extra set of parentheses, specified explicitly in the source. At one time # we tried to clean up the results by detecting and removing redundant # parentheses, but no longer -- you can put in as many as you please. # # Parentheses are a good way to force any statement to become an expression. -exports.ParentheticalNode = class ParentheticalNode extends BaseNode +exports.Parenthetical = class Parenthetical extends Base children: ['expression'] @@ -1371,7 +1371,7 @@ exports.ParentheticalNode = class ParentheticalNode extends BaseNode return if top then @tab + code + ';' else code "(#{code})" -#### ForNode +#### For # CoffeeScript's replacement for the *for* loop is our array and object # comprehensions, that compile into *for* loops here. They also act as an @@ -1380,7 +1380,7 @@ exports.ParentheticalNode = class ParentheticalNode extends BaseNode # Unlike Python array comprehensions, they can be multi-line, and you can pass # the current index of the loop as a second parameter. Unlike Ruby blocks, # you can map and filter in a single pass. -exports.ForNode = class ForNode extends BaseNode +exports.For = class For extends Base children: ['body', 'source', 'guard'] isStatement: YES @@ -1394,8 +1394,8 @@ exports.ForNode = class ForNode extends BaseNode @raw = !!source.raw @object = !!source.object [@name, @index] = [@index, @name] if @object - @pattern = @name instanceof ValueNode - throw new Error('index cannot be a pattern matching expression') if @index instanceof ValueNode + @pattern = @name instanceof Value + throw new Error('index cannot be a pattern matching expression') if @index instanceof Value @returns = false topSensitive: YES @@ -1405,7 +1405,7 @@ exports.ForNode = class ForNode extends BaseNode this compileReturnValue: (val, o) -> - return '\n' + new ReturnNode(literal(val)).compile(o) if @returns + return '\n' + new Return(literal(val)).compile(o) if @returns return '\n' + val if val '' @@ -1415,9 +1415,9 @@ exports.ForNode = class ForNode extends BaseNode # some cannot. compileNode: (o) -> topLevel = del(o, 'top') and not @returns - range = @source instanceof ValueNode and @source.base instanceof RangeNode and not @source.properties.length + range = @source instanceof Value and @source.base instanceof Range and not @source.properties.length source = if range then @source.base else @source - codeInBody = @body.contains (node) -> node instanceof CodeNode + codeInBody = @body.contains (node) -> node instanceof Code scope = o.scope name = @name and @name.compile o index = @index and @index.compile o @@ -1437,7 +1437,7 @@ exports.ForNode = class ForNode extends BaseNode [sourcePart, svar] = @source.compileReference merge(o, top: yes), precompile: yes sourcePart = if sourcePart is svar then '' else "#{sourcePart};" namePart = if @pattern - new AssignNode(@name, literal "#{svar}[#{ivar}]").compile merge o, top: on + new Assign(@name, literal "#{svar}[#{ivar}]").compile merge o, top: on else if name "#{name} = #{svar}[#{ivar}]" unless @object @@ -1447,14 +1447,14 @@ exports.ForNode = class ForNode extends BaseNode sourcePart = (if rvar then "#{rvar} = []; " else '') + sourcePart sourcePart = if sourcePart then "#{@tab}#{sourcePart}\n#{@tab}" else @tab returnResult = @compileReturnValue(rvar, o) - body = PushNode.wrap(rvar, body) unless topLevel + body = Push.wrap(rvar, body) unless topLevel if @guard - body = Expressions.wrap([new IfNode(@guard, body)]) + body = Expressions.wrap([new If(@guard, body)]) if codeInBody body.unshift literal "var #{name} = #{ivar}" if range body.unshift literal "var #{namePart}" if namePart body.unshift literal "var #{index} = #{ivar}" if index - body = ClosureNode.wrap(body, true) + body = Closure.wrap(body, true) else varPart = "#{idt1}#{namePart};\n" if namePart if @object @@ -1468,10 +1468,10 @@ exports.ForNode = class ForNode extends BaseNode #{@tab}}#{returnResult} """ -#### SwitchNode +#### Switch # A JavaScript *switch* statement. Converts into a returnable expression on-demand. -exports.SwitchNode = class SwitchNode extends BaseNode +exports.Switch = class Switch extends Base children: ['subject', 'cases', 'otherwise'] @@ -1495,23 +1495,23 @@ exports.SwitchNode = class SwitchNode extends BaseNode [conditions, block] = pair exprs = block.expressions for condition in flatten [conditions] - condition = new OpNode '!!', new ParentheticalNode condition if @tags.subjectless + condition = new Op '!!', new Parenthetical condition if @tags.subjectless code += "\n#{ @idt(1) }case #{ condition.compile o }:" code += "\n#{ block.compile o }" - code += "\n#{ idt }break;" unless last(exprs) instanceof ReturnNode + code += "\n#{ idt }break;" unless last(exprs) instanceof Return if @otherwise code += "\n#{ @idt(1) }default:\n#{ @otherwise.compile o }" code += "\n#{ @tab }}" code -#### IfNode +#### If # *If/else* statements. Acts as an expression by pushing down requested returns # to the last line of each clause. # -# Single-expression **IfNodes** are compiled into conditional operators if possible, +# Single-expression **Ifs** are compiled into conditional operators if possible, # because ternaries are already proper expressions, and don't need conversion. -exports.IfNode = class IfNode extends BaseNode +exports.If = class If extends Base children: ['condition', 'body', 'elseBody', 'assigner'] @@ -1520,26 +1520,26 @@ exports.IfNode = class IfNode extends BaseNode constructor: (@condition, @body, @tags) -> @tags or= {} if @tags.invert - if @condition instanceof OpNode and @condition.isInvertible() + if @condition instanceof Op and @condition.isInvertible() @condition.invert() else - @condition = new OpNode '!', new ParentheticalNode @condition + @condition = new Op '!', new Parenthetical @condition @elseBody = null @isChain = false bodyNode: -> @body?.unwrap() elseBodyNode: -> @elseBody?.unwrap() - # Rewrite a chain of **IfNodes** to add a default case as the final *else*. + # Rewrite a chain of **Ifs** to add a default case as the final *else*. addElse: (elseBody, statement) -> if @isChain @elseBodyNode().addElse elseBody, statement else - @isChain = elseBody instanceof IfNode + @isChain = elseBody instanceof If @elseBody = @ensureExpressions elseBody this - # The **IfNode** only compiles into a statement if either of its bodies needs + # The **If** only compiles into a statement if either of its bodies needs # to be a statement. Otherwise a conditional operator is safe. isStatement: (o) -> @statement or= !!((o and o.top) or @bodyNode().isStatement(o) or (@elseBody and @elseBodyNode().isStatement(o))) @@ -1558,12 +1558,12 @@ exports.IfNode = class IfNode extends BaseNode @elseBody and= @ensureExpressions(@elseBody.makeReturn()) this else - new ReturnNode this + new Return this ensureExpressions: (node) -> if node instanceof Expressions then node else new Expressions [node] - # Compile the **IfNode** as a regular *if-else* statement. Flattened chains + # Compile the **If** as a regular *if-else* statement. Flattened chains # force inner *else* bodies into statement form. compileStatement: (o) -> top = del o, 'top' @@ -1582,7 +1582,7 @@ exports.IfNode = class IfNode extends BaseNode " else {\n#{ @elseBody.compile(o) }\n#{@tab}}" "#{ifPart}#{elsePart}" - # Compile the IfNode as a conditional operator. + # Compile the If as a conditional operator. compileExpression: (o) -> @bodyNode().tags.operation = @condition.tags.operation = yes @elseBodyNode().tags.operation = yes if @elseBody @@ -1596,42 +1596,42 @@ exports.IfNode = class IfNode extends BaseNode # Faux-nodes are never created by the grammar, but are used during code # generation to generate other combinations of nodes. -#### PushNode +#### Push -# The **PushNode** creates the tree for `array.push(value)`, +# The **Push** creates the tree for `array.push(value)`, # which is helpful for recording the result arrays from comprehensions. -PushNode = +Push = wrap: (name, expressions) -> return expressions if expressions.empty() or expressions.containsPureStatement() - Expressions.wrap [new CallNode( - new ValueNode literal(name), [new AccessorNode literal 'push'] + Expressions.wrap [new Call( + new Value literal(name), [new Accessor literal 'push'] [expressions.unwrap()] )] -#### ClosureNode +#### Closure # A faux-node used to wrap an expressions body in a closure. -ClosureNode = +Closure = # Wrap the expressions body, unless it contains a pure statement, # in which case, no dice. If the body mentions `this` or `arguments`, # then make sure that the closure wrapper preserves the original values. wrap: (expressions, statement) -> return expressions if expressions.containsPureStatement() - func = new ParentheticalNode new CodeNode [], Expressions.wrap [expressions] + func = new Parenthetical new Code [], Expressions.wrap [expressions] args = [] if (mentionsArgs = expressions.contains @literalArgs) or ( expressions.contains @literalThis) meth = literal if mentionsArgs then 'apply' else 'call' args = [literal 'this'] args.push literal 'arguments' if mentionsArgs - func = new ValueNode func, [new AccessorNode meth] - call = new CallNode func, args + func = new Value func, [new Accessor meth] + call = new Call func, args if statement then Expressions.wrap [call] else call - literalArgs: (node) -> node instanceof LiteralNode and node.value is 'arguments' - literalThis: (node) -> node instanceof LiteralNode and node.value is 'this' or - node instanceof CodeNode and node.bound + literalArgs: (node) -> node instanceof Literal and node.value is 'arguments' + literalThis: (node) -> node instanceof Literal and node.value is 'this' or + node instanceof Code and node.bound # Constants # --------- @@ -1680,8 +1680,8 @@ IS_STRING = /^['"]/ # Utility Functions # ----------------- -# Handy helper for generating a LiteralNode. -literal = (name) -> new LiteralNode name +# Handy helper for generating a Literal. +literal = (name) -> new Literal name # Helper for ensuring that utility functions are assigned at the top level. utility = (name) ->