Add location data to nodes without passing it in constructors.

This commit is contained in:
Jason Walton 2012-11-15 15:35:01 -05:00
parent d5d772d55e
commit 25126e2f99
7 changed files with 808 additions and 761 deletions

View File

@ -7,28 +7,36 @@
unwrap = /^function\s*\(\)\s*\{\s*return\s*([\s\S]*);\s*\}/;
o = function(patternString, action, options) {
var match;
var addLocationDataFn, match, patternCount;
patternString = patternString.replace(/\s{2,}/g, ' ');
patternCount = patternString.split(' ').length;
if (!action) {
return [patternString, '$$ = $1;', options];
}
action = (match = unwrap.exec(action)) ? match[1] : "(" + action + "())";
action = action.replace(/\bnew /g, '$&yy.');
action = action.replace(/\b(?:Block\.wrap|extend)\b/g, 'yy.$&');
action = action.replace(/LOCDATA\(([0-9]*)\)/g, '@$1');
action = action.replace(/LOCDATA\(([0-9]*),\s*([0-9]*)\)/g, '(function(){loc = {}; loc.first_column = @$1.first_column; ' + 'loc.first_line = @$1.first_line; ' + 'loc.last_column = @$2.last_column; ' + 'loc.last_line = @$2.last_line; ' + 'return loc;})()');
return [patternString, "$$ = " + action + ";", options];
addLocationDataFn = function(first, last) {
if (!last) {
return "yy.addLocationDataFn(@" + first + ")";
} else {
return "yy.addLocationDataFn(@" + first + ", @" + last + ")";
}
};
action = action.replace(/LOCDATA\(([0-9]*)\)/g, addLocationDataFn('$1'));
action = action.replace(/LOCDATA\(([0-9]*),\s*([0-9]*)\)/g, addLocationDataFn('$1', '$2'));
return [patternString, "$$ = " + (addLocationDataFn(1, patternCount)) + "(" + action + ");", options];
};
grammar = {
Root: [
o('', function() {
return new Block(LOCDATA(1));
return new Block;
}), o('Body'), o('Block TERMINATOR')
],
Body: [
o('Line', function() {
return Block.wrap(LOCDATA(1), [$1]);
return Block.wrap([$1]);
}), o('Body TERMINATOR Line', function() {
return $1.push($3);
}), o('Body TERMINATOR')
@ -36,81 +44,81 @@
Line: [o('Expression'), o('Statement')],
Statement: [
o('Return'), o('Comment'), o('STATEMENT', function() {
return new Literal(LOCDATA(1), $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('Class'), o('Throw')],
Block: [
o('INDENT OUTDENT', function() {
return new Block(LOCDATA(1));
return new Block;
}), o('INDENT Body OUTDENT', function() {
return $2;
})
],
Identifier: [
o('IDENTIFIER', function() {
return new Literal(LOCDATA(1), $1);
return new Literal($1);
})
],
AlphaNumeric: [
o('NUMBER', function() {
return new Literal(LOCDATA(1), $1);
return new Literal($1);
}), o('STRING', function() {
return new Literal(LOCDATA(1), $1);
return new Literal($1);
})
],
Literal: [
o('AlphaNumeric'), o('JS', function() {
return new Literal(LOCDATA(1), $1);
return new Literal($1);
}), o('REGEX', function() {
return new Literal(LOCDATA(1), $1);
return new Literal($1);
}), o('DEBUGGER', function() {
return new Literal(LOCDATA(1), $1);
return new Literal($1);
}), o('UNDEFINED', function() {
return new Undefined(LOCDATA(1));
return new Undefined;
}), o('NULL', function() {
return new Null(LOCDATA(1));
return new Null;
}), o('BOOL', function() {
return new Bool(LOCDATA(1), $1);
return new Bool($1);
})
],
Assign: [
o('Assignable = Expression', function() {
return new Assign(LOCDATA(1, 3), $1, $3);
return new Assign($1, $3);
}), o('Assignable = TERMINATOR Expression', function() {
return new Assign(LOCDATA(1, 4), $1, $4);
return new Assign($1, $4);
}), o('Assignable = INDENT Expression OUTDENT', function() {
return new Assign(LOCDATA(1, 4), $1, $4);
return new Assign($1, $4);
})
],
AssignObj: [
o('ObjAssignable', function() {
return new Value(LOCDATA(1), $1);
return new Value($1);
}), o('ObjAssignable : Expression', function() {
return new Assign(LOCDATA(1, 3), new Value(LOCDATA(1), $1), $3, 'object');
return new Assign(LOCDATA(1)(new Value($1)), $3, 'object');
}), o('ObjAssignable :\
INDENT Expression OUTDENT', function() {
return new Assign(LOCDATA(1, 4), new Value(LOCDATA(1), $1), $4, 'object');
return new Assign(LOCDATA(1)(new Value($1)), $4, 'object');
}), o('Comment')
],
ObjAssignable: [o('Identifier'), o('AlphaNumeric'), o('ThisProperty')],
Return: [
o('RETURN Expression', function() {
return new Return(LOCDATA(1, 2), $2);
return new Return($2);
}), o('RETURN', function() {
return new Return(LOCDATA(1));
return new Return;
})
],
Comment: [
o('HERECOMMENT', function() {
return new Comment(LOCDATA(1), $1);
return new Comment($1);
})
],
Code: [
o('PARAM_START ParamList PARAM_END FuncGlyph Block', function() {
return new Code(LOCDATA(1, 5), $2, $5, $4);
return new Code($2, $5, $4);
}), o('FuncGlyph Block', function() {
return new Code(LOCDATA(1, 2), [], $2, $1);
return new Code([], $2, $1);
})
],
FuncGlyph: [
@ -136,53 +144,53 @@
],
Param: [
o('ParamVar', function() {
return new Param(LOCDATA(1), $1);
return new Param($1);
}), o('ParamVar ...', function() {
return new Param(LOCDATA(1), $1, null, true);
return new Param($1, null, true);
}), o('ParamVar = Expression', function() {
return new Param(LOCDATA(1, 3), $1, $3);
return new Param($1, $3);
})
],
ParamVar: [o('Identifier'), o('ThisProperty'), o('Array'), o('Object')],
Splat: [
o('Expression ...', function() {
return new Splat(LOCDATA(1), $1);
return new Splat($1);
})
],
SimpleAssignable: [
o('Identifier', function() {
return new Value(LOCDATA(1), $1);
return new Value($1);
}), o('Value Accessor', function() {
return $1.add($2);
}), o('Invocation Accessor', function() {
return new Value(LOCDATA(1, 2), $1, [].concat($2));
return new Value($1, [].concat($2));
}), o('ThisProperty')
],
Assignable: [
o('SimpleAssignable'), o('Array', function() {
return new Value(LOCDATA(1), $1);
return new Value($1);
}), o('Object', function() {
return new Value(LOCDATA(1), $1);
return new Value($1);
})
],
Value: [
o('Assignable'), o('Literal', function() {
return new Value(LOCDATA(1), $1);
return new Value($1);
}), o('Parenthetical', function() {
return new Value(LOCDATA(1), $1);
return new Value($1);
}), o('Range', function() {
return new Value(LOCDATA(1), $1);
return new Value($1);
}), o('This')
],
Accessor: [
o('. Identifier', function() {
return new Access(LOCDATA(1, 2), $2);
return new Access($2);
}), o('?. Identifier', function() {
return new Access(LOCDATA(1, 2), $2, 'soak');
return new Access($2, 'soak');
}), o(':: Identifier', function() {
return [new Access(LOCDATA(1), new Literal(LOCDATA(1), 'prototype')), new Access(LOCDATA(1), $2)];
return [LOCDATA(1)(new Access(new Literal('prototype'))), LOCDATA(2)(new Access($2))];
}), o('::', function() {
return new Access(LOCDATA(1), new Literal(LOCDATA(1), 'prototype'));
return new Access(new Literal('prototype'));
}), o('Index')
],
Index: [
@ -196,14 +204,14 @@
],
IndexValue: [
o('Expression', function() {
return new Index(LOCDATA(1), $1);
return new Index($1);
}), o('Slice', function() {
return new Slice(LOCDATA(1), $1);
return new Slice($1);
})
],
Object: [
o('{ AssignList OptComma }', function() {
return new Obj(LOCDATA(1, 2), $2, $1.generated);
return new Obj($2, $1.generated);
})
],
AssignList: [
@ -221,32 +229,32 @@
],
Class: [
o('CLASS', function() {
return new Class(LOCDATA(1));
return new Class;
}), o('CLASS Block', function() {
return new Class(LOCDATA(1, 2), null, null, $2);
return new Class(null, null, $2);
}), o('CLASS EXTENDS Expression', function() {
return new Class(LOCDATA(1, 3), null, $3);
return new Class(null, $3);
}), o('CLASS EXTENDS Expression Block', function() {
return new Class(LOCDATA(1, 4), null, $3, $4);
return new Class(null, $3, $4);
}), o('CLASS SimpleAssignable', function() {
return new Class(LOCDATA(1, 2), $2);
return new Class($2);
}), o('CLASS SimpleAssignable Block', function() {
return new Class(LOCDATA(1, 3), $2, null, $3);
return new Class($2, null, $3);
}), o('CLASS SimpleAssignable EXTENDS Expression', function() {
return new Class(LOCDATA(1, 4), $2, $4);
return new Class($2, $4);
}), o('CLASS SimpleAssignable EXTENDS Expression Block', function() {
return new Class(LOCDATA(1, 5), $2, $4, $5);
return new Class($2, $4, $5);
})
],
Invocation: [
o('Value OptFuncExist Arguments', function() {
return new Call(LOCDATA(1, 3), $1, $3, $2);
return new Call($1, $3, $2);
}), o('Invocation OptFuncExist Arguments', function() {
return new Call(LOCDATA(1, 3), $1, $3, $2);
return new Call($1, $3, $2);
}), o('SUPER', function() {
return new Call(LOCDATA(1), 'super', [new Splat(LOCDATA(1), new Literal(LOCDATA(1), 'arguments'))]);
return new Call('super', [new Splat(new Literal('arguments'))]);
}), o('SUPER Arguments', function() {
return new Call(LOCDATA(1, 2), 'super', $2);
return new Call('super', $2);
})
],
OptFuncExist: [
@ -265,21 +273,21 @@
],
This: [
o('THIS', function() {
return new Value(LOCDATA(1), new Literal(LOCDATA(1), 'this'));
return new Value(new Literal('this'));
}), o('@', function() {
return new Value(LOCDATA(1), new Literal(LOCDATA(1), 'this'));
return new Value(new Literal('this'));
})
],
ThisProperty: [
o('@ Identifier', function() {
return new Value(LOCDATA(1, 2), new Literal(LOCDATA(1), 'this'), [new Access(LOCDATA(2), $2)], 'this');
return new Value(LOCDATA(1)(new Literal('this')), [LOCDATA(2)(new Access($2))], 'this');
})
],
Array: [
o('[ ]', function() {
return new Arr(LOCDATA(1), []);
return new Arr([]);
}), o('[ ArgList OptComma ]', function() {
return new Arr(LOCDATA(1, 2), $2);
return new Arr($2);
})
],
RangeDots: [
@ -291,18 +299,18 @@
],
Range: [
o('[ Expression RangeDots Expression ]', function() {
return new Range(LOCDATA(1, 4), $2, $4, $3);
return new Range($2, $4, $3);
})
],
Slice: [
o('Expression RangeDots Expression', function() {
return new Range(LOCDATA(1, 3), $1, $3, $2);
return new Range($1, $3, $2);
}), o('Expression RangeDots', function() {
return new Range(LOCDATA(1, 2), $1, null, $2);
return new Range($1, null, $2);
}), o('RangeDots Expression', function() {
return new Range(LOCDATA(1, 2), null, $2, $1);
return new Range(null, $2, $1);
}), o('RangeDots', function() {
return new Range(LOCDATA(1), null, null, $1);
return new Range(null, null, $1);
})
],
ArgList: [
@ -326,47 +334,47 @@
],
Try: [
o('TRY Block', function() {
return new Try(LOCDATA(1, 2), $2);
return new Try($2);
}), o('TRY Block Catch', function() {
return new Try(LOCDATA(1, 3), $2, $3[0], $3[1]);
return new Try($2, $3[0], $3[1]);
}), o('TRY Block FINALLY Block', function() {
return new Try(LOCDATA(1, 4), $2, null, null, $4);
return new Try($2, null, null, $4);
}), o('TRY Block Catch FINALLY Block', function() {
return new Try(LOCDATA(1, 5), $2, $3[0], $3[1], $5);
return new Try($2, $3[0], $3[1], $5);
})
],
Catch: [
o('CATCH Identifier Block', function() {
return [$2, $3];
}), o('CATCH Object Block', function() {
return [new Value(LOCDATA(2), $2), $3];
return [LOCDATA(2)(new Value($2)), $3];
})
],
Throw: [
o('THROW Expression', function() {
return new Throw(LOCDATA(1, 2), $2);
return new Throw($2);
})
],
Parenthetical: [
o('( Body )', function() {
return new Parens(LOCDATA(1, 3), $2);
return new Parens($2);
}), o('( INDENT Body OUTDENT )', function() {
return new Parens(LOCDATA(1, 4), $3);
return new Parens($3);
})
],
WhileSource: [
o('WHILE Expression', function() {
return new While(LOCDATA(1, 2), $2);
return new While($2);
}), o('WHILE Expression WHEN Expression', function() {
return new While(LOCDATA(1, 4), $2, {
return new While($2, {
guard: $4
});
}), o('UNTIL Expression', function() {
return new While(LOCDATA(1, 2), $2, {
return new While($2, {
invert: true
});
}), o('UNTIL Expression WHEN Expression', function() {
return new While(LOCDATA(1, 4), $2, {
return new While($2, {
invert: true,
guard: $4
});
@ -376,33 +384,33 @@
o('WhileSource Block', function() {
return $1.addBody($2);
}), o('Statement WhileSource', function() {
return $2.addBody(Block.wrap(LOCDATA(1), [$1]));
return $2.addBody(LOCDATA(1)(Block.wrap([$1])));
}), o('Expression WhileSource', function() {
return $2.addBody(Block.wrap(LOCDATA(1), [$1]));
return $2.addBody(LOCDATA(1)(Block.wrap([$1])));
}), o('Loop', function() {
return $1;
})
],
Loop: [
o('LOOP Block', function() {
return new While(LOCDATA(1, 2), new Literal(LOCDATA(1), 'true')).addBody($2);
return new While(LOCDATA(1)(new Literal('true'))).addBody($2);
}), o('LOOP Expression', function() {
return new While(LOCDATA(1, 2), new Literal(LOCDATA(1), 'true')).addBody(Block.wrap(LOCDATA(2), [$2]));
return new While(LOCDATA(1)(new Literal('true'))).addBody(LOCDATA(2)(Block.wrap([$2])));
})
],
For: [
o('Statement ForBody', function() {
return new For(LOCDATA(1, 2), $1, $2);
return new For($1, $2);
}), o('Expression ForBody', function() {
return new For(LOCDATA(1, 2), $1, $2);
return new For($1, $2);
}), o('ForBody Block', function() {
return new For(LOCDATA(1, 2), $2, $1);
return new For($2, $1);
})
],
ForBody: [
o('FOR Range', function() {
return {
source: new Value(LOCDATA(2), $2)
source: LOCDATA(2)(new Value($2))
};
}), o('ForStart ForSource', function() {
$2.own = $1.own;
@ -421,9 +429,9 @@
],
ForValue: [
o('Identifier'), o('ThisProperty'), o('Array', function() {
return new Value(LOCDATA(1), $1);
return new Value($1);
}), o('Object', function() {
return new Value(LOCDATA(1), $1);
return new Value($1);
})
],
ForVariables: [
@ -475,13 +483,13 @@
],
Switch: [
o('SWITCH Expression INDENT Whens OUTDENT', function() {
return new Switch(LOCDATA(1, 5), $2, $4);
return new Switch($2, $4);
}), o('SWITCH Expression INDENT Whens ELSE Block OUTDENT', function() {
return new Switch(LOCDATA(1, 7), $2, $4, $6);
return new Switch($2, $4, $6);
}), o('SWITCH INDENT Whens OUTDENT', function() {
return new Switch(LOCDATA(1, 4), null, $3);
return new Switch(null, $3);
}), o('SWITCH INDENT Whens ELSE Block OUTDENT', function() {
return new Switch(LOCDATA(1, 6), null, $3, $5);
return new Switch(null, $3, $5);
})
],
Whens: [
@ -498,11 +506,11 @@
],
IfBlock: [
o('IF Expression Block', function() {
return new If(LOCDATA(1, 3), $2, $3, {
return new If($2, $3, {
type: $1
});
}), o('IfBlock ELSE IF Expression Block', function() {
return $1.addElse(new If(LOCDATA(1, 5), $4, $5, {
return $1.addElse(new If($4, $5, {
type: $3
}));
})
@ -511,12 +519,12 @@
o('IfBlock'), o('IfBlock ELSE Block', function() {
return $1.addElse($3);
}), o('Statement POST_IF Expression', function() {
return new If(LOCDATA(1, 3), $3, Block.wrap(LOCDATA(1), [$1]), {
return new If($3, LOCDATA(1)(Block.wrap([$1])), {
type: $2,
statement: true
});
}), o('Expression POST_IF Expression', function() {
return new If(LOCDATA(1, 3), $3, Block.wrap(LOCDATA(1), [$1]), {
return new If($3, LOCDATA(1)(Block.wrap([$1])), {
type: $2,
statement: true
});
@ -524,51 +532,51 @@
],
Operation: [
o('UNARY Expression', function() {
return new Op(LOCDATA(1, 2), $1, $2);
return new Op($1, $2);
}), o('- Expression', (function() {
return new Op(LOCDATA(1, 2), '-', $2);
return new Op('-', $2);
}), {
prec: 'UNARY'
}), o('+ Expression', (function() {
return new Op(LOCDATA(1, 2), '+', $2);
return new Op('+', $2);
}), {
prec: 'UNARY'
}), o('-- SimpleAssignable', function() {
return new Op(LOCDATA(1, 2), '--', $2);
return new Op('--', $2);
}), o('++ SimpleAssignable', function() {
return new Op(LOCDATA(1, 2), '++', $2);
return new Op('++', $2);
}), o('SimpleAssignable --', function() {
return new Op(LOCDATA(1, 2), '--', $1, null, true);
return new Op('--', $1, null, true);
}), o('SimpleAssignable ++', function() {
return new Op(LOCDATA(1, 2), '++', $1, null, true);
return new Op('++', $1, null, true);
}), o('Expression ?', function() {
return new Existence(LOCDATA(1), $1);
return new Existence($1);
}), o('Expression + Expression', function() {
return new Op(LOCDATA(1, 3), '+', $1, $3);
return new Op('+', $1, $3);
}), o('Expression - Expression', function() {
return new Op(LOCDATA(1, 3), '-', $1, $3);
return new Op('-', $1, $3);
}), o('Expression MATH Expression', function() {
return new Op(LOCDATA(1, 3), $2, $1, $3);
return new Op($2, $1, $3);
}), o('Expression SHIFT Expression', function() {
return new Op(LOCDATA(1, 3), $2, $1, $3);
return new Op($2, $1, $3);
}), o('Expression COMPARE Expression', function() {
return new Op(LOCDATA(1, 3), $2, $1, $3);
return new Op($2, $1, $3);
}), o('Expression LOGIC Expression', function() {
return new Op(LOCDATA(1, 3), $2, $1, $3);
return new Op($2, $1, $3);
}), o('Expression RELATION Expression', function() {
if ($2.charAt(0) === '!') {
return new Op(LOCDATA(1, 3), $2.slice(1), $1, $3).invert();
return new Op($2.slice(1), $1, $3).invert();
} else {
return new Op(LOCDATA(1, 3), $2, $1, $3);
return new Op($2, $1, $3);
}
}), o('SimpleAssignable COMPOUND_ASSIGN\
Expression', function() {
return new Assign(LOCDATA(1, 3), $1, $3, $2);
return new Assign($1, $3, $2);
}), o('SimpleAssignable COMPOUND_ASSIGN\
INDENT Expression OUTDENT', function() {
return new Assign(LOCDATA(1, 5), $1, $4, $2);
return new Assign($1, $4, $2);
}), o('SimpleAssignable EXTENDS Expression', function() {
return new Extends(LOCDATA(1, 3), $1, $3);
return new Extends($1, $3);
})
]
};

View File

@ -1,6 +1,6 @@
// Generated by CoffeeScript 1.4.0
(function() {
var extend, flatten, _ref;
var buildLocationData, extend, flatten, _ref;
exports.starts = function(string, literal, start) {
return literal === string.substr(start, literal.length);
@ -85,4 +85,26 @@
return false;
};
buildLocationData = function(first, last) {
if (!last) {
return first;
} else {
return {
first_line: first.first_line,
first_column: first.first_column,
last_line: last.last_line,
last_column: last.last_column
};
}
};
exports.addLocationDataFn = function(first, last) {
return function(obj) {
if (((typeof obj) === 'object') && (!!obj['updateLocationDataIfMissing'])) {
obj.updateLocationDataIfMissing(buildLocationData(first, last));
}
return obj;
};
};
}).call(this);

View File

@ -1,6 +1,6 @@
// Generated by CoffeeScript 1.4.0
(function() {
var Access, Arr, Assign, Base, Block, Call, Class, Closure, Code, Comment, Existence, Extends, For, IDENTIFIER, IDENTIFIER_STR, IS_STRING, If, In, Index, LEVEL_ACCESS, LEVEL_COND, LEVEL_LIST, LEVEL_OP, LEVEL_PAREN, LEVEL_TOP, Literal, METHOD_DEF, NEGATE, NO, Obj, Op, Param, Parens, RESERVED, Range, Return, SIMPLENUM, STRICT_PROSCRIBED, Scope, Slice, Splat, Switch, TAB, THIS, Throw, Try, UTILITIES, Value, While, YES, compact, del, ends, extend, flatten, last, merge, multident, some, starts, unfoldSoak, utility, _ref, _ref1,
var Access, Arr, Assign, Base, Block, Call, Class, Closure, Code, Comment, Existence, Extends, For, IDENTIFIER, IDENTIFIER_STR, IS_STRING, If, In, Index, LEVEL_ACCESS, LEVEL_COND, LEVEL_LIST, LEVEL_OP, LEVEL_PAREN, LEVEL_TOP, Literal, METHOD_DEF, NEGATE, NO, Obj, Op, Param, Parens, RESERVED, Range, Return, SIMPLENUM, STRICT_PROSCRIBED, Scope, Slice, Splat, Switch, TAB, THIS, Throw, Try, UTILITIES, Value, While, YES, addLocationDataFn, compact, del, ends, extend, flatten, last, merge, multident, some, starts, unfoldSoak, utility, _ref, _ref1,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
@ -9,10 +9,12 @@
_ref = require('./lexer'), RESERVED = _ref.RESERVED, STRICT_PROSCRIBED = _ref.STRICT_PROSCRIBED;
_ref1 = require('./helpers'), compact = _ref1.compact, flatten = _ref1.flatten, extend = _ref1.extend, merge = _ref1.merge, del = _ref1.del, starts = _ref1.starts, ends = _ref1.ends, last = _ref1.last, some = _ref1.some;
_ref1 = require('./helpers'), compact = _ref1.compact, flatten = _ref1.flatten, extend = _ref1.extend, merge = _ref1.merge, del = _ref1.del, starts = _ref1.starts, ends = _ref1.ends, last = _ref1.last, some = _ref1.some, addLocationDataFn = _ref1.addLocationDataFn;
exports.extend = extend;
exports.addLocationDataFn = addLocationDataFn;
YES = function() {
return true;
};
@ -54,7 +56,7 @@
throw SyntaxError('cannot use a pure statement in an expression.');
}
o.sharedScope = true;
return Closure.wrap(this.locationData, this).compileNode(o);
return Closure.wrap(this).compileNode(o);
};
Base.prototype.cache = function(o, level, reused) {
@ -63,8 +65,8 @@
ref = level ? this.compile(o, level) : this;
return [ref, ref];
} else {
ref = new Literal(this.locationData, reused || o.scope.freeVariable('ref'));
sub = new Assign(this.locationData, ref, this);
ref = new Literal(reused || o.scope.freeVariable('ref'));
sub = new Assign(ref, this);
if (level) {
return [sub.compile(o, level), ref.value];
} else {
@ -86,9 +88,9 @@
var me;
me = this.unwrapAll();
if (res) {
return new Call(this.locationData, new Literal(this.locationData, "" + res + ".push"), [me]);
return new Call(new Literal("" + res + ".push"), [me]);
} else {
return new Return(this.locationData, me);
return new Return(me);
}
};
@ -176,7 +178,7 @@
};
Base.prototype.invert = function() {
return new Op(this.locationData, '!', this);
return new Op('!', this);
};
Base.prototype.unwrapAll = function() {
@ -206,6 +208,16 @@
Base.prototype.assigns = NO;
Base.prototype.updateLocationDataIfMissing = function(locationData) {
if (!this.locationData) {
this.locationData = {};
extend(this.locationData, locationData);
}
return this.eachChild(function(child) {
return child.updateLocationDataIfMissing(locationData);
});
};
return Base;
})();
@ -214,8 +226,7 @@
__extends(Block, _super);
function Block(locationData, nodes) {
this.locationData = locationData;
function Block(nodes) {
this.expressions = compact(flatten(nodes || []));
}
@ -417,11 +428,11 @@
return code + post;
};
Block.wrap = function(locationData, nodes) {
Block.wrap = function(nodes) {
if (nodes.length === 1 && nodes[0] instanceof Block) {
return nodes[0];
}
return new Block(locationData, nodes);
return new Block(nodes);
};
return Block;
@ -432,8 +443,7 @@
__extends(Literal, _super);
function Literal(locationData, value) {
this.locationData = locationData;
function Literal(value) {
this.value = value;
}
@ -491,8 +501,8 @@
__extends(Undefined, _super);
function Undefined(locationData) {
this.locationData = locationData;
function Undefined() {
return Undefined.__super__.constructor.apply(this, arguments);
}
Undefined.prototype.isAssignable = NO;
@ -515,8 +525,8 @@
__extends(Null, _super);
function Null(locationData) {
this.locationData = locationData;
function Null() {
return Null.__super__.constructor.apply(this, arguments);
}
Null.prototype.isAssignable = NO;
@ -543,8 +553,7 @@
return this.val;
};
function Bool(locationData, val) {
this.locationData = locationData;
function Bool(val) {
this.val = val;
}
@ -556,8 +565,7 @@
__extends(Return, _super);
function Return(locationData, expr) {
this.locationData = locationData;
function Return(expr) {
if (expr && !expr.unwrap().isUndefined) {
this.expression = expr;
}
@ -593,11 +601,10 @@
__extends(Value, _super);
function Value(locationData, base, props, tag) {
function Value(base, props, tag) {
if (!props && base instanceof Value) {
return base;
}
this.locationData = locationData;
this.base = base;
this.properties = props || [];
if (tag) {
@ -686,20 +693,20 @@
if (this.properties.length < 2 && !this.base.isComplex() && !(name != null ? name.isComplex() : void 0)) {
return [this, this];
}
base = new Value(this.locationData, this.base, this.properties.slice(0, -1));
base = new Value(this.base, this.properties.slice(0, -1));
if (base.isComplex()) {
bref = new Literal(this.locationData, o.scope.freeVariable('base'));
base = new Value(this.locationData, new Parens(this.locationData, new Assign(this.locationData, bref, base)));
bref = new Literal(o.scope.freeVariable('base'));
base = new Value(new Parens(new Assign(bref, base)));
}
if (!name) {
return [base, bref];
}
if (name.isComplex()) {
nref = new Literal(this.locationData, o.scope.freeVariable('name'));
name = new Index(this.locationData, new Assign(this.locationData, nref, name.index));
nref = new Index(this.locationData, nref);
nref = new Literal(o.scope.freeVariable('name'));
name = new Index(new Assign(nref, name.index));
nref = new Index(nref);
}
return [base.add(name), new Value(this.locationData, bref || base.base, [nref || name])];
return [base.add(name), new Value(bref || base.base, [nref || name])];
};
Value.prototype.compileNode = function(o) {
@ -736,14 +743,14 @@
continue;
}
prop.soak = false;
fst = new Value(_this.locationData, _this.base, _this.properties.slice(0, i));
snd = new Value(_this.locationData, _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 = new Literal(_this.locationData, o.scope.freeVariable('ref'));
fst = new Parens(_this.locationData, new Assign(_this.locationData, ref, fst));
ref = new Literal(o.scope.freeVariable('ref'));
fst = new Parens(new Assign(ref, fst));
snd.base = ref;
}
return new If(_this.locationData, new Existence(_this.locationData, fst), snd, {
return new If(new Existence(fst), snd, {
soak: true
});
}
@ -760,8 +767,7 @@
__extends(Comment, _super);
function Comment(locationData, comment) {
this.locationData = locationData;
function Comment(comment) {
this.comment = comment;
}
@ -786,8 +792,7 @@
__extends(Call, _super);
function Call(locationData, variable, args, soak) {
this.locationData = locationData;
function Call(variable, args, soak) {
this.args = args != null ? args : [];
this.soak = soak;
this.isNew = false;
@ -819,12 +824,12 @@
throw SyntaxError('cannot call super on an anonymous function.');
}
if (method.klass) {
accesses = [new Access(this.locationData, new Literal(this.locationData, '__super__'))];
accesses = [new Access(new Literal('__super__'))];
if (method["static"]) {
accesses.push(new Access(this.locationData, new Literal(this.locationData, 'constructor')));
accesses.push(new Access(new Literal('constructor')));
}
accesses.push(new Access(this.locationData, new Literal(this.locationData, name)));
return (new Value(this.locationData, new Literal(this.locationData, method.klass), accesses)).compile(o);
accesses.push(new Access(new Literal(name)));
return (new Value(new Literal(method.klass), accesses)).compile(o);
} else {
return "" + name + ".__super__.constructor";
}
@ -843,15 +848,15 @@
if (ifn = unfoldSoak(o, this, 'variable')) {
return ifn;
}
_ref2 = new Value(this.locationData, this.variable).cacheReference(o), left = _ref2[0], rite = _ref2[1];
_ref2 = new Value(this.variable).cacheReference(o), left = _ref2[0], rite = _ref2[1];
} else {
left = new Literal(this.locationData, this.superReference(o));
rite = new Value(this.locationData, left);
left = new Literal(this.superReference(o));
rite = new Value(left);
}
rite = new Call(this.locationData, rite, this.args);
rite = new Call(rite, this.args);
rite.isNew = this.isNew;
left = new Literal(this.locationData, "typeof " + (left.compile(o)) + " === \"function\"");
return new If(this.locationData, left, new Value(this.locationData, rite), {
left = new Literal("typeof " + (left.compile(o)) + " === \"function\"");
return new If(left, new Value(rite), {
soak: true
});
}
@ -901,7 +906,7 @@
prop = _ref2[_j];
if (prop instanceof Assign || prop instanceof Comment) {
if (!obj) {
nodes.push(obj = new Obj(this.locationData, properties = [], true));
nodes.push(obj = new Obj(properties = [], true));
}
properties.push(prop);
} else {
@ -951,7 +956,7 @@
idt = this.tab + TAB;
return "(function(func, args, ctor) {\n" + idt + "ctor.prototype = func.prototype;\n" + idt + "var child = new ctor, result = func.apply(child, args);\n" + idt + "return Object(result) === result ? result : child;\n" + this.tab + "})(" + (this.variable.compile(o, LEVEL_LIST)) + ", " + splatArgs + ", function(){})";
}
base = new Value(this.locationData, this.variable);
base = new Value(this.variable);
if ((name = base.properties.pop()) && base.isComplex()) {
ref = o.scope.freeVariable('ref');
fun = "(" + ref + " = " + (base.compile(o, LEVEL_LIST)) + ")" + (name.compile(o));
@ -978,8 +983,7 @@
__extends(Extends, _super);
function Extends(locationData, child, parent) {
this.locationData = locationData;
function Extends(child, parent) {
this.child = child;
this.parent = parent;
}
@ -987,7 +991,7 @@
Extends.prototype.children = ['child', 'parent'];
Extends.prototype.compile = function(o) {
return new Call(this.locationData, new Value(this.locationData, new Literal(this.locationData, utility('extends'))), [this.child, this.parent]).compile(o);
return new Call(new Value(new Literal(utility('extends'))), [this.child, this.parent]).compile(o);
};
return Extends;
@ -998,8 +1002,7 @@
__extends(Access, _super);
function Access(locationData, name, tag) {
this.locationData = locationData;
function Access(name, tag) {
this.name = name;
this.name.asKey = true;
this.soak = tag === 'soak';
@ -1027,8 +1030,7 @@
__extends(Index, _super);
function Index(locationData, index) {
this.locationData = locationData;
function Index(index) {
this.index = index;
}
@ -1052,8 +1054,7 @@
Range.prototype.children = ['from', 'to'];
function Range(locationData, from, to, tag) {
this.locationData = locationData;
function Range(from, to, tag) {
this.from = from;
this.to = to;
this.exclusive = tag === 'exclusive';
@ -1154,8 +1155,7 @@
Slice.prototype.children = ['range'];
function Slice(locationData, range) {
this.locationData = locationData;
function Slice(range) {
this.range = range;
Slice.__super__.constructor.call(this);
}
@ -1179,8 +1179,7 @@
__extends(Obj, _super);
function Obj(locationData, props, generated) {
this.locationData = locationData;
function Obj(props, generated) {
this.generated = generated != null ? generated : false;
this.objects = this.properties = props || [];
}
@ -1211,18 +1210,18 @@
join = i === props.length - 1 ? '' : prop === lastNoncom || prop instanceof Comment ? '\n' : ',\n';
indent = prop instanceof Comment ? '' : idt;
if (prop instanceof Value && prop["this"]) {
prop = new Assign(this.locationData, prop.properties[0].name, prop, 'object');
prop = new Assign(prop.properties[0].name, prop, 'object');
}
if (!(prop instanceof Comment)) {
if (!(prop instanceof Assign)) {
prop = new Assign(this.locationData, prop, prop, 'object');
prop = new Assign(prop, prop, 'object');
}
(prop.variable.base || prop.variable).asKey = true;
}
_results.push(indent + prop.compile(o, LEVEL_TOP) + join);
}
return _results;
}).call(this);
})();
props = props.join('');
obj = "{" + (props && '\n' + props + '\n' + this.tab) + "}";
if (this.front) {
@ -1252,8 +1251,7 @@
__extends(Arr, _super);
function Arr(locationData, objs) {
this.locationData = locationData;
function Arr(objs) {
this.objects = objs || [];
}
@ -1307,11 +1305,10 @@
__extends(Class, _super);
function Class(locationData, variable, parent, body) {
this.locationData = locationData;
function Class(variable, parent, body) {
this.variable = variable;
this.parent = parent;
this.body = body != null ? body : new Block(this.locationData);
this.body = body != null ? body : new Block;
this.boundFuncs = [];
this.body.classBody = true;
}
@ -1353,8 +1350,8 @@
_results = [];
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
bvar = _ref2[_i];
lhs = (new Value(this.locationData, new Literal(this.locationData, "this"), [new Access(this.locationData, bvar)])).compile(o);
_results.push(this.ctor.body.unshift(new Literal(this.locationData, "" + lhs + " = " + (utility('bind')) + "(" + lhs + ", this)")));
lhs = (new Value(new Literal("this"), [new Access(bvar)])).compile(o);
_results.push(this.ctor.body.unshift(new Literal("" + lhs + " = " + (utility('bind')) + "(" + lhs + ", this)")));
}
return _results;
}
@ -1382,7 +1379,7 @@
assign = this.ctor = func;
} else {
this.externalCtor = o.scope.freeVariable('class');
assign = new Assign(this.locationData, new Literal(this.locationData, this.externalCtor), func);
assign = new Assign(new Literal(this.externalCtor), func);
}
} else {
if (assign.variable["this"]) {
@ -1391,7 +1388,7 @@
func.context = name;
}
} else {
assign.variable = new Value(this.locationData, new Literal(this.locationData, name), [new Access(this.locationData, new Literal(this.locationData, 'prototype')), new Access(this.locationData, base)]);
assign.variable = new Value(new Literal(name), [new Access(new Literal('prototype')), new Access(base)]);
if (func instanceof Code && func.bound) {
this.boundFuncs.push(base);
func.bound = false;
@ -1438,12 +1435,12 @@
Class.prototype.ensureConstructor = function(name) {
if (!this.ctor) {
this.ctor = new Code(this.locationData);
this.ctor = new Code;
if (this.parent) {
this.ctor.body.push(new Literal(this.locationData, "" + name + ".__super__.constructor.apply(this, arguments)"));
this.ctor.body.push(new Literal("" + name + ".__super__.constructor.apply(this, arguments)"));
}
if (this.externalCtor) {
this.ctor.body.push(new Literal(this.locationData, "" + this.externalCtor + ".apply(this, arguments)"));
this.ctor.body.push(new Literal("" + this.externalCtor + ".apply(this, arguments)"));
}
this.ctor.body.makeReturn();
this.body.expressions.unshift(this.ctor);
@ -1460,7 +1457,7 @@
if (name.reserved) {
name = "_" + name;
}
lname = new Literal(this.locationData, name);
lname = new Literal(name);
this.hoistDirectivePrologue();
this.setContext(name);
this.walkBody(name, o);
@ -1472,17 +1469,17 @@
this.body.expressions.push(lname);
(_ref2 = this.body.expressions).unshift.apply(_ref2, this.directives);
this.addBoundFunctions(o);
call = Closure.wrap(this.locationData, this.body);
call = Closure.wrap(this.body);
if (this.parent) {
this.superClass = new Literal(this.locationData, o.scope.freeVariable('super', false));
this.body.expressions.unshift(new Extends(this.locationData, lname, this.superClass));
this.superClass = new Literal(o.scope.freeVariable('super', false));
this.body.expressions.unshift(new Extends(lname, this.superClass));
call.args.push(this.parent);
params = call.variable.params || call.variable.base.params;
params.push(new Param(this.locationData, this.superClass));
params.push(new Param(this.superClass));
}
klass = new Parens(this.locationData, call, true);
klass = new Parens(call, true);
if (this.variable) {
klass = new Assign(this.locationData, this.variable, klass);
klass = new Assign(this.variable, klass);
}
return klass.compile(o);
};
@ -1495,9 +1492,8 @@
__extends(Assign, _super);
function Assign(locationData, variable, value, context, options) {
function Assign(variable, value, context, options) {
var forbidden, name, _ref2;
this.locationData = locationData;
this.variable = variable;
this.value = value;
this.context = context;
@ -1586,18 +1582,18 @@
_ref2 = obj, (_ref3 = _ref2.variable, idx = _ref3.base), obj = _ref2.value;
} else {
if (obj.base instanceof Parens) {
_ref4 = new Value(this.locationData, obj.unwrapAll()).cacheReference(o), obj = _ref4[0], idx = _ref4[1];
_ref4 = new Value(obj.unwrapAll()).cacheReference(o), obj = _ref4[0], idx = _ref4[1];
} else {
idx = isObject ? obj["this"] ? obj.properties[0].name : obj : new Literal(this.locationData, 0);
idx = isObject ? obj["this"] ? obj.properties[0].name : obj : new Literal(0);
}
}
acc = IDENTIFIER.test(idx.unwrap().value || 0);
value = new Value(this.locationData, value);
value.properties.push(new (acc ? Access : Index)(this.locationData, idx));
value = new Value(value);
value.properties.push(new (acc ? Access : Index)(idx));
if (_ref5 = obj.unwrap().value, __indexOf.call(RESERVED, _ref5) >= 0) {
throw new SyntaxError("assignment to a reserved word: " + (obj.compile(o)) + " = " + (value.compile(o)));
}
return new Assign(this.locationData, obj, value, null, {
return new Assign(obj, value, null, {
param: this.param
}).compile(o, LEVEL_TOP);
}
@ -1616,7 +1612,7 @@
_ref6 = obj, (_ref7 = _ref6.variable, idx = _ref7.base), obj = _ref6.value;
} else {
if (obj.base instanceof Parens) {
_ref8 = new Value(this.locationData, obj.unwrapAll()).cacheReference(o), obj = _ref8[0], idx = _ref8[1];
_ref8 = new Value(obj.unwrapAll()).cacheReference(o), obj = _ref8[0], idx = _ref8[1];
} else {
idx = obj["this"] ? obj.properties[0].name : obj;
}
@ -1632,7 +1628,7 @@
} else {
val += ") : []";
}
val = new Literal(this.locationData, val);
val = new Literal(val);
splat = "" + ivar + "++";
} else {
name = obj.unwrap().value;
@ -1641,17 +1637,17 @@
throw new SyntaxError("multiple splats are disallowed in an assignment: " + obj + "...");
}
if (typeof idx === 'number') {
idx = new Literal(this.locationData, splat || idx);
idx = new Literal(splat || idx);
acc = false;
} else {
acc = isObject && IDENTIFIER.test(idx.unwrap().value || 0);
}
val = new Value(this.locationData, new Literal(this.locationData, vvar), [new (acc ? Access : Index)(this.locationData, idx)]);
val = new Value(new Literal(vvar), [new (acc ? Access : Index)(idx)]);
}
if ((name != null) && __indexOf.call(RESERVED, name) >= 0) {
throw new SyntaxError("assignment to a reserved word: " + (obj.compile(o)) + " = " + (val.compile(o)));
}
assigns.push(new Assign(this.locationData, obj, val, null, {
assigns.push(new Assign(obj, val, null, {
param: this.param,
subpattern: true
}).compile(o, LEVEL_LIST));
@ -1676,7 +1672,7 @@
if (__indexOf.call(this.context, "?") >= 0) {
o.isExistentialEquals = true;
}
return new Op(this.locationData, this.context.slice(0, -1), left, new Assign(this.locationData, right, this.value, '=')).compile(o);
return new Op(this.context.slice(0, -1), left, new Assign(right, this.value, '=')).compile(o);
};
Assign.prototype.compileSplice = function(o) {
@ -1716,10 +1712,9 @@
__extends(Code, _super);
function Code(locationData, params, body, tag) {
this.locationData = locationData;
function Code(params, body, tag) {
this.params = params || [];
this.body = body || new Block(this.locationData);
this.body = body || new Block;
this.bound = tag === 'boundfunc';
if (this.bound) {
this.context = '_this';
@ -1766,7 +1761,7 @@
o.scope.add(p.value, 'var', true);
}
}
splats = new Assign(this.locationData, new Value(this.locationData, new Arr(this.locationData, (function() {
splats = new Assign(new Value(new Arr((function() {
var _l, _len3, _ref5, _results;
_ref5 = this.params;
_results = [];
@ -1775,7 +1770,7 @@
_results.push(p.asReference(o));
}
return _results;
}).call(this))), new Value(this.locationData, new Literal(this.locationData, 'arguments')));
}).call(this))), new Value(new Literal('arguments')));
break;
}
_ref5 = this.params;
@ -1784,17 +1779,17 @@
if (param.isComplex()) {
val = ref = param.asReference(o);
if (param.value) {
val = new Op(this.locationData, '?', ref, param.value);
val = new Op('?', ref, param.value);
}
exprs.push(new Assign(this.locationData, new Value(this.locationData, param.name), val, '=', {
exprs.push(new Assign(new Value(param.name), val, '=', {
param: true
}));
} else {
ref = param;
if (param.value) {
lit = new Literal(this.locationData, ref.name.value + ' == null');
val = new Assign(this.locationData, new Value(this.locationData, param.name), param.value, '=');
exprs.push(new If(this.locationData, lit, val));
lit = new Literal(ref.name.value + ' == null');
val = new Assign(new Value(param.name), param.value, '=');
exprs.push(new If(lit, val));
}
}
if (!splats) {
@ -1876,9 +1871,8 @@
__extends(Param, _super);
function Param(locationData, name, value, splat) {
function Param(name, value, splat) {
var _ref2;
this.locationData = locationData;
this.name = name;
this.value = value;
this.splat = splat;
@ -1902,14 +1896,14 @@
if (node["this"]) {
node = node.properties[0].name;
if (node.value.reserved) {
node = new Literal(this.locationData, o.scope.freeVariable(node.value));
node = new Literal(o.scope.freeVariable(node.value));
}
} else if (node.isComplex()) {
node = new Literal(this.locationData, o.scope.freeVariable('arg'));
node = new Literal(o.scope.freeVariable('arg'));
}
node = new Value(this.locationData, node);
node = new Value(node);
if (this.splat) {
node = new Splat(this.locationData, node);
node = new Splat(node);
}
return this.reference = node;
};
@ -1973,9 +1967,8 @@
Splat.prototype.isAssignable = YES;
function Splat(locationData, name) {
this.locationData = locationData;
this.name = name.compile ? name : new Literal(this.locationData, name);
function Splat(name) {
this.name = name.compile ? name : new Literal(name);
}
Splat.prototype.assigns = function(name) {
@ -2040,8 +2033,7 @@
__extends(While, _super);
function While(locationData, condition, options) {
this.locationData = locationData;
function While(condition, options) {
this.condition = (options != null ? options.invert : void 0) ? condition.invert() : condition;
this.guard = options != null ? options.guard : void 0;
}
@ -2097,10 +2089,10 @@
}
if (this.guard) {
if (body.expressions.length > 1) {
body.expressions.unshift(new If(this.locationData, new Parens(this.locationData, this.guard)).invert(), new Literal(this.locationData, "continue"));
body.expressions.unshift(new If((new Parens(this.guard)).invert(), new Literal("continue")));
} else {
if (this.guard) {
body = Block.wrap(this.locationData, [new If(this.locationData, this.guard, body)]);
body = Block.wrap([new If(this.guard, body)]);
}
}
}
@ -2122,10 +2114,9 @@
__extends(Op, _super);
function Op(locationData, op, first, second, flip) {
this.locationData = locationData;
function Op(op, first, second, flip) {
if (op === 'in') {
return new In(this.locationData, first, second);
return new In(first, second);
}
if (op === 'do') {
return this.generateDo(first);
@ -2135,7 +2126,7 @@
return first.newInstance();
}
if (first instanceof Code && first.bound || first["do"]) {
first = new Parens(this.locationData, first);
first = new Parens(first);
}
}
this.operator = CONVERSIONS[op] || op;
@ -2184,7 +2175,7 @@
curr = curr.first;
}
if (!allInvertable) {
return new Parens(this.locationData, this).invert();
return new Parens(this).invert();
}
curr = this;
while (curr && curr.operator) {
@ -2200,11 +2191,11 @@
}
return this;
} else if (this.second) {
return new Parens(this.locationData, this).invert();
return new Parens(this).invert();
} else if (this.operator === '!' && (fst = this.first.unwrap()) instanceof Op && ((_ref2 = fst.operator) === '!' || _ref2 === 'in' || _ref2 === 'instanceof')) {
return fst;
} else {
return new Op(this.locationData, '!', this);
return new Op('!', this);
}
};
@ -2227,7 +2218,7 @@
passedParams.push(param);
}
}
call = new Call(this.locationData, exp, passedParams);
call = new Call(exp, passedParams);
call["do"] = true;
return call;
};
@ -2272,13 +2263,13 @@
Op.prototype.compileExistence = function(o) {
var fst, ref;
if (this.first.isComplex()) {
ref = new Literal(this.locationData, o.scope.freeVariable('ref'));
fst = new Parens(this.locationData, new Assign(this.locationData, ref, this.first));
ref = new Literal(o.scope.freeVariable('ref'));
fst = new Parens(new Assign(ref, this.first));
} else {
fst = this.first;
ref = fst;
}
return new If(this.locationData, new Existence(this.locationData, fst), ref, {
return new If(new Existence(fst), ref, {
type: 'if'
}).addElse(this.second).compile(o);
};
@ -2291,14 +2282,14 @@
return this.first.compile(o);
}
if (o.level >= LEVEL_ACCESS) {
return (new Parens(this.locationData, this)).compile(o);
return (new Parens(this)).compile(o);
}
plusMinus = op === '+' || op === '-';
if ((op === 'new' || op === 'typeof' || op === 'delete') || plusMinus && this.first instanceof Op && this.first.operator === op) {
parts.push(' ');
}
if ((plusMinus && this.first instanceof Op) || (op === 'new' && this.first.isStatement(o))) {
this.first = new Parens(this.locationData, this.first);
this.first = new Parens(this.first);
}
parts.push(this.first.compile(o, LEVEL_OP));
if (this.flip) {
@ -2319,8 +2310,7 @@
__extends(In, _super);
function In(locationData, object, array) {
this.locationData = locationData;
function In(object, array) {
this.object = object;
this.array = array;
}
@ -2400,8 +2390,7 @@
__extends(Try, _super);
function Try(locationData, attempt, error, recovery, ensure) {
this.locationData = locationData;
function Try(attempt, error, recovery, ensure) {
this.attempt = attempt;
this.error = error;
this.recovery = recovery;
@ -2435,8 +2424,8 @@
var _base, _ref2;
if (this.recovery) {
if (typeof (_base = this.error).isObject === "function" ? _base.isObject() : void 0) {
placeholder = new Literal(this.locationData, '_error');
this.recovery.unshift(new Assign(this.locationData, this.error, placeholder));
placeholder = new Literal('_error');
this.recovery.unshift(new Assign(this.error, placeholder));
this.error = placeholder;
}
if (_ref2 = this.error.value, __indexOf.call(STRICT_PROSCRIBED, _ref2) >= 0) {
@ -2462,8 +2451,7 @@
__extends(Throw, _super);
function Throw(locationData, expression) {
this.locationData = locationData;
function Throw(expression) {
this.expression = expression;
}
@ -2487,8 +2475,7 @@
__extends(Existence, _super);
function Existence(locationData, expression) {
this.locationData = locationData;
function Existence(expression) {
this.expression = expression;
}
@ -2521,8 +2508,7 @@
__extends(Parens, _super);
function Parens(locationData, body) {
this.locationData = locationData;
function Parens(body) {
this.body = body;
}
@ -2560,11 +2546,10 @@
__extends(For, _super);
function For(locationData, body, source) {
function For(body, source) {
var _ref2;
this.locationData = locationData;
this.source = source.source, this.guard = source.guard, this.step = source.step, this.name = source.name, this.index = source.index;
this.body = Block.wrap(this.locationData, [body]);
this.body = Block.wrap([body]);
this.own = !!source.own;
this.object = !!source.object;
if (this.object) {
@ -2588,7 +2573,7 @@
For.prototype.compileNode = function(o) {
var body, defPart, forPart, forVarPart, guardPart, idt1, index, ivar, kvar, kvarAssign, lastJumps, lvar, name, namePart, ref, resultPart, returnResult, rvar, scope, source, stepPart, stepvar, svar, varPart, _ref2;
body = Block.wrap(this.locationData, [this.body]);
body = Block.wrap([this.body]);
lastJumps = (_ref2 = last(body.expressions)) != null ? _ref2.jumps() : void 0;
if (lastJumps && lastJumps instanceof Return) {
this.returns = false;
@ -2651,15 +2636,15 @@
}
if (this.guard) {
if (body.expressions.length > 1) {
body.expressions.unshift(new If(this.locationData, (new Parens(this.locationData, this.guard)).invert(), new Literal(this.locationData, "continue")));
body.expressions.unshift(new If((new Parens(this.guard)).invert(), new Literal("continue")));
} else {
if (this.guard) {
body = Block.wrap(this.locationData, [new If(this.locationData, this.guard, body)]);
body = Block.wrap([new If(this.guard, body)]);
}
}
}
if (this.pattern) {
body.expressions.unshift(new Assign(this.locationData, this.name, new Literal(this.locationData, "" + svar + "[" + kvar + "]")));
body.expressions.unshift(new Assign(this.name, new Literal("" + svar + "[" + kvar + "]")));
}
defPart += this.pluckDirectCall(o, body);
if (namePart) {
@ -2695,13 +2680,13 @@
continue;
}
fn = ((_ref6 = val.base) != null ? _ref6.unwrapAll() : void 0) || val;
ref = new Literal(this.locationData, o.scope.freeVariable('fn'));
base = new Value(this.locationData, ref);
ref = new Literal(o.scope.freeVariable('fn'));
base = new Value(ref);
if (val.base) {
_ref7 = [base, val], val.base = _ref7[0], base = _ref7[1];
}
body.expressions[idx] = new Call(this.locationData, base, expr.args);
defs += this.tab + new Assign(this.locationData, ref, fn).compile(o, LEVEL_TOP) + ';\n';
body.expressions[idx] = new Call(base, expr.args);
defs += this.tab + new Assign(ref, fn).compile(o, LEVEL_TOP) + ';\n';
}
return defs;
};
@ -2714,8 +2699,7 @@
__extends(Switch, _super);
function Switch(locationData, subject, cases, otherwise) {
this.locationData = locationData;
function Switch(subject, cases, otherwise) {
this.subject = subject;
this.cases = cases;
this.otherwise = otherwise;
@ -2750,7 +2734,7 @@
pair[1].makeReturn(res);
}
if (res) {
this.otherwise || (this.otherwise = new Block(this.locationData, [new Literal(this.locationData, 'void 0')]));
this.otherwise || (this.otherwise = new Block([new Literal('void 0')]));
}
if ((_ref3 = this.otherwise) != null) {
_ref3.makeReturn(res);
@ -2800,8 +2784,7 @@
__extends(If, _super);
function If(locationData, condition, body, options) {
this.locationData = locationData;
function If(condition, body, options) {
this.body = body;
if (options == null) {
options = {};
@ -2854,10 +2837,10 @@
If.prototype.makeReturn = function(res) {
if (res) {
this.elseBody || (this.elseBody = new Block(this.locationData, [new Literal(this.locationData, 'void 0')]));
this.elseBody || (this.elseBody = new Block([new Literal('void 0')]));
}
this.body && (this.body = new Block(this.locationData, [this.body.makeReturn(res)]));
this.elseBody && (this.elseBody = new Block(this.locationData, [this.elseBody.makeReturn(res)]));
this.body && (this.body = new Block([this.body.makeReturn(res)]));
this.elseBody && (this.elseBody = new Block([this.elseBody.makeReturn(res)]));
return this;
};
@ -2865,7 +2848,7 @@
if (node instanceof Block) {
return node;
} else {
return new Block(this.locationData, [node]);
return new Block([node]);
}
};
@ -2874,7 +2857,7 @@
child = del(o, 'chainChild');
exeq = del(o, 'isExistentialEquals');
if (exeq) {
return new If(this.locationData, this.condition.invert(), this.elseBodyNode(), {
return new If(this.condition.invert(), this.elseBodyNode(), {
type: 'if'
}).compile(o);
}
@ -2913,25 +2896,25 @@
})(Base);
Closure = {
wrap: function(locationData, expressions, statement, noReturn) {
wrap: function(expressions, statement, noReturn) {
var args, call, func, mentionsArgs, meth;
if (expressions.jumps()) {
return expressions;
}
func = new Code(locationData, [], Block.wrap(locationData, [expressions]));
func = new Code([], Block.wrap([expressions]));
args = [];
if ((mentionsArgs = expressions.contains(this.literalArgs)) || expressions.contains(this.literalThis)) {
meth = new Literal(locationData, mentionsArgs ? 'apply' : 'call');
args = [new Literal(locationData, 'this')];
meth = new Literal(mentionsArgs ? 'apply' : 'call');
args = [new Literal('this')];
if (mentionsArgs) {
args.push(new Literal(locationData, 'arguments'));
args.push(new Literal('arguments'));
}
func = new Value(this.locationData, func, [new Access(locationData, meth)]);
func = new Value(func, [new Access(meth)]);
}
func.noReturn = noReturn;
call = new Call(locationData, func, args);
call = new Call(func, args);
if (statement) {
return Block.wrap(locationData, [call]);
return Block.wrap([call]);
} else {
return call;
}
@ -2950,7 +2933,7 @@
return;
}
parent[name] = ifn.body;
ifn.body = new Value(this.locationData, parent);
ifn.body = new Value(parent);
return ifn;
};

View File

@ -9,15 +9,15 @@ performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
var $0 = $$.length - 1;
switch (yystate) {
case 1:return this.$ = new yy.Block(_$[$0]);
case 1:return this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Block);
break;
case 2:return this.$ = $$[$0];
break;
case 3:return this.$ = $$[$0-1];
break;
case 4:this.$ = yy.Block.wrap(_$[$0], [$$[$0]]);
case 4:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(yy.Block.wrap([$$[$0]]));
break;
case 5:this.$ = $$[$0-2].push($$[$0]);
case 5:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])($$[$0-2].push($$[$0]));
break;
case 6:this.$ = $$[$0-1];
break;
@ -29,7 +29,7 @@ case 9:this.$ = $$[$0];
break;
case 10:this.$ = $$[$0];
break;
case 11:this.$ = new yy.Literal(_$[$0], $$[$0]);
case 11:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Literal($$[$0]));
break;
case 12:this.$ = $$[$0];
break;
@ -55,41 +55,41 @@ case 22:this.$ = $$[$0];
break;
case 23:this.$ = $$[$0];
break;
case 24:this.$ = new yy.Block(_$[$0-1]);
case 24:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Block);
break;
case 25:this.$ = $$[$0-1];
case 25:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])($$[$0-1]);
break;
case 26:this.$ = new yy.Literal(_$[$0], $$[$0]);
case 26:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Literal($$[$0]));
break;
case 27:this.$ = new yy.Literal(_$[$0], $$[$0]);
case 27:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Literal($$[$0]));
break;
case 28:this.$ = new yy.Literal(_$[$0], $$[$0]);
case 28:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Literal($$[$0]));
break;
case 29:this.$ = $$[$0];
break;
case 30:this.$ = new yy.Literal(_$[$0], $$[$0]);
case 30:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Literal($$[$0]));
break;
case 31:this.$ = new yy.Literal(_$[$0], $$[$0]);
case 31:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Literal($$[$0]));
break;
case 32:this.$ = new yy.Literal(_$[$0], $$[$0]);
case 32:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Literal($$[$0]));
break;
case 33:this.$ = new yy.Undefined(_$[$0]);
case 33:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Undefined);
break;
case 34:this.$ = new yy.Null(_$[$0]);
case 34:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Null);
break;
case 35:this.$ = new yy.Bool(_$[$0], $$[$0]);
case 35:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Bool($$[$0]));
break;
case 36:this.$ = new yy.Assign((function(){loc = {}; loc.first_column = _$[$0-2].first_column; loc.first_line = _$[$0-2].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), $$[$0-2], $$[$0]);
case 36:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Assign($$[$0-2], $$[$0]));
break;
case 37:this.$ = new yy.Assign((function(){loc = {}; loc.first_column = _$[$0-3].first_column; loc.first_line = _$[$0-3].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), $$[$0-3], $$[$0]);
case 37:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.Assign($$[$0-3], $$[$0]));
break;
case 38:this.$ = new yy.Assign((function(){loc = {}; loc.first_column = _$[$0-4].first_column; loc.first_line = _$[$0-4].first_line; loc.last_column = _$[$0-1].last_column; loc.last_line = _$[$0-1].last_line; return loc;})(), $$[$0-4], $$[$0-1]);
case 38:this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Assign($$[$0-4], $$[$0-1]));
break;
case 39:this.$ = new yy.Value(_$[$0], $$[$0]);
case 39:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Value($$[$0]));
break;
case 40:this.$ = new yy.Assign((function(){loc = {}; loc.first_column = _$[$0-2].first_column; loc.first_line = _$[$0-2].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), new yy.Value(_$[$0-2], $$[$0-2]), $$[$0], 'object');
case 40:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Assign(yy.addLocationDataFn(_$[$0-2])(new yy.Value($$[$0-2])), $$[$0], 'object'));
break;
case 41:this.$ = new yy.Assign((function(){loc = {}; loc.first_column = _$[$0-4].first_column; loc.first_line = _$[$0-4].first_line; loc.last_column = _$[$0-1].last_column; loc.last_line = _$[$0-1].last_line; return loc;})(), new yy.Value(_$[$0-4], $$[$0-4]), $$[$0-1], 'object');
case 41:this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Assign(yy.addLocationDataFn(_$[$0-4])(new yy.Value($$[$0-4])), $$[$0-1], 'object'));
break;
case 42:this.$ = $$[$0];
break;
@ -99,39 +99,39 @@ case 44:this.$ = $$[$0];
break;
case 45:this.$ = $$[$0];
break;
case 46:this.$ = new yy.Return((function(){loc = {}; loc.first_column = _$[$0-1].first_column; loc.first_line = _$[$0-1].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), $$[$0]);
case 46:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Return($$[$0]));
break;
case 47:this.$ = new yy.Return(_$[$0]);
case 47:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Return);
break;
case 48:this.$ = new yy.Comment(_$[$0], $$[$0]);
case 48:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Comment($$[$0]));
break;
case 49:this.$ = new yy.Code((function(){loc = {}; loc.first_column = _$[$0-4].first_column; loc.first_line = _$[$0-4].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), $$[$0-3], $$[$0], $$[$0-1]);
case 49:this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Code($$[$0-3], $$[$0], $$[$0-1]));
break;
case 50:this.$ = new yy.Code((function(){loc = {}; loc.first_column = _$[$0-1].first_column; loc.first_line = _$[$0-1].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), [], $$[$0], $$[$0-1]);
case 50:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Code([], $$[$0], $$[$0-1]));
break;
case 51:this.$ = 'func';
case 51:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])('func');
break;
case 52:this.$ = 'boundfunc';
case 52:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])('boundfunc');
break;
case 53:this.$ = $$[$0];
break;
case 54:this.$ = $$[$0];
break;
case 55:this.$ = [];
case 55:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])([]);
break;
case 56:this.$ = [$$[$0]];
case 56:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])([$$[$0]]);
break;
case 57:this.$ = $$[$0-2].concat($$[$0]);
case 57:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])($$[$0-2].concat($$[$0]));
break;
case 58:this.$ = $$[$0-3].concat($$[$0]);
case 58:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])($$[$0-3].concat($$[$0]));
break;
case 59:this.$ = $$[$0-5].concat($$[$0-2]);
case 59:this.$ = yy.addLocationDataFn(_$[$0-5], _$[$0])($$[$0-5].concat($$[$0-2]));
break;
case 60:this.$ = new yy.Param(_$[$0], $$[$0]);
case 60:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Param($$[$0]));
break;
case 61:this.$ = new yy.Param(_$[$0-1], $$[$0-1], null, true);
case 61:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Param($$[$0-1], null, true));
break;
case 62:this.$ = new yy.Param((function(){loc = {}; loc.first_column = _$[$0-2].first_column; loc.first_line = _$[$0-2].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), $$[$0-2], $$[$0]);
case 62:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Param($$[$0-2], $$[$0]));
break;
case 63:this.$ = $$[$0];
break;
@ -141,129 +141,129 @@ case 65:this.$ = $$[$0];
break;
case 66:this.$ = $$[$0];
break;
case 67:this.$ = new yy.Splat(_$[$0-1], $$[$0-1]);
case 67:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Splat($$[$0-1]));
break;
case 68:this.$ = new yy.Value(_$[$0], $$[$0]);
case 68:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Value($$[$0]));
break;
case 69:this.$ = $$[$0-1].add($$[$0]);
case 69:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])($$[$0-1].add($$[$0]));
break;
case 70:this.$ = new yy.Value((function(){loc = {}; loc.first_column = _$[$0-1].first_column; loc.first_line = _$[$0-1].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), $$[$0-1], [].concat($$[$0]));
case 70:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Value($$[$0-1], [].concat($$[$0])));
break;
case 71:this.$ = $$[$0];
break;
case 72:this.$ = $$[$0];
break;
case 73:this.$ = new yy.Value(_$[$0], $$[$0]);
case 73:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Value($$[$0]));
break;
case 74:this.$ = new yy.Value(_$[$0], $$[$0]);
case 74:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Value($$[$0]));
break;
case 75:this.$ = $$[$0];
break;
case 76:this.$ = new yy.Value(_$[$0], $$[$0]);
case 76:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Value($$[$0]));
break;
case 77:this.$ = new yy.Value(_$[$0], $$[$0]);
case 77:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Value($$[$0]));
break;
case 78:this.$ = new yy.Value(_$[$0], $$[$0]);
case 78:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Value($$[$0]));
break;
case 79:this.$ = $$[$0];
break;
case 80:this.$ = new yy.Access((function(){loc = {}; loc.first_column = _$[$0-1].first_column; loc.first_line = _$[$0-1].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), $$[$0]);
case 80:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Access($$[$0]));
break;
case 81:this.$ = new yy.Access((function(){loc = {}; loc.first_column = _$[$0-1].first_column; loc.first_line = _$[$0-1].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), $$[$0], 'soak');
case 81:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Access($$[$0], 'soak'));
break;
case 82:this.$ = [new yy.Access(_$[$0-1], new yy.Literal(_$[$0-1], 'prototype')), new yy.Access(_$[$0-1], $$[$0])];
case 82:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])([yy.addLocationDataFn(_$[$0-1])(new yy.Access(new yy.Literal('prototype'))), yy.addLocationDataFn(_$[$0])(new yy.Access($$[$0]))]);
break;
case 83:this.$ = new yy.Access(_$[$0], new yy.Literal(_$[$0], 'prototype'));
case 83:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Access(new yy.Literal('prototype')));
break;
case 84:this.$ = $$[$0];
break;
case 85:this.$ = $$[$0-1];
case 85:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])($$[$0-1]);
break;
case 86:this.$ = yy.extend($$[$0], {
case 86:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(yy.extend($$[$0], {
soak: true
});
}));
break;
case 87:this.$ = new yy.Index(_$[$0], $$[$0]);
case 87:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Index($$[$0]));
break;
case 88:this.$ = new yy.Slice(_$[$0], $$[$0]);
case 88:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Slice($$[$0]));
break;
case 89:this.$ = new yy.Obj((function(){loc = {}; loc.first_column = _$[$0-3].first_column; loc.first_line = _$[$0-3].first_line; loc.last_column = _$[$0-2].last_column; loc.last_line = _$[$0-2].last_line; return loc;})(), $$[$0-2], $$[$0-3].generated);
case 89:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.Obj($$[$0-2], $$[$0-3].generated));
break;
case 90:this.$ = [];
case 90:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])([]);
break;
case 91:this.$ = [$$[$0]];
case 91:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])([$$[$0]]);
break;
case 92:this.$ = $$[$0-2].concat($$[$0]);
case 92:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])($$[$0-2].concat($$[$0]));
break;
case 93:this.$ = $$[$0-3].concat($$[$0]);
case 93:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])($$[$0-3].concat($$[$0]));
break;
case 94:this.$ = $$[$0-5].concat($$[$0-2]);
case 94:this.$ = yy.addLocationDataFn(_$[$0-5], _$[$0])($$[$0-5].concat($$[$0-2]));
break;
case 95:this.$ = new yy.Class(_$[$0]);
case 95:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Class);
break;
case 96:this.$ = new yy.Class((function(){loc = {}; loc.first_column = _$[$0-1].first_column; loc.first_line = _$[$0-1].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), null, null, $$[$0]);
case 96:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Class(null, null, $$[$0]));
break;
case 97:this.$ = new yy.Class((function(){loc = {}; loc.first_column = _$[$0-2].first_column; loc.first_line = _$[$0-2].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), null, $$[$0]);
case 97:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Class(null, $$[$0]));
break;
case 98:this.$ = new yy.Class((function(){loc = {}; loc.first_column = _$[$0-3].first_column; loc.first_line = _$[$0-3].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), null, $$[$0-1], $$[$0]);
case 98:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.Class(null, $$[$0-1], $$[$0]));
break;
case 99:this.$ = new yy.Class((function(){loc = {}; loc.first_column = _$[$0-1].first_column; loc.first_line = _$[$0-1].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), $$[$0]);
case 99:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Class($$[$0]));
break;
case 100:this.$ = new yy.Class((function(){loc = {}; loc.first_column = _$[$0-2].first_column; loc.first_line = _$[$0-2].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), $$[$0-1], null, $$[$0]);
case 100:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Class($$[$0-1], null, $$[$0]));
break;
case 101:this.$ = new yy.Class((function(){loc = {}; loc.first_column = _$[$0-3].first_column; loc.first_line = _$[$0-3].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), $$[$0-2], $$[$0]);
case 101:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.Class($$[$0-2], $$[$0]));
break;
case 102:this.$ = new yy.Class((function(){loc = {}; loc.first_column = _$[$0-4].first_column; loc.first_line = _$[$0-4].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), $$[$0-3], $$[$0-1], $$[$0]);
case 102:this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Class($$[$0-3], $$[$0-1], $$[$0]));
break;
case 103:this.$ = new yy.Call((function(){loc = {}; loc.first_column = _$[$0-2].first_column; loc.first_line = _$[$0-2].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), $$[$0-2], $$[$0], $$[$0-1]);
case 103:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Call($$[$0-2], $$[$0], $$[$0-1]));
break;
case 104:this.$ = new yy.Call((function(){loc = {}; loc.first_column = _$[$0-2].first_column; loc.first_line = _$[$0-2].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), $$[$0-2], $$[$0], $$[$0-1]);
case 104:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Call($$[$0-2], $$[$0], $$[$0-1]));
break;
case 105:this.$ = new yy.Call(_$[$0], 'super', [new yy.Splat(_$[$0], new yy.Literal(_$[$0], 'arguments'))]);
case 105:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Call('super', [new yy.Splat(new yy.Literal('arguments'))]));
break;
case 106:this.$ = new yy.Call((function(){loc = {}; loc.first_column = _$[$0-1].first_column; loc.first_line = _$[$0-1].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), 'super', $$[$0]);
case 106:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Call('super', $$[$0]));
break;
case 107:this.$ = false;
case 107:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(false);
break;
case 108:this.$ = true;
case 108:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(true);
break;
case 109:this.$ = [];
case 109:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])([]);
break;
case 110:this.$ = $$[$0-2];
case 110:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])($$[$0-2]);
break;
case 111:this.$ = new yy.Value(_$[$0], new yy.Literal(_$[$0], 'this'));
case 111:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Value(new yy.Literal('this')));
break;
case 112:this.$ = new yy.Value(_$[$0], new yy.Literal(_$[$0], 'this'));
case 112:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Value(new yy.Literal('this')));
break;
case 113:this.$ = new yy.Value((function(){loc = {}; loc.first_column = _$[$0-1].first_column; loc.first_line = _$[$0-1].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), new yy.Literal(_$[$0-1], 'this'), [new yy.Access(_$[$0], $$[$0])], 'this');
case 113:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Value(yy.addLocationDataFn(_$[$0-1])(new yy.Literal('this')), [yy.addLocationDataFn(_$[$0])(new yy.Access($$[$0]))], 'this'));
break;
case 114:this.$ = new yy.Arr(_$[$0-1], []);
case 114:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Arr([]));
break;
case 115:this.$ = new yy.Arr((function(){loc = {}; loc.first_column = _$[$0-3].first_column; loc.first_line = _$[$0-3].first_line; loc.last_column = _$[$0-2].last_column; loc.last_line = _$[$0-2].last_line; return loc;})(), $$[$0-2]);
case 115:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.Arr($$[$0-2]));
break;
case 116:this.$ = 'inclusive';
case 116:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])('inclusive');
break;
case 117:this.$ = 'exclusive';
case 117:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])('exclusive');
break;
case 118:this.$ = new yy.Range((function(){loc = {}; loc.first_column = _$[$0-4].first_column; loc.first_line = _$[$0-4].first_line; loc.last_column = _$[$0-1].last_column; loc.last_line = _$[$0-1].last_line; return loc;})(), $$[$0-3], $$[$0-1], $$[$0-2]);
case 118:this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Range($$[$0-3], $$[$0-1], $$[$0-2]));
break;
case 119:this.$ = new yy.Range((function(){loc = {}; loc.first_column = _$[$0-2].first_column; loc.first_line = _$[$0-2].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), $$[$0-2], $$[$0], $$[$0-1]);
case 119:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Range($$[$0-2], $$[$0], $$[$0-1]));
break;
case 120:this.$ = new yy.Range((function(){loc = {}; loc.first_column = _$[$0-1].first_column; loc.first_line = _$[$0-1].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), $$[$0-1], null, $$[$0]);
case 120:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Range($$[$0-1], null, $$[$0]));
break;
case 121:this.$ = new yy.Range((function(){loc = {}; loc.first_column = _$[$0-1].first_column; loc.first_line = _$[$0-1].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), null, $$[$0], $$[$0-1]);
case 121:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Range(null, $$[$0], $$[$0-1]));
break;
case 122:this.$ = new yy.Range(_$[$0], null, null, $$[$0]);
case 122:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Range(null, null, $$[$0]));
break;
case 123:this.$ = [$$[$0]];
case 123:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])([$$[$0]]);
break;
case 124:this.$ = $$[$0-2].concat($$[$0]);
case 124:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])($$[$0-2].concat($$[$0]));
break;
case 125:this.$ = $$[$0-3].concat($$[$0]);
case 125:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])($$[$0-3].concat($$[$0]));
break;
case 126:this.$ = $$[$0-2];
case 126:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])($$[$0-2]);
break;
case 127:this.$ = $$[$0-5].concat($$[$0-2]);
case 127:this.$ = yy.addLocationDataFn(_$[$0-5], _$[$0])($$[$0-5].concat($$[$0-2]));
break;
case 128:this.$ = $$[$0];
break;
@ -271,205 +271,205 @@ case 129:this.$ = $$[$0];
break;
case 130:this.$ = $$[$0];
break;
case 131:this.$ = [].concat($$[$0-2], $$[$0]);
case 131:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])([].concat($$[$0-2], $$[$0]));
break;
case 132:this.$ = new yy.Try((function(){loc = {}; loc.first_column = _$[$0-1].first_column; loc.first_line = _$[$0-1].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), $$[$0]);
case 132:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Try($$[$0]));
break;
case 133:this.$ = new yy.Try((function(){loc = {}; loc.first_column = _$[$0-2].first_column; loc.first_line = _$[$0-2].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), $$[$0-1], $$[$0][0], $$[$0][1]);
case 133:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Try($$[$0-1], $$[$0][0], $$[$0][1]));
break;
case 134:this.$ = new yy.Try((function(){loc = {}; loc.first_column = _$[$0-3].first_column; loc.first_line = _$[$0-3].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), $$[$0-2], null, null, $$[$0]);
case 134:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.Try($$[$0-2], null, null, $$[$0]));
break;
case 135:this.$ = new yy.Try((function(){loc = {}; loc.first_column = _$[$0-4].first_column; loc.first_line = _$[$0-4].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), $$[$0-3], $$[$0-2][0], $$[$0-2][1], $$[$0]);
case 135:this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Try($$[$0-3], $$[$0-2][0], $$[$0-2][1], $$[$0]));
break;
case 136:this.$ = [$$[$0-1], $$[$0]];
case 136:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])([$$[$0-1], $$[$0]]);
break;
case 137:this.$ = [new yy.Value(_$[$0-1], $$[$0-1]), $$[$0]];
case 137:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])([yy.addLocationDataFn(_$[$0-1])(new yy.Value($$[$0-1])), $$[$0]]);
break;
case 138:this.$ = new yy.Throw((function(){loc = {}; loc.first_column = _$[$0-1].first_column; loc.first_line = _$[$0-1].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), $$[$0]);
case 138:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Throw($$[$0]));
break;
case 139:this.$ = new yy.Parens((function(){loc = {}; loc.first_column = _$[$0-2].first_column; loc.first_line = _$[$0-2].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), $$[$0-1]);
case 139:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Parens($$[$0-1]));
break;
case 140:this.$ = new yy.Parens((function(){loc = {}; loc.first_column = _$[$0-4].first_column; loc.first_line = _$[$0-4].first_line; loc.last_column = _$[$0-1].last_column; loc.last_line = _$[$0-1].last_line; return loc;})(), $$[$0-2]);
case 140:this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Parens($$[$0-2]));
break;
case 141:this.$ = new yy.While((function(){loc = {}; loc.first_column = _$[$0-1].first_column; loc.first_line = _$[$0-1].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), $$[$0]);
case 141:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.While($$[$0]));
break;
case 142:this.$ = new yy.While((function(){loc = {}; loc.first_column = _$[$0-3].first_column; loc.first_line = _$[$0-3].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), $$[$0-2], {
case 142:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.While($$[$0-2], {
guard: $$[$0]
});
}));
break;
case 143:this.$ = new yy.While((function(){loc = {}; loc.first_column = _$[$0-1].first_column; loc.first_line = _$[$0-1].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), $$[$0], {
case 143:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.While($$[$0], {
invert: true
});
}));
break;
case 144:this.$ = new yy.While((function(){loc = {}; loc.first_column = _$[$0-3].first_column; loc.first_line = _$[$0-3].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), $$[$0-2], {
case 144:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.While($$[$0-2], {
invert: true,
guard: $$[$0]
}));
break;
case 145:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])($$[$0-1].addBody($$[$0]));
break;
case 146:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])($$[$0].addBody(yy.addLocationDataFn(_$[$0-1])(yy.Block.wrap([$$[$0-1]]))));
break;
case 147:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])($$[$0].addBody(yy.addLocationDataFn(_$[$0-1])(yy.Block.wrap([$$[$0-1]]))));
break;
case 148:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])($$[$0]);
break;
case 149:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.While(yy.addLocationDataFn(_$[$0-1])(new yy.Literal('true'))).addBody($$[$0]));
break;
case 150:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.While(yy.addLocationDataFn(_$[$0-1])(new yy.Literal('true'))).addBody(yy.addLocationDataFn(_$[$0])(yy.Block.wrap([$$[$0]]))));
break;
case 151:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.For($$[$0-1], $$[$0]));
break;
case 152:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.For($$[$0-1], $$[$0]));
break;
case 153:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.For($$[$0], $$[$0-1]));
break;
case 154:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])({
source: yy.addLocationDataFn(_$[$0])(new yy.Value($$[$0]))
});
break;
case 145:this.$ = $$[$0-1].addBody($$[$0]);
break;
case 146:this.$ = $$[$0].addBody(yy.Block.wrap(_$[$0-1], [$$[$0-1]]));
break;
case 147:this.$ = $$[$0].addBody(yy.Block.wrap(_$[$0-1], [$$[$0-1]]));
break;
case 148:this.$ = $$[$0];
break;
case 149:this.$ = new yy.While((function(){loc = {}; loc.first_column = _$[$0-1].first_column; loc.first_line = _$[$0-1].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), new yy.Literal(_$[$0-1], 'true')).addBody($$[$0]);
break;
case 150:this.$ = new yy.While((function(){loc = {}; loc.first_column = _$[$0-1].first_column; loc.first_line = _$[$0-1].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), new yy.Literal(_$[$0-1], 'true')).addBody(yy.Block.wrap(_$[$0], [$$[$0]]));
break;
case 151:this.$ = new yy.For((function(){loc = {}; loc.first_column = _$[$0-1].first_column; loc.first_line = _$[$0-1].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), $$[$0-1], $$[$0]);
break;
case 152:this.$ = new yy.For((function(){loc = {}; loc.first_column = _$[$0-1].first_column; loc.first_line = _$[$0-1].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), $$[$0-1], $$[$0]);
break;
case 153:this.$ = new yy.For((function(){loc = {}; loc.first_column = _$[$0-1].first_column; loc.first_line = _$[$0-1].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), $$[$0], $$[$0-1]);
break;
case 154:this.$ = {
source: new yy.Value(_$[$0], $$[$0])
};
break;
case 155:this.$ = (function () {
case 155:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])((function () {
$$[$0].own = $$[$0-1].own;
$$[$0].name = $$[$0-1][0];
$$[$0].index = $$[$0-1][1];
return $$[$0];
}());
}()));
break;
case 156:this.$ = $$[$0];
case 156:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])($$[$0]);
break;
case 157:this.$ = (function () {
case 157:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])((function () {
$$[$0].own = true;
return $$[$0];
}());
}()));
break;
case 158:this.$ = $$[$0];
break;
case 159:this.$ = $$[$0];
break;
case 160:this.$ = new yy.Value(_$[$0], $$[$0]);
case 160:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Value($$[$0]));
break;
case 161:this.$ = new yy.Value(_$[$0], $$[$0]);
case 161:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])(new yy.Value($$[$0]));
break;
case 162:this.$ = [$$[$0]];
case 162:this.$ = yy.addLocationDataFn(_$[$0], _$[$0])([$$[$0]]);
break;
case 163:this.$ = [$$[$0-2], $$[$0]];
case 163:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])([$$[$0-2], $$[$0]]);
break;
case 164:this.$ = {
case 164:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])({
source: $$[$0]
};
});
break;
case 165:this.$ = {
case 165:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])({
source: $$[$0],
object: true
};
});
break;
case 166:this.$ = {
case 166:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])({
source: $$[$0-2],
guard: $$[$0]
};
});
break;
case 167:this.$ = {
case 167:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])({
source: $$[$0-2],
guard: $$[$0],
object: true
};
});
break;
case 168:this.$ = {
case 168:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])({
source: $$[$0-2],
step: $$[$0]
};
});
break;
case 169:this.$ = {
case 169:this.$ = yy.addLocationDataFn(_$[$0-5], _$[$0])({
source: $$[$0-4],
guard: $$[$0-2],
step: $$[$0]
};
});
break;
case 170:this.$ = {
case 170:this.$ = yy.addLocationDataFn(_$[$0-5], _$[$0])({
source: $$[$0-4],
step: $$[$0-2],
guard: $$[$0]
};
});
break;
case 171:this.$ = new yy.Switch((function(){loc = {}; loc.first_column = _$[$0-4].first_column; loc.first_line = _$[$0-4].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), $$[$0-3], $$[$0-1]);
case 171:this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Switch($$[$0-3], $$[$0-1]));
break;
case 172:this.$ = new yy.Switch((function(){loc = {}; loc.first_column = _$[$0-6].first_column; loc.first_line = _$[$0-6].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), $$[$0-5], $$[$0-3], $$[$0-1]);
case 172:this.$ = yy.addLocationDataFn(_$[$0-6], _$[$0])(new yy.Switch($$[$0-5], $$[$0-3], $$[$0-1]));
break;
case 173:this.$ = new yy.Switch((function(){loc = {}; loc.first_column = _$[$0-3].first_column; loc.first_line = _$[$0-3].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), null, $$[$0-1]);
case 173:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])(new yy.Switch(null, $$[$0-1]));
break;
case 174:this.$ = new yy.Switch((function(){loc = {}; loc.first_column = _$[$0-5].first_column; loc.first_line = _$[$0-5].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), null, $$[$0-3], $$[$0-1]);
case 174:this.$ = yy.addLocationDataFn(_$[$0-5], _$[$0])(new yy.Switch(null, $$[$0-3], $$[$0-1]));
break;
case 175:this.$ = $$[$0];
break;
case 176:this.$ = $$[$0-1].concat($$[$0]);
case 176:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])($$[$0-1].concat($$[$0]));
break;
case 177:this.$ = [[$$[$0-1], $$[$0]]];
case 177:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])([[$$[$0-1], $$[$0]]]);
break;
case 178:this.$ = [[$$[$0-2], $$[$0-1]]];
case 178:this.$ = yy.addLocationDataFn(_$[$0-3], _$[$0])([[$$[$0-2], $$[$0-1]]]);
break;
case 179:this.$ = new yy.If((function(){loc = {}; loc.first_column = _$[$0-2].first_column; loc.first_line = _$[$0-2].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), $$[$0-1], $$[$0], {
type: $$[$0-2]
});
break;
case 180:this.$ = $$[$0-4].addElse(new yy.If((function(){loc = {}; loc.first_column = _$[$0-4].first_column; loc.first_line = _$[$0-4].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), $$[$0-1], $$[$0], {
case 179:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.If($$[$0-1], $$[$0], {
type: $$[$0-2]
}));
break;
case 180:this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])($$[$0-4].addElse(new yy.If($$[$0-1], $$[$0], {
type: $$[$0-2]
})));
break;
case 181:this.$ = $$[$0];
break;
case 182:this.$ = $$[$0-2].addElse($$[$0]);
case 182:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])($$[$0-2].addElse($$[$0]));
break;
case 183:this.$ = new yy.If((function(){loc = {}; loc.first_column = _$[$0-2].first_column; loc.first_line = _$[$0-2].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), $$[$0], yy.Block.wrap(_$[$0-2], [$$[$0-2]]), {
case 183:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.If($$[$0], yy.addLocationDataFn(_$[$0-2])(yy.Block.wrap([$$[$0-2]])), {
type: $$[$0-1],
statement: true
});
}));
break;
case 184:this.$ = new yy.If((function(){loc = {}; loc.first_column = _$[$0-2].first_column; loc.first_line = _$[$0-2].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), $$[$0], yy.Block.wrap(_$[$0-2], [$$[$0-2]]), {
case 184:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.If($$[$0], yy.addLocationDataFn(_$[$0-2])(yy.Block.wrap([$$[$0-2]])), {
type: $$[$0-1],
statement: true
});
}));
break;
case 185:this.$ = new yy.Op((function(){loc = {}; loc.first_column = _$[$0-1].first_column; loc.first_line = _$[$0-1].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), $$[$0-1], $$[$0]);
case 185:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Op($$[$0-1], $$[$0]));
break;
case 186:this.$ = new yy.Op((function(){loc = {}; loc.first_column = _$[$0-1].first_column; loc.first_line = _$[$0-1].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), '-', $$[$0]);
case 186:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Op('-', $$[$0]));
break;
case 187:this.$ = new yy.Op((function(){loc = {}; loc.first_column = _$[$0-1].first_column; loc.first_line = _$[$0-1].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), '+', $$[$0]);
case 187:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Op('+', $$[$0]));
break;
case 188:this.$ = new yy.Op((function(){loc = {}; loc.first_column = _$[$0-1].first_column; loc.first_line = _$[$0-1].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), '--', $$[$0]);
case 188:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Op('--', $$[$0]));
break;
case 189:this.$ = new yy.Op((function(){loc = {}; loc.first_column = _$[$0-1].first_column; loc.first_line = _$[$0-1].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), '++', $$[$0]);
case 189:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Op('++', $$[$0]));
break;
case 190:this.$ = new yy.Op((function(){loc = {}; loc.first_column = _$[$0-1].first_column; loc.first_line = _$[$0-1].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), '--', $$[$0-1], null, true);
case 190:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Op('--', $$[$0-1], null, true));
break;
case 191:this.$ = new yy.Op((function(){loc = {}; loc.first_column = _$[$0-1].first_column; loc.first_line = _$[$0-1].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), '++', $$[$0-1], null, true);
case 191:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Op('++', $$[$0-1], null, true));
break;
case 192:this.$ = new yy.Existence(_$[$0-1], $$[$0-1]);
case 192:this.$ = yy.addLocationDataFn(_$[$0-1], _$[$0])(new yy.Existence($$[$0-1]));
break;
case 193:this.$ = new yy.Op((function(){loc = {}; loc.first_column = _$[$0-2].first_column; loc.first_line = _$[$0-2].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), '+', $$[$0-2], $$[$0]);
case 193:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Op('+', $$[$0-2], $$[$0]));
break;
case 194:this.$ = new yy.Op((function(){loc = {}; loc.first_column = _$[$0-2].first_column; loc.first_line = _$[$0-2].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), '-', $$[$0-2], $$[$0]);
case 194:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Op('-', $$[$0-2], $$[$0]));
break;
case 195:this.$ = new yy.Op((function(){loc = {}; loc.first_column = _$[$0-2].first_column; loc.first_line = _$[$0-2].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), $$[$0-1], $$[$0-2], $$[$0]);
case 195:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Op($$[$0-1], $$[$0-2], $$[$0]));
break;
case 196:this.$ = new yy.Op((function(){loc = {}; loc.first_column = _$[$0-2].first_column; loc.first_line = _$[$0-2].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), $$[$0-1], $$[$0-2], $$[$0]);
case 196:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Op($$[$0-1], $$[$0-2], $$[$0]));
break;
case 197:this.$ = new yy.Op((function(){loc = {}; loc.first_column = _$[$0-2].first_column; loc.first_line = _$[$0-2].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), $$[$0-1], $$[$0-2], $$[$0]);
case 197:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Op($$[$0-1], $$[$0-2], $$[$0]));
break;
case 198:this.$ = new yy.Op((function(){loc = {}; loc.first_column = _$[$0-2].first_column; loc.first_line = _$[$0-2].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), $$[$0-1], $$[$0-2], $$[$0]);
case 198:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Op($$[$0-1], $$[$0-2], $$[$0]));
break;
case 199:this.$ = (function () {
case 199:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])((function () {
if ($$[$0-1].charAt(0) === '!') {
return new yy.Op((function(){loc = {}; loc.first_column = _$[$0-2].first_column; loc.first_line = _$[$0-2].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), $$[$0-1].slice(1), $$[$0-2], $$[$0]).invert();
return new yy.Op($$[$0-1].slice(1), $$[$0-2], $$[$0]).invert();
} else {
return new yy.Op((function(){loc = {}; loc.first_column = _$[$0-2].first_column; loc.first_line = _$[$0-2].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), $$[$0-1], $$[$0-2], $$[$0]);
return new yy.Op($$[$0-1], $$[$0-2], $$[$0]);
}
}());
}()));
break;
case 200:this.$ = new yy.Assign((function(){loc = {}; loc.first_column = _$[$0-2].first_column; loc.first_line = _$[$0-2].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), $$[$0-2], $$[$0], $$[$0-1]);
case 200:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Assign($$[$0-2], $$[$0], $$[$0-1]));
break;
case 201:this.$ = new yy.Assign((function(){loc = {}; loc.first_column = _$[$0-4].first_column; loc.first_line = _$[$0-4].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), $$[$0-4], $$[$0-1], $$[$0-3]);
case 201:this.$ = yy.addLocationDataFn(_$[$0-4], _$[$0])(new yy.Assign($$[$0-4], $$[$0-1], $$[$0-3]));
break;
case 202:this.$ = new yy.Extends((function(){loc = {}; loc.first_column = _$[$0-2].first_column; loc.first_line = _$[$0-2].first_line; loc.last_column = _$[$0].last_column; loc.last_line = _$[$0].last_line; return loc;})(), $$[$0-2], $$[$0]);
case 202:this.$ = yy.addLocationDataFn(_$[$0-2], _$[$0])(new yy.Extends($$[$0-2], $$[$0]));
break;
}
},

View File

@ -32,18 +32,27 @@ unwrap = /^function\s*\(\)\s*\{\s*return\s*([\s\S]*);\s*\}/
# previous nonterminal.
o = (patternString, action, options) ->
patternString = patternString.replace /\s{2,}/g, ' '
patternCount = patternString.split(' ').length
return [patternString, '$$ = $1;', options] unless action
action = if match = unwrap.exec action then match[1] else "(#{action}())"
# All runtime functions we need are defined on "yy"
action = action.replace /\bnew /g, '$&yy.'
action = action.replace /\b(?:Block\.wrap|extend)\b/g, 'yy.$&'
action = action.replace /LOCDATA\(([0-9]*)\)/g, '@$1'
action = action.replace /LOCDATA\(([0-9]*),\s*([0-9]*)\)/g,
'(function(){loc = {}; loc.first_column = @$1.first_column; ' +
'loc.first_line = @$1.first_line; ' +
'loc.last_column = @$2.last_column; ' +
'loc.last_line = @$2.last_line; ' +
'return loc;})()'
[patternString, "$$ = #{action};", options]
# Returns a function which adds location data to the first parameter passed
# in, and returns the parameter. If the parameter is not a node, it will
# just be passed through unaffected.
addLocationDataFn = (first, last) ->
if not last
"yy.addLocationDataFn(@#{first})"
else
"yy.addLocationDataFn(@#{first}, @#{last})"
action = action.replace /LOCDATA\(([0-9]*)\)/g, addLocationDataFn('$1')
action = action.replace /LOCDATA\(([0-9]*),\s*([0-9]*)\)/g, addLocationDataFn('$1', '$2')
[patternString, "$$ = #{addLocationDataFn(1, patternCount)}(#{action});", options]
# Grammatical Rules
# -----------------
@ -63,14 +72,14 @@ grammar =
# The **Root** is the top-level node in the syntax tree. Since we parse bottom-up,
# all parsing must end here.
Root: [
o '', -> new Block LOCDATA(1)
o '', -> new Block
o 'Body'
o 'Block TERMINATOR'
]
# Any list of statements and expressions, separated by line breaks or semicolons.
Body: [
o 'Line', -> Block.wrap LOCDATA(1), [$1]
o 'Line', -> Block.wrap [$1]
o 'Body TERMINATOR Line', -> $1.push $3
o 'Body TERMINATOR'
]
@ -85,7 +94,7 @@ grammar =
Statement: [
o 'Return'
o 'Comment'
o 'STATEMENT', -> new Literal LOCDATA(1), $1
o 'STATEMENT', -> new Literal $1
]
# All the different types of expressions in our language. The basic unit of
@ -111,48 +120,48 @@ grammar =
# will convert some postfix forms into blocks for us, by adjusting the
# token stream.
Block: [
o 'INDENT OUTDENT', -> new Block LOCDATA(1)
o 'INDENT OUTDENT', -> new Block
o 'INDENT Body OUTDENT', -> $2
]
# A literal identifier, a variable name or property.
Identifier: [
o 'IDENTIFIER', -> new Literal LOCDATA(1), $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 Literal LOCDATA(1), $1
o 'STRING', -> new Literal LOCDATA(1), $1
o 'NUMBER', -> new Literal $1
o 'STRING', -> new Literal $1
]
# All of our immediate values. Generally these can be passed straight
# through and printed to JavaScript.
Literal: [
o 'AlphaNumeric'
o 'JS', -> new Literal LOCDATA(1), $1
o 'REGEX', -> new Literal LOCDATA(1), $1
o 'DEBUGGER', -> new Literal LOCDATA(1), $1
o 'UNDEFINED', -> new Undefined LOCDATA(1)
o 'NULL', -> new Null LOCDATA(1)
o 'BOOL', -> new Bool LOCDATA(1), $1
o 'JS', -> new Literal $1
o 'REGEX', -> new Literal $1
o 'DEBUGGER', -> new Literal $1
o 'UNDEFINED', -> new Undefined
o 'NULL', -> new Null
o 'BOOL', -> new Bool $1
]
# Assignment of a variable, property, or index to a value.
Assign: [
o 'Assignable = Expression', -> new Assign LOCDATA(1, 3), $1, $3
o 'Assignable = TERMINATOR Expression', -> new Assign LOCDATA(1, 4), $1, $4
o 'Assignable = INDENT Expression OUTDENT', -> new Assign LOCDATA(1, 4), $1, $4
o 'Assignable = Expression', -> new Assign $1, $3
o 'Assignable = TERMINATOR Expression', -> new Assign $1, $4
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 'ObjAssignable', -> new Value LOCDATA(1), $1
o 'ObjAssignable : Expression', -> new Assign LOCDATA(1, 3), new Value(LOCDATA(1), $1), $3, 'object'
o 'ObjAssignable', -> new Value $1
o 'ObjAssignable : Expression', -> new Assign LOCDATA(1)(new Value $1), $3, 'object'
o 'ObjAssignable :
INDENT Expression OUTDENT', -> new Assign LOCDATA(1, 4), new Value(LOCDATA(1), $1), $4, 'object'
INDENT Expression OUTDENT', -> new Assign LOCDATA(1)(new Value $1), $4, 'object'
o 'Comment'
]
@ -164,21 +173,21 @@ grammar =
# A return statement from a function body.
Return: [
o 'RETURN Expression', -> new Return LOCDATA(1, 2), $2
o 'RETURN', -> new Return LOCDATA(1)
o 'RETURN Expression', -> new Return $2
o 'RETURN', -> new Return
]
# A block comment.
Comment: [
o 'HERECOMMENT', -> new Comment LOCDATA(1), $1
o 'HERECOMMENT', -> new Comment $1
]
# The **Code** node is the function literal. It's defined by an indented block
# of **Block** preceded by a function arrow, with an optional parameter
# list.
Code: [
o 'PARAM_START ParamList PARAM_END FuncGlyph Block', -> new Code LOCDATA(1, 5), $2, $5, $4
o 'FuncGlyph Block', -> new Code LOCDATA(1, 2), [], $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
@ -206,9 +215,9 @@ grammar =
# A single parameter in a function definition can be ordinary, or a splat
# that hoovers up the remaining arguments.
Param: [
o 'ParamVar', -> new Param LOCDATA(1), $1
o 'ParamVar ...', -> new Param LOCDATA(1), $1, null, on
o 'ParamVar = Expression', -> new Param LOCDATA(1, 3), $1, $3
o 'ParamVar', -> new Param $1
o 'ParamVar ...', -> new Param $1, null, on
o 'ParamVar = Expression', -> new Param $1, $3
]
# Function Parameters
@ -221,42 +230,41 @@ grammar =
# A splat that occurs outside of a parameter list.
Splat: [
o 'Expression ...', -> new Splat LOCDATA(1), $1
o 'Expression ...', -> new Splat $1
]
# Variables and properties that can be assigned to.
SimpleAssignable: [
o 'Identifier', -> new Value LOCDATA(1), $1
# TODO: Add $2 to LOCDATA
o 'Identifier', -> new Value $1
o 'Value Accessor', -> $1.add $2
o 'Invocation Accessor', -> new Value LOCDATA(1, 2), $1, [].concat $2
o 'Invocation Accessor', -> new Value $1, [].concat $2
o 'ThisProperty'
]
# Everything that can be assigned to.
Assignable: [
o 'SimpleAssignable'
o 'Array', -> new Value LOCDATA(1), $1
o 'Object', -> new Value LOCDATA(1), $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 Value LOCDATA(1), $1
o 'Parenthetical', -> new Value LOCDATA(1), $1
o 'Range', -> new Value LOCDATA(1), $1
o 'Literal', -> new Value $1
o 'Parenthetical', -> new Value $1
o 'Range', -> new Value $1
o 'This'
]
# The general group of accessors into an object, by property, by prototype
# or by array index or slice.
Accessor: [
o '. Identifier', -> new Access LOCDATA(1,2), $2
o '?. Identifier', -> new Access LOCDATA(1,2), $2, 'soak'
o ':: Identifier', -> [(new Access LOCDATA(1), new Literal LOCDATA(1), 'prototype'), new Access LOCDATA(1), $2]
o '::', -> new Access LOCDATA(1), new Literal LOCDATA(1), 'prototype'
o '. Identifier', -> new Access $2
o '?. Identifier', -> new Access $2, 'soak'
o ':: Identifier', -> [LOCDATA(1)(new Access new Literal 'prototype'), LOCDATA(2)(new Access $2)]
o '::', -> new Access new Literal 'prototype'
o 'Index'
]
@ -267,13 +275,13 @@ grammar =
]
IndexValue: [
o 'Expression', -> new Index LOCDATA(1), $1
o 'Slice', -> new Slice LOCDATA(1), $1
o 'Expression', -> new Index $1
o 'Slice', -> new Slice $1
]
# In CoffeeScript, an object literal is simply a list of assignments.
Object: [
o '{ AssignList OptComma }', -> new Obj LOCDATA(1,2), $2, $1.generated
o '{ AssignList OptComma }', -> new Obj $2, $1.generated
]
# Assignment of properties within an object literal can be separated by
@ -289,22 +297,22 @@ grammar =
# Class definitions have optional bodies of prototype property assignments,
# and optional references to the superclass.
Class: [
o 'CLASS', -> new Class LOCDATA(1)
o 'CLASS Block', -> new Class LOCDATA(1, 2), null, null, $2
o 'CLASS EXTENDS Expression', -> new Class LOCDATA(1, 3), null, $3
o 'CLASS EXTENDS Expression Block', -> new Class LOCDATA(1, 4), null, $3, $4
o 'CLASS SimpleAssignable', -> new Class LOCDATA(1, 2), $2
o 'CLASS SimpleAssignable Block', -> new Class LOCDATA(1, 3), $2, null, $3
o 'CLASS SimpleAssignable EXTENDS Expression', -> new Class LOCDATA(1, 4), $2, $4
o 'CLASS SimpleAssignable EXTENDS Expression Block', -> new Class LOCDATA(1, 5), $2, $4, $5
o 'CLASS', -> new Class
o 'CLASS Block', -> new Class null, null, $2
o 'CLASS EXTENDS Expression', -> new Class null, $3
o 'CLASS EXTENDS Expression Block', -> new Class null, $3, $4
o 'CLASS SimpleAssignable', -> new Class $2
o 'CLASS SimpleAssignable Block', -> new Class $2, null, $3
o 'CLASS SimpleAssignable EXTENDS Expression', -> new Class $2, $4
o 'CLASS SimpleAssignable EXTENDS Expression Block', -> new Class $2, $4, $5
]
# Ordinary function invocation, or a chained series of calls.
Invocation: [
o 'Value OptFuncExist Arguments', -> new Call LOCDATA(1, 3), $1, $3, $2
o 'Invocation OptFuncExist Arguments', -> new Call LOCDATA(1, 3), $1, $3, $2
o 'SUPER', -> new Call LOCDATA(1), 'super', [new Splat(LOCDATA(1), new Literal(LOCDATA(1), 'arguments'))]
o 'SUPER Arguments', -> new Call LOCDATA(1, 2),'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.
@ -316,24 +324,24 @@ grammar =
# The list of arguments to a function call.
Arguments: [
o 'CALL_START CALL_END', -> []
o 'CALL_START ArgList OptComma CALL_END', -> return $2
o 'CALL_START ArgList OptComma CALL_END', -> $2
]
# A reference to the *this* current object.
This: [
o 'THIS', -> new Value LOCDATA(1), new Literal LOCDATA(1), 'this'
o '@', -> new Value LOCDATA(1), new Literal LOCDATA(1), 'this'
o 'THIS', -> new Value new Literal 'this'
o '@', -> new Value new Literal 'this'
]
# A reference to a property on *this*.
ThisProperty: [
o '@ Identifier', -> new Value LOCDATA(1, 2), new Literal(LOCDATA(1), 'this'), [new Access(LOCDATA(2), $2)], 'this'
o '@ Identifier', -> new Value LOCDATA(1)(new Literal 'this'), [LOCDATA(2)(new Access $2)], 'this'
]
# The array literal.
Array: [
o '[ ]', -> new Arr LOCDATA(1), []
o '[ ArgList OptComma ]', -> new Arr LOCDATA(1, 2), $2
o '[ ]', -> new Arr []
o '[ ArgList OptComma ]', -> new Arr $2
]
# Inclusive and exclusive range dots.
@ -344,15 +352,15 @@ grammar =
# The CoffeeScript range literal.
Range: [
o '[ Expression RangeDots Expression ]', -> new Range LOCDATA(1, 4), $2, $4, $3
o '[ Expression RangeDots Expression ]', -> new Range $2, $4, $3
]
# Array slice literals.
Slice: [
o 'Expression RangeDots Expression', -> new Range LOCDATA(1, 3), $1, $3, $2
o 'Expression RangeDots', -> new Range LOCDATA(1, 2), $1, null, $2
o 'RangeDots Expression', -> new Range LOCDATA(1, 2), null, $2, $1
o 'RangeDots', -> new Range LOCDATA(1), null, null, $1
o 'Expression RangeDots Expression', -> new Range $1, $3, $2
o 'Expression RangeDots', -> new Range $1, null, $2
o 'RangeDots Expression', -> new Range null, $2, $1
o 'RangeDots', -> new Range null, null, $1
]
# The **ArgList** is both the list of objects passed into a function call,
@ -382,21 +390,21 @@ grammar =
# The variants of *try/catch/finally* exception handling blocks.
Try: [
o 'TRY Block', -> new Try LOCDATA(1,2), $2
o 'TRY Block Catch', -> new Try LOCDATA(1,3), $2, $3[0], $3[1]
o 'TRY Block FINALLY Block', -> new Try LOCDATA(1,4), $2, null, null, $4
o 'TRY Block Catch FINALLY Block', -> new Try LOCDATA(1,5), $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.
Catch: [
o 'CATCH Identifier Block', -> [$2, $3]
o 'CATCH Object Block', -> [new Value(LOCDATA(2), $2), $3]
o 'CATCH Object Block', -> [LOCDATA(2)(new Value $2), $3]
]
# Throw an exception object.
Throw: [
o 'THROW Expression', -> new Throw LOCDATA(1,2), $2
o 'THROW Expression', -> new Throw $2
]
# Parenthetical expressions. Note that the **Parenthetical** is a **Value**,
@ -404,44 +412,43 @@ grammar =
# where only values are accepted, wrapping it in parentheses will always do
# the trick.
Parenthetical: [
o '( Body )', -> new Parens LOCDATA(1,3), $2
o '( INDENT Body OUTDENT )', -> new Parens LOCDATA(1,4), $3
o '( Body )', -> new Parens $2
o '( INDENT Body OUTDENT )', -> new Parens $3
]
# The condition portion of a while loop.
WhileSource: [
o 'WHILE Expression', -> new While LOCDATA(1,2), $2
o 'WHILE Expression WHEN Expression', -> new While LOCDATA(1,4), $2, guard: $4
o 'UNTIL Expression', -> new While LOCDATA(1,2), $2, invert: true
o 'UNTIL Expression WHEN Expression', -> new While LOCDATA(1,4), $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,
# or postfix, with a single expression. There is no do..while.
While: [
# TODO: LOCDATA
o 'WhileSource Block', -> $1.addBody $2
o 'Statement WhileSource', -> $2.addBody Block.wrap(LOCDATA(1), [$1])
o 'Expression WhileSource', -> $2.addBody Block.wrap(LOCDATA(1), [$1])
o 'Statement WhileSource', -> $2.addBody LOCDATA(1) Block.wrap([$1])
o 'Expression WhileSource', -> $2.addBody LOCDATA(1) Block.wrap([$1])
o 'Loop', -> $1
]
Loop: [
o 'LOOP Block', -> new While(LOCDATA(1,2), new Literal(LOCDATA(1), 'true')).addBody $2
o 'LOOP Expression', -> new While(LOCDATA(1,2), new Literal(LOCDATA(1), 'true')).addBody Block.wrap(LOCDATA(2), [$2])
o 'LOOP Block', -> new While(LOCDATA(1) new Literal 'true').addBody $2
o 'LOOP Expression', -> new While(LOCDATA(1) new Literal 'true').addBody LOCDATA(2) Block.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 For LOCDATA(1,2), $1, $2
o 'Expression ForBody', -> new For LOCDATA(1,2), $1, $2
o 'ForBody Block', -> new For LOCDATA(1,2), $2, $1
o 'Statement ForBody', -> new For $1, $2
o 'Expression ForBody', -> new For $1, $2
o 'ForBody Block', -> new For $2, $1
]
ForBody: [
o 'FOR Range', -> return source: new Value(LOCDATA(2), $2)
o 'FOR Range', -> source: LOCDATA(2) new Value $2
o 'ForStart ForSource', -> $2.own = $1.own; $2.name = $1[0]; $2.index = $1[1]; $2
]
@ -455,8 +462,8 @@ grammar =
ForValue: [
o 'Identifier'
o 'ThisProperty'
o 'Array', -> new Value LOCDATA(1), $1
o 'Object', -> new Value LOCDATA(1), $1
o 'Array', -> new Value $1
o 'Object', -> new Value $1
]
# An array or range comprehension has variables for the current element
@ -481,10 +488,10 @@ grammar =
]
Switch: [
o 'SWITCH Expression INDENT Whens OUTDENT', -> new Switch LOCDATA(1,5), $2, $4
o 'SWITCH Expression INDENT Whens ELSE Block OUTDENT', -> new Switch LOCDATA(1,7), $2, $4, $6
o 'SWITCH INDENT Whens OUTDENT', -> new Switch LOCDATA(1,4), null, $3
o 'SWITCH INDENT Whens ELSE Block OUTDENT', -> new Switch LOCDATA(1,6), 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: [
@ -502,8 +509,8 @@ grammar =
# if-related rules are broken up along these lines in order to avoid
# ambiguity.
IfBlock: [
o 'IF Expression Block', -> new If LOCDATA(1,3), $2, $3, type: $1
o 'IfBlock ELSE IF Expression Block', -> $1.addElse new If LOCDATA(1,5), $4, $5, type: $3
o 'IF Expression Block', -> new If $2, $3, type: $1
o 'IfBlock ELSE IF Expression Block', -> $1.addElse new If $4, $5, type: $3
]
# The full complement of *if* expressions, including postfix one-liner
@ -511,8 +518,8 @@ grammar =
If: [
o 'IfBlock'
o 'IfBlock ELSE Block', -> $1.addElse $3
o 'Statement POST_IF Expression', -> new If LOCDATA(1, 3), $3, Block.wrap(LOCDATA(1), [$1]), type: $2, statement: true
o 'Expression POST_IF Expression', -> new If LOCDATA(1, 3), $3, Block.wrap(LOCDATA(1), [$1]), type: $2, statement: true
o 'Statement POST_IF Expression', -> new If $3, LOCDATA(1)(Block.wrap [$1]), type: $2, statement: true
o 'Expression POST_IF Expression', -> new If $3, LOCDATA(1)(Block.wrap [$1]), type: $2, statement: true
]
# Arithmetic and logical operators, working on one or more operands.
@ -522,36 +529,36 @@ grammar =
# -type rule, but in order to make the precedence binding possible, separate
# rules are necessary.
Operation: [
o 'UNARY Expression', -> new Op LOCDATA(1, 2), $1 , $2
o '- Expression', (-> new Op LOCDATA(1, 2), '-', $2), prec: 'UNARY'
o '+ Expression', (-> new Op LOCDATA(1, 2), '+', $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 '-- SimpleAssignable', -> new Op LOCDATA(1, 2), '--', $2
o '++ SimpleAssignable', -> new Op LOCDATA(1, 2), '++', $2
o 'SimpleAssignable --', -> new Op LOCDATA(1, 2), '--', $1, null, true
o 'SimpleAssignable ++', -> new Op LOCDATA(1, 2), '++', $1, null, true
o '-- SimpleAssignable', -> new Op '--', $2
o '++ SimpleAssignable', -> new Op '++', $2
o 'SimpleAssignable --', -> new Op '--', $1, null, true
o 'SimpleAssignable ++', -> new Op '++', $1, null, true
# [The existential operator](http://jashkenas.github.com/coffee-script/#existence).
o 'Expression ?', -> new Existence LOCDATA(1), $1
o 'Expression ?', -> new Existence $1
o 'Expression + Expression', -> new Op LOCDATA(1, 3), '+' , $1, $3
o 'Expression - Expression', -> new Op LOCDATA(1, 3), '-' , $1, $3
o 'Expression + Expression', -> new Op '+' , $1, $3
o 'Expression - Expression', -> new Op '-' , $1, $3
o 'Expression MATH Expression', -> new Op LOCDATA(1, 3), $2, $1, $3
o 'Expression SHIFT Expression', -> new Op LOCDATA(1, 3), $2, $1, $3
o 'Expression COMPARE Expression', -> new Op LOCDATA(1, 3), $2, $1, $3
o 'Expression LOGIC Expression', -> new Op LOCDATA(1, 3), $2, $1, $3
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 'Expression RELATION Expression', ->
if $2.charAt(0) is '!'
new Op(LOCDATA(1, 3), $2[1..], $1, $3).invert()
new Op($2[1..], $1, $3).invert()
else
new Op LOCDATA(1, 3), $2, $1, $3
new Op $2, $1, $3
o 'SimpleAssignable COMPOUND_ASSIGN
Expression', -> new Assign LOCDATA(1, 3), $1, $3, $2
Expression', -> new Assign $1, $3, $2
o 'SimpleAssignable COMPOUND_ASSIGN
INDENT Expression OUTDENT', -> new Assign LOCDATA(1, 5), $1, $4, $2
o 'SimpleAssignable EXTENDS Expression', -> new Extends LOCDATA(1, 3), $1, $3
INDENT Expression OUTDENT', -> new Assign $1, $4, $2
o 'SimpleAssignable EXTENDS Expression', -> new Extends $1, $3
]

View File

@ -59,3 +59,23 @@ exports.last = (array, back) -> array[array.length - (back or 0) - 1]
exports.some = Array::some ? (fn) ->
return true for e in this when fn e
false
# Merge two jison-style location data objects together.
# If `last` is not provided, this will simply return `first`.
buildLocationData = (first, last) ->
if not last
first
else
first_line: first.first_line
first_column: first.first_column
last_line: last.last_line
last_column: last.last_column
# This returns a function which takes an object as a parameter, and if that object is an AST node,
# updates that object's locationData. The object is returned either way.
exports.addLocationDataFn = (first, last) ->
(obj) ->
if ((typeof obj) is 'object') and (!!obj['updateLocationDataIfMissing'])
obj.updateLocationDataIfMissing buildLocationData(first, last)
return obj

View File

@ -7,9 +7,11 @@
{RESERVED, STRICT_PROSCRIBED} = require './lexer'
# Import the helpers we plan to use.
{compact, flatten, extend, merge, del, starts, ends, last, some} = require './helpers'
{compact, flatten, extend, merge, del, starts, ends, last, some, addLocationDataFn} = require './helpers'
exports.extend = extend # for parser
# Functions required by parser
exports.extend = extend
exports.addLocationDataFn = addLocationDataFn
# Constant functions for nodes that don't need customization.
YES = -> yes
@ -52,7 +54,7 @@ exports.Base = class Base
if @jumps()
throw SyntaxError 'cannot use a pure statement in an expression.'
o.sharedScope = yes
Closure.wrap(@locationData, this).compileNode o
Closure.wrap(this).compileNode 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,
@ -62,8 +64,8 @@ exports.Base = class Base
ref = if level then @compile o, level else this
[ref, ref]
else
ref = new Literal @locationData, reused or o.scope.freeVariable 'ref'
sub = new Assign @locationData, ref, this
ref = new Literal reused or o.scope.freeVariable 'ref'
sub = new Assign ref, this
if level then [sub.compile(o, level), ref.value] else [sub, ref]
# Compile to a source/variable pair suitable for looping.
@ -79,9 +81,9 @@ exports.Base = class Base
makeReturn: (res) ->
me = @unwrapAll()
if res
new Call @locationData, new Literal(@locationData, "#{res}.push"), [me]
new Call new Literal("#{res}.push"), [me]
else
new Return @locationData, me
new Return me
# 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
@ -132,7 +134,7 @@ exports.Base = class Base
child.traverseChildren crossScope, func
invert: ->
new Op @locationData, '!', this
new Op '!', this
unwrapAll: ->
node = this
@ -155,13 +157,23 @@ exports.Base = class Base
# Is this node used to assign a certain variable?
assigns: NO
# For this node and all descendents, set the location data to `locationData` if the location
# data is not already set.
updateLocationDataIfMissing: (locationData) ->
if not @locationData
@locationData = {}
extend @locationData, locationData
@eachChild (child) ->
child.updateLocationDataIfMissing locationData
#### Block
# The block 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.Block = class Block extends Base
constructor: (@locationData, nodes) ->
constructor: (nodes) ->
@expressions = compact flatten nodes or []
children: ['expressions']
@ -298,9 +310,9 @@ exports.Block = class Block extends Base
# Wrap up the given nodes as a **Block**, unless it already happens
# to be one.
@wrap: (locationData, nodes) ->
@wrap: (nodes) ->
return nodes[0] if nodes.length is 1 and nodes[0] instanceof Block
new Block locationData, nodes
new Block nodes
#### Literal
@ -308,7 +320,7 @@ exports.Block = class Block extends Base
# JavaScript without translation, such as: strings, numbers,
# `true`, `false`, `null`...
exports.Literal = class Literal extends Base
constructor: (@locationData, @value) ->
constructor: (@value) ->
makeReturn: ->
if @isStatement() then this else super
@ -341,16 +353,12 @@ exports.Literal = class Literal extends Base
' "' + @value + '"'
class exports.Undefined extends Base
constructor: (@locationData) ->
isAssignable: NO
isComplex: NO
compileNode: (o) ->
if o.level >= LEVEL_ACCESS then '(void 0)' else 'void 0'
class exports.Null extends Base
constructor: (@locationData) ->
isAssignable: NO
isComplex: NO
compileNode: -> "null"
@ -359,14 +367,14 @@ class exports.Bool extends Base
isAssignable: NO
isComplex: NO
compileNode: -> @val
constructor: (@locationData, @val) ->
constructor: (@val) ->
#### Return
# A `return` is a *pureStatement* -- wrapping it in a closure wouldn't
# make sense.
exports.Return = class Return extends Base
constructor: (@locationData, expr) ->
constructor: (expr) ->
@expression = expr if expr and not expr.unwrap().isUndefined
children: ['expression']
@ -387,9 +395,8 @@ exports.Return = class Return extends Base
# A value, variable or literal or parenthesized, indexed or dotted into,
# or vanilla.
exports.Value = class Value extends Base
constructor: (locationData, base, props, tag) ->
constructor: (base, props, tag) ->
return base if not props and base instanceof Value
@locationData = locationData
@base = base
@properties = props or []
@[tag] = true if tag
@ -439,16 +446,16 @@ exports.Value = class Value extends Base
name = last @properties
if @properties.length < 2 and not @base.isComplex() and not name?.isComplex()
return [this, this] # `a` `a.b`
base = new Value @locationData, @base, @properties[...-1]
base = new Value @base, @properties[...-1]
if base.isComplex() # `a().b`
bref = new Literal @locationData, o.scope.freeVariable 'base'
base = new Value(@locationData, new Parens(@locationData, new Assign(@locationData, bref, base)))
bref = new Literal o.scope.freeVariable 'base'
base = new Value new Parens new Assign bref, base
return [base, bref] unless name # `a()`
if name.isComplex() # `a[b()]`
nref = new Literal @locationData, o.scope.freeVariable 'name'
name = new Index @locationData, new Assign(@locationData, nref, name.index)
nref = new Index @locationData, nref
[base.add(name), new Value(@locationData, bref or base.base, [nref or name])]
nref = new Literal o.scope.freeVariable 'name'
name = new Index new Assign nref, name.index
nref = new Index nref
[base.add(name), new Value(bref or base.base, [nref or name])]
# We compile a value to JavaScript by compiling and joining each property.
# Things get much more interesting if the chain of properties has *soak*
@ -471,13 +478,13 @@ exports.Value = class Value extends Base
return ifn
for prop, i in @properties when prop.soak
prop.soak = off
fst = new Value @locationData, @base, @properties[...i]
snd = new Value @locationData, @base, @properties[i..]
fst = new Value @base, @properties[...i]
snd = new Value @base, @properties[i..]
if fst.isComplex()
ref = new Literal @locationData, o.scope.freeVariable 'ref'
fst = new Parens @locationData, new Assign(@locationData, ref, fst)
ref = new Literal o.scope.freeVariable 'ref'
fst = new Parens new Assign ref, fst
snd.base = ref
return new If @locationData, new Existence(@locationData, fst), snd, soak: on
return new If new Existence(fst), snd, soak: on
null
@unfoldedSoak = result or no
@ -486,7 +493,7 @@ exports.Value = class Value extends Base
# CoffeeScript passes through block comments as JavaScript block comments
# at the same position.
exports.Comment = class Comment extends Base
constructor: (@locationData, @comment) ->
constructor: (@comment) ->
isStatement: YES
makeReturn: THIS
@ -501,7 +508,7 @@ exports.Comment = class Comment extends Base
# Node for a function invocation. Takes care of converting `super()` calls into
# calls against the prototype's function of the same name.
exports.Call = class Call extends Base
constructor: (@locationData, variable, @args = [], @soak) ->
constructor: (variable, @args = [], @soak) ->
@isNew = false
@isSuper = variable is 'super'
@variable = if @isSuper then null else variable
@ -525,10 +532,10 @@ exports.Call = class Call extends Base
{name} = method
throw SyntaxError 'cannot call super on an anonymous function.' unless name?
if method.klass
accesses = [new Access(@locationData, new Literal @locationData, '__super__')]
(accesses.push new Access(@locationData, new Literal @locationData, 'constructor')) if method.static
accesses.push new Access(@locationData, new Literal @locationData, name)
(new Value(@locationData, new Literal(@locationData, method.klass), accesses)).compile o
accesses = [new Access(new Literal '__super__')]
accesses.push new Access new Literal 'constructor' if method.static
accesses.push new Access new Literal name
(new Value (new Literal method.klass), accesses).compile o
else
"#{name}.__super__.constructor"
@ -542,14 +549,14 @@ exports.Call = class Call extends Base
if @soak
if @variable
return ifn if ifn = unfoldSoak o, this, 'variable'
[left, rite] = new Value(@locationData, @variable).cacheReference o
[left, rite] = new Value(@variable).cacheReference o
else
left = new Literal @locationData, @superReference o
rite = new Value @locationData, left
rite = new Call @locationData, rite, @args
left = new Literal @superReference o
rite = new Value left
rite = new Call rite, @args
rite.isNew = @isNew
left = new Literal @locationData, "typeof #{ left.compile o } === \"function\""
return new If @locationData, left, new Value(@locationData, rite), soak: yes
left = new Literal "typeof #{ left.compile o } === \"function\""
return new If left, new Value(rite), soak: yes
call = this
list = []
loop
@ -580,7 +587,7 @@ exports.Call = class Call extends Base
obj = null
for prop in node.base.properties
if prop instanceof Assign or prop instanceof Comment
nodes.push obj = new Obj @locationData, properties = [], true if not obj
nodes.push obj = new Obj properties = [], true if not obj
properties.push prop
else
nodes.push prop
@ -601,6 +608,7 @@ exports.Call = class Call extends Base
# `super()` is converted into a call against the superclass's implementation
# of the current function.
# TODO: This looks like it is never called?
compileSuper: (args, o) ->
"#{@superReference(o)}.call(#{@superThis(o)}#{ if args.length then ', ' else '' }#{args})"
@ -619,7 +627,7 @@ exports.Call = class Call extends Base
#{idt}return Object(result) === result ? result : child;
#{@tab}})(#{ @variable.compile o, LEVEL_LIST }, #{splatArgs}, function(){})
"""
base = new Value @locationData, @variable
base = new Value @variable
if (name = base.properties.pop()) and base.isComplex()
ref = o.scope.freeVariable 'ref'
fun = "(#{ref} = #{ base.compile o, LEVEL_LIST })#{ name.compile o }"
@ -639,20 +647,20 @@ exports.Call = class Call extends Base
# After `goog.inherits` from the
# [Closure Library](http://closure-library.googlecode.com/svn/docs/closureGoogBase.js.html).
exports.Extends = class Extends extends Base
constructor: (@locationData, @child, @parent) ->
constructor: (@child, @parent) ->
children: ['child', 'parent']
# Hooks one constructor into another's prototype chain.
compile: (o) ->
new Call(@locationData, new Value(@locationData, new Literal @locationData, utility 'extends'), [@child, @parent]).compile o
new Call(new Value(new Literal utility 'extends'), [@child, @parent]).compile o
#### Access
# A `.` access into a property of a value, or the `::` shorthand for
# an access into the object's prototype.
exports.Access = class Access extends Base
constructor: (@locationData, @name, tag) ->
constructor: (@name, tag) ->
@name.asKey = yes
@soak = tag is 'soak'
@ -668,7 +676,7 @@ exports.Access = class Access extends Base
# A `[ ... ]` indexed access into an array or object.
exports.Index = class Index extends Base
constructor: (@locationData, @index) ->
constructor: (@index) ->
children: ['index']
@ -687,7 +695,7 @@ exports.Range = class Range extends Base
children: ['from', 'to']
constructor: (@locationData, @from, @to, tag) ->
constructor: (@from, @to, tag) ->
@exclusive = tag is 'exclusive'
@equals = if @exclusive then '' else '='
@ -779,7 +787,7 @@ exports.Slice = class Slice extends Base
children: ['range']
constructor: (@locationData, @range) ->
constructor: (@range) ->
super()
# We have to be careful when trying to slice through the end of the array,
@ -803,7 +811,7 @@ exports.Slice = class Slice extends Base
# An object literal, nothing fancy.
exports.Obj = class Obj extends Base
constructor: (@locationData, props, @generated = false) ->
constructor: (props, @generated = false) ->
@objects = @properties = props or []
children: ['properties']
@ -825,10 +833,10 @@ exports.Obj = class Obj extends Base
',\n'
indent = if prop instanceof Comment then '' else idt
if prop instanceof Value and prop.this
prop = new Assign @locationData, prop.properties[0].name, prop, 'object'
prop = new Assign prop.properties[0].name, prop, 'object'
if prop not instanceof Comment
if prop not instanceof Assign
prop = new Assign @locationData, prop, prop, 'object'
prop = new Assign prop, prop, 'object'
(prop.variable.base or prop.variable).asKey = yes
indent + prop.compile(o, LEVEL_TOP) + join
props = props.join ''
@ -843,7 +851,7 @@ exports.Obj = class Obj extends Base
# An array literal.
exports.Arr = class Arr extends Base
constructor: (@locationData, objs) ->
constructor: (objs) ->
@objects = objs or []
children: ['objects']
@ -871,7 +879,7 @@ exports.Arr = class Arr extends Base
# Initialize a **Class** with its name, an optional superclass, and a
# list of prototype property assignments.
exports.Class = class Class extends Base
constructor: (@locationData, @variable, @parent, @body = new Block(@locationData)) ->
constructor: (@variable, @parent, @body = new Block) ->
@boundFuncs = []
@body.classBody = yes
@ -904,8 +912,8 @@ exports.Class = class Class extends Base
addBoundFunctions: (o) ->
if @boundFuncs.length
for bvar in @boundFuncs
lhs = (new Value @locationData, (new Literal @locationData, "this"), [new Access @locationData, bvar]).compile o
@ctor.body.unshift new Literal @locationData, "#{lhs} = #{utility 'bind'}(#{lhs}, this)"
lhs = (new Value (new Literal "this"), [new Access bvar]).compile o
@ctor.body.unshift new Literal "#{lhs} = #{utility 'bind'}(#{lhs}, this)"
# Merge the properties from a top-level object as prototypal properties
# on the class.
@ -925,14 +933,14 @@ exports.Class = class Class extends Base
assign = @ctor = func
else
@externalCtor = o.scope.freeVariable 'class'
assign = new Assign @locationData, new Literal(@locationData, @externalCtor), func
assign = new Assign new Literal(@externalCtor), func
else
if assign.variable.this
func.static = yes
if func.bound
func.context = name
else
assign.variable = new Value(@locationData, new Literal(@locationData, name), [(new Access @locationData, new Literal(@locationData, 'prototype')), new Access(@locationData, base) ])
assign.variable = new Value(new Literal(name), [(new Access new Literal 'prototype'), new Access base ])
if func instanceof Code and func.bound
@boundFuncs.push base
func.bound = no
@ -963,9 +971,9 @@ exports.Class = class Class extends Base
# configured.
ensureConstructor: (name) ->
if not @ctor
@ctor = new Code @locationData
@ctor.body.push new Literal @locationData, "#{name}.__super__.constructor.apply(this, arguments)" if @parent
@ctor.body.push new Literal @locationData, "#{@externalCtor}.apply(this, arguments)" if @externalCtor
@ctor = new Code
@ctor.body.push new Literal "#{name}.__super__.constructor.apply(this, arguments)" if @parent
@ctor.body.push new Literal "#{@externalCtor}.apply(this, arguments)" if @externalCtor
@ctor.body.makeReturn()
@body.expressions.unshift @ctor
@ctor.ctor = @ctor.name = name
@ -979,7 +987,7 @@ exports.Class = class Class extends Base
decl = @determineName()
name = decl or '_Class'
name = "_#{name}" if name.reserved
lname = new Literal @locationData, name
lname = new Literal name
@hoistDirectivePrologue()
@setContext name
@ -991,17 +999,17 @@ exports.Class = class Class extends Base
@body.expressions.unshift @directives...
@addBoundFunctions o
call = Closure.wrap @locationData, @body
call = Closure.wrap @body
if @parent
@superClass = new Literal @locationData, o.scope.freeVariable 'super', no
@body.expressions.unshift new Extends @locationData, lname, @superClass
@superClass = new Literal o.scope.freeVariable 'super', no
@body.expressions.unshift new Extends lname, @superClass
call.args.push @parent
params = call.variable.params or call.variable.base.params
params.push new Param @locationData, @superClass
params.push new Param @superClass
klass = new Parens @locationData, call, yes
klass = new Assign @locationData, @variable, klass if @variable
klass = new Parens call, yes
klass = new Assign @variable, klass if @variable
klass.compile o
#### Assign
@ -1009,7 +1017,7 @@ exports.Class = class Class extends Base
# The **Assign** is used to assign a local variable to value, or to set the
# property of an object -- including within object literals.
exports.Assign = class Assign extends Base
constructor: (@locationData, @variable, @value, @context, options) ->
constructor: (@variable, @value, @context, options) ->
@param = options and options.param
@subpattern = options and options.subpattern
forbidden = (name = @variable.unwrapAll().value) in STRICT_PROSCRIBED
@ -1071,18 +1079,18 @@ exports.Assign = class Assign extends Base
{variable: {base: idx}, value: obj} = obj
else
if obj.base instanceof Parens
[obj, idx] = new Value(@locationData, obj.unwrapAll()).cacheReference o
[obj, idx] = new Value(obj.unwrapAll()).cacheReference o
else
idx = if isObject
if obj.this then obj.properties[0].name else obj
else
new Literal @locationData, 0
new Literal 0
acc = IDENTIFIER.test idx.unwrap().value or 0
value = new Value @locationData, value
value.properties.push new (if acc then Access else Index) @locationData, idx
value = new Value value
value.properties.push new (if acc then Access else Index) idx
if obj.unwrap().value in RESERVED
throw new SyntaxError "assignment to a reserved word: #{obj.compile o} = #{value.compile o}"
return new Assign(@locationData, obj, value, null, param: @param).compile o, LEVEL_TOP
return new Assign(obj, value, null, param: @param).compile o, LEVEL_TOP
vvar = value.compile o, LEVEL_LIST
assigns = []
splat = false
@ -1099,7 +1107,7 @@ exports.Assign = class Assign extends Base
else
# A shorthand `{a, b, @c} = val` pattern-match.
if obj.base instanceof Parens
[obj, idx] = new Value(@locationData, obj.unwrapAll()).cacheReference o
[obj, idx] = new Value(obj.unwrapAll()).cacheReference o
else
idx = if obj.this then obj.properties[0].name else obj
if not splat and obj instanceof Splat
@ -1111,7 +1119,7 @@ exports.Assign = class Assign extends Base
val += ", #{ivar} = #{vvar}.length - #{rest}) : (#{ivar} = #{i}, [])"
else
val += ") : []"
val = new Literal @locationData, val
val = new Literal val
splat = "#{ivar}++"
else
name = obj.unwrap().value
@ -1120,14 +1128,14 @@ exports.Assign = class Assign extends Base
throw new SyntaxError \
"multiple splats are disallowed in an assignment: #{obj}..."
if typeof idx is 'number'
idx = new Literal @locationData, splat or idx
idx = new Literal splat or idx
acc = no
else
acc = isObject and IDENTIFIER.test idx.unwrap().value or 0
val = new Value @locationData, new Literal(@locationData, vvar), [new (if acc then Access else Index) @locationData, idx]
val = new Value new Literal(vvar), [new (if acc then Access else Index) idx]
if name? and name in RESERVED
throw new SyntaxError "assignment to a reserved word: #{obj.compile o} = #{val.compile o}"
assigns.push new Assign(@locationData, obj, val, null, param: @param, subpattern: yes).compile o, LEVEL_LIST
assigns.push new Assign(obj, val, null, param: @param, subpattern: yes).compile o, LEVEL_LIST
assigns.push vvar unless top or @subpattern
code = assigns.join ', '
if o.level < LEVEL_LIST then code else "(#{code})"
@ -1142,7 +1150,7 @@ exports.Assign = class Assign extends Base
left.base.value != "this" and not o.scope.check left.base.value
throw new Error "the variable \"#{left.base.value}\" can't be assigned with #{@context} because it has not been defined."
if "?" in @context then o.isExistentialEquals = true
new Op(@locationData, @context[...-1], left, new Assign(@locationData, right, @value, '=') ).compile o
new Op(@context[...-1], left, new Assign(right, @value, '=') ).compile o
# Compile the assignment from an array splice literal, using JavaScript's
# `Array#splice` method.
@ -1169,9 +1177,9 @@ exports.Assign = class Assign extends Base
# When for the purposes of walking the contents of a function body, the Code
# has no *children* -- they're within the inner scope.
exports.Code = class Code extends Base
constructor: (@locationData, params, body, tag) ->
constructor: (params, body, tag) ->
@params = params or []
@body = body or new Block @locationData
@body = body or new Block
@bound = tag is 'boundfunc'
@context = '_this' if @bound
@ -1200,21 +1208,20 @@ exports.Code = class Code extends Base
for {name: p} in @params
if p.this then p = p.properties[0].name
if p.value then o.scope.add p.value, 'var', yes
splats = new Assign(@locationData,
new Value(@locationData, new Arr(@locationData, p.asReference o for p in @params)),
new Value(@locationData, new Literal(@locationData, 'arguments')))
splats = new Assign new Value(new Arr(p.asReference o for p in @params)),
new Value new Literal 'arguments'
break
for param in @params
if param.isComplex()
val = ref = param.asReference o
val = new Op @locationData, '?', ref, param.value if param.value
exprs.push new Assign @locationData, new Value(@locationData, param.name), val, '=', param: yes
val = new Op '?', ref, param.value if param.value
exprs.push new Assign new Value(param.name), val, '=', param: yes
else
ref = param
if param.value
lit = new Literal @locationData, ref.name.value + ' == null'
val = new Assign @locationData, new Value(@locationData, param.name), param.value, '='
exprs.push new If @locationData, lit, val
lit = new Literal ref.name.value + ' == null'
val = new Assign new Value(param.name), param.value, '='
exprs.push new If lit, val
params.push ref unless splats
wasEmpty = @body.isEmpty()
exprs.unshift splats if splats
@ -1256,7 +1263,7 @@ exports.Code = class Code extends Base
# 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.Param = class Param extends Base
constructor: (@locationData, @name, @value, @splat) ->
constructor: (@name, @value, @splat) ->
if (name = @name.unwrapAll().value) in STRICT_PROSCRIBED
throw SyntaxError "parameter name \"#{name}\" is not allowed"
@ -1271,11 +1278,11 @@ exports.Param = class Param extends Base
if node.this
node = node.properties[0].name
if node.value.reserved
node = new Literal @locationData, o.scope.freeVariable node.value
node = new Literal o.scope.freeVariable node.value
else if node.isComplex()
node = new Literal @locationData, o.scope.freeVariable 'arg'
node = new Value @locationData, node
node = new Splat @locationData, node if @splat
node = new Literal o.scope.freeVariable 'arg'
node = new Value node
node = new Splat node if @splat
@reference = node
isComplex: ->
@ -1327,8 +1334,8 @@ exports.Splat = class Splat extends Base
isAssignable: YES
constructor: (@locationData, name) ->
@name = if name.compile then name else new Literal @locationData, name
constructor: (name) ->
@name = if name.compile then name else new Literal name
assigns: (name) ->
@name.assigns name
@ -1364,7 +1371,7 @@ exports.Splat = class Splat extends Base
# it, all other loops can be manufactured. Useful in cases where you need more
# flexibility or more speed than a comprehension can provide.
exports.While = class While extends Base
constructor: (@locationData, condition, options) ->
constructor: (condition, options) ->
@condition = if options?.invert then condition.invert() else condition
@guard = options?.guard
@ -1404,9 +1411,9 @@ exports.While = class While extends Base
set = "#{@tab}#{rvar} = [];\n"
if @guard
if body.expressions.length > 1
body.expressions.unshift new If(@locationData, new Parens(@locationData, @guard)).invert(), new Literal(@locationData, "continue")
body.expressions.unshift new If (new Parens @guard).invert(), new Literal "continue"
else
body = Block.wrap @locationData, [new If @locationData, @guard, body] if @guard
body = Block.wrap [new If @guard, body] if @guard
body = "\n#{ body.compile o, LEVEL_TOP }\n#{@tab}"
code = set + @tab + "while (#{ @condition.compile o, LEVEL_PAREN }) {#{body}}"
if @returns
@ -1418,13 +1425,13 @@ exports.While = class While extends Base
# Simple Arithmetic and logical operations. Performs some conversion from
# CoffeeScript operations into their JavaScript equivalents.
exports.Op = class Op extends Base
constructor: (@locationData, op, first, second, flip ) ->
return new In @locationData, first, second if op is 'in'
constructor: (op, first, second, flip ) ->
return new In first, second if op is 'in'
if op is 'do'
return @generateDo first
if op is 'new'
return first.newInstance() if first instanceof Call and not first.do and not first.isNew
first = new Parens @locationData, first if first instanceof Code and first.bound or first.do
first = new Parens first if first instanceof Code and first.bound or first.do
@operator = CONVERSIONS[op] or op
@first = first
@second = second
@ -1464,7 +1471,7 @@ exports.Op = class Op extends Base
while curr and curr.operator
allInvertable and= (curr.operator of INVERSIONS)
curr = curr.first
return new Parens(@locationData, this).invert() unless allInvertable
return new Parens(this).invert() unless allInvertable
curr = this
while curr and curr.operator
curr.invert = !curr.invert
@ -1477,12 +1484,12 @@ exports.Op = class Op extends Base
@first.invert()
this
else if @second
new Parens(@locationData, this).invert()
new Parens(this).invert()
else if @operator is '!' and (fst = @first.unwrap()) instanceof Op and
fst.operator in ['!', 'in', 'instanceof']
fst
else
new Op @locationData, '!', this
new Op '!', this
unfoldSoak: (o) ->
@operator in ['++', '--', 'delete'] and unfoldSoak o, this, 'first'
@ -1499,7 +1506,7 @@ exports.Op = class Op extends Base
delete param.value
else
passedParams.push param
call = new Call @locationData, exp, passedParams
call = new Call exp, passedParams
call.do = yes
call
@ -1532,12 +1539,12 @@ exports.Op = class Op extends Base
compileExistence: (o) ->
if @first.isComplex()
ref = new Literal @locationData, o.scope.freeVariable 'ref'
fst = new Parens @locationData, new Assign(@locationData, ref, @first)
ref = new Literal o.scope.freeVariable 'ref'
fst = new Parens new Assign ref, @first
else
fst = @first
ref = fst
new If(@locationData, new Existence(@locationData, fst), ref, type: 'if').addElse(@second).compile o
new If(new Existence(fst), ref, type: 'if').addElse(@second).compile o
# Compile a unary **Op**.
compileUnary: (o) ->
@ -1546,12 +1553,12 @@ exports.Op = class Op extends Base
@first.negated = not @first.negated
return @first.compile o
if o.level >= LEVEL_ACCESS
return (new Parens @locationData, this).compile o
return (new Parens this).compile o
plusMinus = op in ['+', '-']
parts.push ' ' if op in ['new', 'typeof', 'delete'] or
plusMinus and @first instanceof Op and @first.operator is op
if (plusMinus && @first instanceof Op) or (op is 'new' and @first.isStatement o)
@first = new Parens @locationData, @first
@first = new Parens @first
parts.push @first.compile o, LEVEL_OP
parts.reverse() if @flip
parts.join ''
@ -1561,7 +1568,7 @@ exports.Op = class Op extends Base
#### In
exports.In = class In extends Base
constructor: (@locationData, @object, @array) ->
constructor: (@object, @array) ->
children: ['object', 'array']
@ -1600,7 +1607,7 @@ exports.In = class In extends Base
# A classic *try/catch/finally* block.
exports.Try = class Try extends Base
constructor: (@locationData, @attempt, @error, @recovery, @ensure) ->
constructor: (@attempt, @error, @recovery, @ensure) ->
children: ['attempt', 'recovery', 'ensure']
@ -1621,8 +1628,8 @@ exports.Try = class Try extends Base
catchPart = if @recovery
if @error.isObject?()
placeholder = new Literal @locationData, '_error'
@recovery.unshift new Assign @locationData, @error, placeholder
placeholder = new Literal '_error'
@recovery.unshift new Assign @error, placeholder
@error = placeholder
if @error.value in STRICT_PROSCRIBED
throw SyntaxError "catch variable may not be \"#{@error.value}\""
@ -1641,7 +1648,7 @@ exports.Try = class Try extends Base
# Simple node to throw an exception.
exports.Throw = class Throw extends Base
constructor: (@locationData, @expression) ->
constructor: (@expression) ->
children: ['expression']
@ -1660,7 +1667,7 @@ exports.Throw = class Throw extends Base
# similar to `.nil?` in Ruby, and avoids having to consult a JavaScript truth
# table.
exports.Existence = class Existence extends Base
constructor: (@locationData, @expression) ->
constructor: (@expression) ->
children: ['expression']
@ -1685,7 +1692,7 @@ exports.Existence = class Existence extends Base
#
# Parentheses are a good way to force any statement to become an expression.
exports.Parens = class Parens extends Base
constructor: (@locationData, @body) ->
constructor: (@body) ->
children: ['body']
@ -1712,9 +1719,9 @@ exports.Parens = class Parens extends Base
# the current index of the loop as a second parameter. Unlike Ruby blocks,
# you can map and filter in a single pass.
exports.For = class For extends While
constructor: (@locationData, body, source) ->
constructor: (body, source) ->
{@source, @guard, @step, @name, @index} = source
@body = Block.wrap @locationData, [body]
@body = Block.wrap [body]
@own = !!source.own
@object = !!source.object
[@name, @index] = [@index, @name] if @object
@ -1732,7 +1739,7 @@ exports.For = class For extends While
# comprehensions. Some of the generated code can be shared in common, and
# some cannot.
compileNode: (o) ->
body = Block.wrap @locationData, [@body]
body = Block.wrap [@body]
lastJumps = last(body.expressions)?.jumps()
@returns = no if lastJumps and lastJumps instanceof Return
source = if @range then @source.base else @source
@ -1773,11 +1780,11 @@ exports.For = class For extends While
body.makeReturn rvar
if @guard
if body.expressions.length > 1
body.expressions.unshift new If @locationData, (new Parens @locationData, @guard).invert(), new Literal(@locationData, "continue")
body.expressions.unshift new If (new Parens @guard).invert(), new Literal "continue"
else
body = Block.wrap @locationData, [new If @locationData, @guard, body] if @guard
body = Block.wrap [new If @guard, body] if @guard
if @pattern
body.expressions.unshift new Assign @locationData, @name, new Literal(@locationData, "#{svar}[#{kvar}]")
body.expressions.unshift new Assign @name, new Literal "#{svar}[#{kvar}]"
defPart += @pluckDirectCall o, body
varPart = "\n#{idt1}#{namePart};" if namePart
if @object
@ -1801,19 +1808,19 @@ exports.For = class For extends While
val.properties.length is 1 and
val.properties[0].name?.value in ['call', 'apply'])
fn = val.base?.unwrapAll() or val
ref = new Literal @locationData, o.scope.freeVariable 'fn'
base = new Value @locationData, ref
ref = new Literal o.scope.freeVariable 'fn'
base = new Value ref
if val.base
[val.base, base] = [base, val]
body.expressions[idx] = new Call @locationData, base, expr.args
defs += @tab + new Assign(@locationData, ref, fn).compile(o, LEVEL_TOP) + ';\n'
body.expressions[idx] = new Call base, expr.args
defs += @tab + new Assign(ref, fn).compile(o, LEVEL_TOP) + ';\n'
defs
#### Switch
# A JavaScript *switch* statement. Converts into a returnable expression on-demand.
exports.Switch = class Switch extends Base
constructor: (@locationData, @subject, @cases, @otherwise) ->
constructor: (@subject, @cases, @otherwise) ->
children: ['subject', 'cases', 'otherwise']
@ -1826,7 +1833,7 @@ exports.Switch = class Switch extends Base
makeReturn: (res) ->
pair[1].makeReturn res for pair in @cases
@otherwise or= new Block @locationData, [new Literal @locationData, 'void 0'] if res
@otherwise or= new Block [new Literal 'void 0'] if res
@otherwise?.makeReturn res
this
@ -1854,7 +1861,7 @@ exports.Switch = class Switch extends Base
# Single-expression **Ifs** are compiled into conditional operators if possible,
# because ternaries are already proper expressions, and don't need conversion.
exports.If = class If extends Base
constructor: (@locationData, condition, @body, options = {}) ->
constructor: (condition, @body, options = {}) ->
@condition = if options.type is 'unless' then condition.invert() else condition
@elseBody = null
@isChain = false
@ -1886,13 +1893,13 @@ exports.If = class If extends Base
if @isStatement o then @compileStatement o else @compileExpression o
makeReturn: (res) ->
@elseBody or= new Block @locationData, [new Literal @locationData, 'void 0'] if res
@body and= new Block @locationData, [@body.makeReturn res]
@elseBody and= new Block @locationData, [@elseBody.makeReturn res]
@elseBody or= new Block [new Literal 'void 0'] if res
@body and= new Block [@body.makeReturn res]
@elseBody and= new Block [@elseBody.makeReturn res]
this
ensureBlock: (node) ->
if node instanceof Block then node else new Block @locationData, [node]
if node instanceof Block then node else new Block [node]
# Compile the `If` as a regular *if-else* statement. Flattened chains
# force inner *else* bodies into statement form.
@ -1901,7 +1908,7 @@ exports.If = class If extends Base
exeq = del o, 'isExistentialEquals'
if exeq
return new If(@locationData, @condition.invert(), @elseBodyNode(), type: 'if').compile o
return new If(@condition.invert(), @elseBodyNode(), type: 'if').compile o
cond = @condition.compile o, LEVEL_PAREN
o.indent += TAB
@ -1940,18 +1947,18 @@ 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: (locationData, expressions, statement, noReturn) ->
wrap: (expressions, statement, noReturn) ->
return expressions if expressions.jumps()
func = new Code locationData, [], Block.wrap(locationData, [expressions])
func = new Code [], Block.wrap [expressions]
args = []
if (mentionsArgs = expressions.contains @literalArgs) or expressions.contains @literalThis
meth = new Literal locationData, if mentionsArgs then 'apply' else 'call'
args = [new Literal locationData, 'this']
args.push new Literal locationData, 'arguments' if mentionsArgs
func = new Value @locationData, func, [new Access locationData, meth]
meth = new Literal if mentionsArgs then 'apply' else 'call'
args = [new Literal 'this']
args.push new Literal 'arguments' if mentionsArgs
func = new Value func, [new Access meth]
func.noReturn = noReturn
call = new Call locationData, func, args
if statement then Block.wrap locationData, [call] else call
call = new Call func, args
if statement then Block.wrap [call] else call
literalArgs: (node) ->
node instanceof Literal and node.value is 'arguments' and not node.asKey
@ -1965,7 +1972,7 @@ Closure =
unfoldSoak = (o, parent, name) ->
return unless ifn = parent[name].unfoldSoak o
parent[name] = ifn.body
ifn.body = new Value @locationData, parent
ifn.body = new Value parent
ifn
# Constants