1 // Generated by CoffeeScript 1.8.0
3 var Access, Arr, Assign, Base, Block, Call, Class, Code, CodeFragment, Comment, Existence, Expansion, Extends, For, HEXNUM, IDENTIFIER, IDENTIFIER_STR, IS_REGEX, IS_STRING, If, In, Index, LEVEL_ACCESS, LEVEL_COND, LEVEL_LIST, LEVEL_OP, LEVEL_PAREN, LEVEL_TOP, Literal, METHOD_DEF, NEGATE, NO, NUMBER, 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, fragmentsToText, isLiteralArguments, isLiteralThis, last, locationDataToString, merge, multident, parseNum, some, starts, throwSyntaxError, unfoldSoak, utility, _ref, _ref1,
4 __hasProp = {}.hasOwnProperty,
5 __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; },
6 __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 Error.stackTraceLimit = Infinity;
11 Scope = require('./scope').Scope;
13 _ref = require('./lexer'), RESERVED = _ref.RESERVED, STRICT_PROSCRIBED = _ref.STRICT_PROSCRIBED;
15 _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, locationDataToString = _ref1.locationDataToString, throwSyntaxError = _ref1.throwSyntaxError;
17 exports.extend = extend;
19 exports.addLocationDataFn = addLocationDataFn;
34 this.negated = !this.negated;
38 exports.CodeFragment = CodeFragment = (function() {
39 function CodeFragment(parent, code) {
41 this.code = "" + code;
42 this.locationData = parent != null ? parent.locationData : void 0;
43 this.type = (parent != null ? (_ref2 = parent.constructor) != null ? _ref2.name : void 0 : void 0) || 'unknown';
46 CodeFragment.prototype.toString = function() {
47 return "" + this.code + (this.locationData ? ": " + locationDataToString(this.locationData) : '');
54 fragmentsToText = function(fragments) {
57 var _i, _len, _results;
59 for (_i = 0, _len = fragments.length; _i < _len; _i++) {
60 fragment = fragments[_i];
61 _results.push(fragment.code);
67 exports.Base = Base = (function() {
70 Base.prototype.compile = function(o, lvl) {
71 return fragmentsToText(this.compileToFragments(o, lvl));
74 Base.prototype.compileToFragments = function(o, lvl) {
80 node = this.unfoldSoak(o) || this;
82 if (o.level === LEVEL_TOP || !node.isStatement(o)) {
83 return node.compileNode(o);
85 return node.compileClosure(o);
89 Base.prototype.compileClosure = function(o) {
90 var args, argumentsNode, func, jumpNode, meth;
91 if (jumpNode = this.jumps()) {
92 jumpNode.error('cannot use a pure statement in an expression');
95 func = new Code([], Block.wrap([this]));
97 if ((argumentsNode = this.contains(isLiteralArguments)) || this.contains(isLiteralThis)) {
98 args = [new Literal('this')];
101 args.push(new Literal('arguments'));
105 func = new Value(func, [new Access(new Literal(meth))]);
107 return (new Call(func, args)).compileNode(o);
110 Base.prototype.cache = function(o, level, reused) {
112 if (!this.isComplex()) {
113 ref = level ? this.compileToFragments(o, level) : this;
116 ref = new Literal(reused || o.scope.freeVariable('ref'));
117 sub = new Assign(ref, this);
119 return [sub.compileToFragments(o, level), [this.makeCode(ref.value)]];
126 Base.prototype.cacheToCodeFragments = function(cacheValues) {
127 return [fragmentsToText(cacheValues[0]), fragmentsToText(cacheValues[1])];
130 Base.prototype.makeReturn = function(res) {
132 me = this.unwrapAll();
134 return new Call(new Literal("" + res + ".push"), [me]);
136 return new Return(me);
140 Base.prototype.contains = function(pred) {
143 this.traverseChildren(false, function(n) {
152 Base.prototype.lastNonComment = function(list) {
156 if (!(list[i] instanceof Comment)) {
163 Base.prototype.toString = function(idt, name) {
169 name = this.constructor.name;
171 tree = '\n' + idt + name;
175 this.eachChild(function(node) {
176 return tree += node.toString(idt + TAB);
181 Base.prototype.eachChild = function(func) {
182 var attr, child, _i, _j, _len, _len1, _ref2, _ref3;
183 if (!this.children) {
186 _ref2 = this.children;
187 for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
190 _ref3 = flatten([this[attr]]);
191 for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) {
193 if (func(child) === false) {
202 Base.prototype.traverseChildren = function(crossScope, func) {
203 return this.eachChild(function(child) {
206 if (recur !== false) {
207 return child.traverseChildren(crossScope, func);
212 Base.prototype.invert = function() {
213 return new Op('!', this);
216 Base.prototype.unwrapAll = function() {
219 while (node !== (node = node.unwrap())) {
225 Base.prototype.children = [];
227 Base.prototype.isStatement = NO;
229 Base.prototype.jumps = NO;
231 Base.prototype.isComplex = YES;
233 Base.prototype.isChainable = NO;
235 Base.prototype.isAssignable = NO;
237 Base.prototype.unwrap = THIS;
239 Base.prototype.unfoldSoak = NO;
241 Base.prototype.assigns = NO;
243 Base.prototype.updateLocationDataIfMissing = function(locationData) {
244 if (this.locationData) {
247 this.locationData = locationData;
248 return this.eachChild(function(child) {
249 return child.updateLocationDataIfMissing(locationData);
253 Base.prototype.error = function(message) {
254 return throwSyntaxError(message, this.locationData);
257 Base.prototype.makeCode = function(code) {
258 return new CodeFragment(this, code);
261 Base.prototype.wrapInBraces = function(fragments) {
262 return [].concat(this.makeCode('('), fragments, this.makeCode(')'));
265 Base.prototype.joinFragmentArrays = function(fragmentsList, joinStr) {
266 var answer, fragments, i, _i, _len;
268 for (i = _i = 0, _len = fragmentsList.length; _i < _len; i = ++_i) {
269 fragments = fragmentsList[i];
271 answer.push(this.makeCode(joinStr));
273 answer = answer.concat(fragments);
282 exports.Block = Block = (function(_super) {
283 __extends(Block, _super);
285 function Block(nodes) {
286 this.expressions = compact(flatten(nodes || []));
289 Block.prototype.children = ['expressions'];
291 Block.prototype.push = function(node) {
292 this.expressions.push(node);
296 Block.prototype.pop = function() {
297 return this.expressions.pop();
300 Block.prototype.unshift = function(node) {
301 this.expressions.unshift(node);
305 Block.prototype.unwrap = function() {
306 if (this.expressions.length === 1) {
307 return this.expressions[0];
313 Block.prototype.isEmpty = function() {
314 return !this.expressions.length;
317 Block.prototype.isStatement = function(o) {
318 var exp, _i, _len, _ref2;
319 _ref2 = this.expressions;
320 for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
322 if (exp.isStatement(o)) {
329 Block.prototype.jumps = function(o) {
330 var exp, jumpNode, _i, _len, _ref2;
331 _ref2 = this.expressions;
332 for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
334 if (jumpNode = exp.jumps(o)) {
340 Block.prototype.makeReturn = function(res) {
342 len = this.expressions.length;
344 expr = this.expressions[len];
345 if (!(expr instanceof Comment)) {
346 this.expressions[len] = expr.makeReturn(res);
347 if (expr instanceof Return && !expr.expression) {
348 this.expressions.splice(len, 1);
356 Block.prototype.compileToFragments = function(o, level) {
361 return Block.__super__.compileToFragments.call(this, o, level);
363 return this.compileRoot(o);
367 Block.prototype.compileNode = function(o) {
368 var answer, compiledNodes, fragments, index, node, top, _i, _len, _ref2;
370 top = o.level === LEVEL_TOP;
372 _ref2 = this.expressions;
373 for (index = _i = 0, _len = _ref2.length; _i < _len; index = ++_i) {
375 node = node.unwrapAll();
376 node = node.unfoldSoak(o) || node;
377 if (node instanceof Block) {
378 compiledNodes.push(node.compileNode(o));
381 fragments = node.compileToFragments(o);
382 if (!node.isStatement(o)) {
383 fragments.unshift(this.makeCode("" + this.tab));
384 fragments.push(this.makeCode(";"));
386 compiledNodes.push(fragments);
388 compiledNodes.push(node.compileToFragments(o, LEVEL_LIST));
393 return [].concat(this.joinFragmentArrays(compiledNodes, '\n\n'), this.makeCode("\n"));
395 return this.joinFragmentArrays(compiledNodes, '\n');
398 if (compiledNodes.length) {
399 answer = this.joinFragmentArrays(compiledNodes, ', ');
401 answer = [this.makeCode("void 0")];
403 if (compiledNodes.length > 1 && o.level >= LEVEL_LIST) {
404 return this.wrapInBraces(answer);
410 Block.prototype.compileRoot = function(o) {
411 var exp, fragments, i, name, prelude, preludeExps, rest, _i, _len, _ref2;
412 o.indent = o.bare ? '' : TAB;
415 o.scope = new Scope(null, this, null);
416 _ref2 = o.locals || [];
417 for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
419 o.scope.parameter(name);
423 preludeExps = (function() {
424 var _j, _len1, _ref3, _results;
425 _ref3 = this.expressions;
427 for (i = _j = 0, _len1 = _ref3.length; _j < _len1; i = ++_j) {
429 if (!(exp.unwrap() instanceof Comment)) {
436 rest = this.expressions.slice(preludeExps.length);
437 this.expressions = preludeExps;
438 if (preludeExps.length) {
439 prelude = this.compileNode(merge(o, {
442 prelude.push(this.makeCode("\n"));
444 this.expressions = rest;
446 fragments = this.compileWithDeclarations(o);
450 return [].concat(prelude, this.makeCode("(function() {\n"), fragments, this.makeCode("\n}).call(this);\n"));
453 Block.prototype.compileWithDeclarations = function(o) {
454 var assigns, declars, exp, fragments, i, post, rest, scope, spaced, _i, _len, _ref2, _ref3, _ref4;
457 _ref2 = this.expressions;
458 for (i = _i = 0, _len = _ref2.length; _i < _len; i = ++_i) {
461 if (!(exp instanceof Comment || exp instanceof Literal)) {
469 rest = this.expressions.splice(i, 9e9);
470 _ref3 = [this.spaced, false], spaced = _ref3[0], this.spaced = _ref3[1];
471 _ref4 = [this.compileNode(o), spaced], fragments = _ref4[0], this.spaced = _ref4[1];
472 this.expressions = rest;
474 post = this.compileNode(o);
476 if (scope.expressions === this) {
477 declars = o.scope.hasDeclarations();
478 assigns = scope.hasAssignments;
479 if (declars || assigns) {
481 fragments.push(this.makeCode('\n'));
483 fragments.push(this.makeCode("" + this.tab + "var "));
485 fragments.push(this.makeCode(scope.declaredVariables().join(', ')));
489 fragments.push(this.makeCode(",\n" + (this.tab + TAB)));
491 fragments.push(this.makeCode(scope.assignedVariables().join(",\n" + (this.tab + TAB))));
493 fragments.push(this.makeCode(";\n" + (this.spaced ? '\n' : '')));
494 } else if (fragments.length && post.length) {
495 fragments.push(this.makeCode("\n"));
498 return fragments.concat(post);
501 Block.wrap = function(nodes) {
502 if (nodes.length === 1 && nodes[0] instanceof Block) {
505 return new Block(nodes);
512 exports.Literal = Literal = (function(_super) {
513 __extends(Literal, _super);
515 function Literal(value) {
519 Literal.prototype.makeReturn = function() {
520 if (this.isStatement()) {
523 return Literal.__super__.makeReturn.apply(this, arguments);
527 Literal.prototype.isAssignable = function() {
528 return IDENTIFIER.test(this.value);
531 Literal.prototype.isStatement = function() {
533 return (_ref2 = this.value) === 'break' || _ref2 === 'continue' || _ref2 === 'debugger';
536 Literal.prototype.isComplex = NO;
538 Literal.prototype.assigns = function(name) {
539 return name === this.value;
542 Literal.prototype.jumps = function(o) {
543 if (this.value === 'break' && !((o != null ? o.loop : void 0) || (o != null ? o.block : void 0))) {
546 if (this.value === 'continue' && !(o != null ? o.loop : void 0)) {
551 Literal.prototype.compileNode = function(o) {
552 var answer, code, _ref2;
553 code = this.value === 'this' ? ((_ref2 = o.scope.method) != null ? _ref2.bound : void 0) ? o.scope.method.context : this.value : this.value.reserved ? "\"" + this.value + "\"" : this.value;
554 answer = this.isStatement() ? "" + this.tab + code + ";" : code;
555 return [this.makeCode(answer)];
558 Literal.prototype.toString = function() {
559 return ' "' + this.value + '"';
566 exports.Undefined = (function(_super) {
567 __extends(Undefined, _super);
569 function Undefined() {
570 return Undefined.__super__.constructor.apply(this, arguments);
573 Undefined.prototype.isAssignable = NO;
575 Undefined.prototype.isComplex = NO;
577 Undefined.prototype.compileNode = function(o) {
578 return [this.makeCode(o.level >= LEVEL_ACCESS ? '(void 0)' : 'void 0')];
585 exports.Null = (function(_super) {
586 __extends(Null, _super);
589 return Null.__super__.constructor.apply(this, arguments);
592 Null.prototype.isAssignable = NO;
594 Null.prototype.isComplex = NO;
596 Null.prototype.compileNode = function() {
597 return [this.makeCode("null")];
604 exports.Bool = (function(_super) {
605 __extends(Bool, _super);
607 Bool.prototype.isAssignable = NO;
609 Bool.prototype.isComplex = NO;
611 Bool.prototype.compileNode = function() {
612 return [this.makeCode(this.val)];
623 exports.Return = Return = (function(_super) {
624 __extends(Return, _super);
626 function Return(expression) {
627 this.expression = expression;
630 Return.prototype.children = ['expression'];
632 Return.prototype.isStatement = YES;
634 Return.prototype.makeReturn = THIS;
636 Return.prototype.jumps = THIS;
638 Return.prototype.compileToFragments = function(o, level) {
640 expr = (_ref2 = this.expression) != null ? _ref2.makeReturn() : void 0;
641 if (expr && !(expr instanceof Return)) {
642 return expr.compileToFragments(o, level);
644 return Return.__super__.compileToFragments.call(this, o, level);
648 Return.prototype.compileNode = function(o) {
651 answer.push(this.makeCode(this.tab + ("return" + (this.expression ? " " : ""))));
652 if (this.expression) {
653 answer = answer.concat(this.expression.compileToFragments(o, LEVEL_PAREN));
655 answer.push(this.makeCode(";"));
663 exports.Value = Value = (function(_super) {
664 __extends(Value, _super);
666 function Value(base, props, tag) {
667 if (!props && base instanceof Value) {
671 this.properties = props || [];
678 Value.prototype.children = ['base', 'properties'];
680 Value.prototype.add = function(props) {
681 this.properties = this.properties.concat(props);
685 Value.prototype.hasProperties = function() {
686 return !!this.properties.length;
689 Value.prototype.bareLiteral = function(type) {
690 return !this.properties.length && this.base instanceof type;
693 Value.prototype.isArray = function() {
694 return this.bareLiteral(Arr);
697 Value.prototype.isRange = function() {
698 return this.bareLiteral(Range);
701 Value.prototype.isComplex = function() {
702 return this.hasProperties() || this.base.isComplex();
705 Value.prototype.isAssignable = function() {
706 return this.hasProperties() || this.base.isAssignable();
709 Value.prototype.isSimpleNumber = function() {
710 return this.bareLiteral(Literal) && SIMPLENUM.test(this.base.value);
713 Value.prototype.isString = function() {
714 return this.bareLiteral(Literal) && IS_STRING.test(this.base.value);
717 Value.prototype.isRegex = function() {
718 return this.bareLiteral(Literal) && IS_REGEX.test(this.base.value);
721 Value.prototype.isAtomic = function() {
722 var node, _i, _len, _ref2;
723 _ref2 = this.properties.concat(this.base);
724 for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
726 if (node.soak || node instanceof Call) {
733 Value.prototype.isNotCallable = function() {
734 return this.isSimpleNumber() || this.isString() || this.isRegex() || this.isArray() || this.isRange() || this.isSplice() || this.isObject();
737 Value.prototype.isStatement = function(o) {
738 return !this.properties.length && this.base.isStatement(o);
741 Value.prototype.assigns = function(name) {
742 return !this.properties.length && this.base.assigns(name);
745 Value.prototype.jumps = function(o) {
746 return !this.properties.length && this.base.jumps(o);
749 Value.prototype.isObject = function(onlyGenerated) {
750 if (this.properties.length) {
753 return (this.base instanceof Obj) && (!onlyGenerated || this.base.generated);
756 Value.prototype.isSplice = function() {
757 return last(this.properties) instanceof Slice;
760 Value.prototype.looksStatic = function(className) {
762 return this.base.value === className && this.properties.length && ((_ref2 = this.properties[0].name) != null ? _ref2.value : void 0) !== 'prototype';
765 Value.prototype.unwrap = function() {
766 if (this.properties.length) {
773 Value.prototype.cacheReference = function(o) {
774 var base, bref, name, nref;
775 name = last(this.properties);
776 if (this.properties.length < 2 && !this.base.isComplex() && !(name != null ? name.isComplex() : void 0)) {
779 base = new Value(this.base, this.properties.slice(0, -1));
780 if (base.isComplex()) {
781 bref = new Literal(o.scope.freeVariable('base'));
782 base = new Value(new Parens(new Assign(bref, base)));
787 if (name.isComplex()) {
788 nref = new Literal(o.scope.freeVariable('name'));
789 name = new Index(new Assign(nref, name.index));
790 nref = new Index(nref);
792 return [base.add(name), new Value(bref || base.base, [nref || name])];
795 Value.prototype.compileNode = function(o) {
796 var fragments, prop, props, _i, _len;
797 this.base.front = this.front;
798 props = this.properties;
799 fragments = this.base.compileToFragments(o, (props.length ? LEVEL_ACCESS : null));
800 if ((this.base instanceof Parens || props.length) && SIMPLENUM.test(fragmentsToText(fragments))) {
801 fragments.push(this.makeCode('.'));
803 for (_i = 0, _len = props.length; _i < _len; _i++) {
805 fragments.push.apply(fragments, prop.compileToFragments(o));
810 Value.prototype.unfoldSoak = function(o) {
811 return this.unfoldedSoak != null ? this.unfoldedSoak : this.unfoldedSoak = (function(_this) {
813 var fst, i, ifn, prop, ref, snd, _i, _len, _ref2, _ref3;
814 if (ifn = _this.base.unfoldSoak(o)) {
815 (_ref2 = ifn.body.properties).push.apply(_ref2, _this.properties);
818 _ref3 = _this.properties;
819 for (i = _i = 0, _len = _ref3.length; _i < _len; i = ++_i) {
825 fst = new Value(_this.base, _this.properties.slice(0, i));
826 snd = new Value(_this.base, _this.properties.slice(i));
827 if (fst.isComplex()) {
828 ref = new Literal(o.scope.freeVariable('ref'));
829 fst = new Parens(new Assign(ref, fst));
832 return new If(new Existence(fst), snd, {
845 exports.Comment = Comment = (function(_super) {
846 __extends(Comment, _super);
848 function Comment(comment) {
849 this.comment = comment;
852 Comment.prototype.isStatement = YES;
854 Comment.prototype.makeReturn = THIS;
856 Comment.prototype.compileNode = function(o, level) {
858 comment = this.comment.replace(/^(\s*)#/gm, "$1 *");
859 code = "/*" + (multident(comment, this.tab)) + (__indexOf.call(comment, '\n') >= 0 ? "\n" + this.tab : '') + " */";
860 if ((level || o.level) === LEVEL_TOP) {
861 code = o.indent + code;
863 return [this.makeCode("\n"), this.makeCode(code)];
870 exports.Call = Call = (function(_super) {
871 __extends(Call, _super);
873 function Call(variable, args, soak) {
874 this.args = args != null ? args : [];
877 this.isSuper = variable === 'super';
878 this.variable = this.isSuper ? null : variable;
879 if (variable instanceof Value && variable.isNotCallable()) {
880 variable.error("literal is not a function");
884 Call.prototype.children = ['variable', 'args'];
886 Call.prototype.newInstance = function() {
888 base = ((_ref2 = this.variable) != null ? _ref2.base : void 0) || this.variable;
889 if (base instanceof Call && !base.isNew) {
897 Call.prototype.superReference = function(o) {
898 var accesses, method;
899 method = o.scope.namedMethod();
900 if (method != null ? method.klass : void 0) {
901 accesses = [new Access(new Literal('__super__'))];
902 if (method["static"]) {
903 accesses.push(new Access(new Literal('constructor')));
905 accesses.push(new Access(new Literal(method.name)));
906 return (new Value(new Literal(method.klass), accesses)).compile(o);
907 } else if (method != null ? method.ctor : void 0) {
908 return "" + method.name + ".__super__.constructor";
910 return this.error('cannot call super outside of an instance method.');
914 Call.prototype.superThis = function(o) {
916 method = o.scope.method;
917 return (method && !method.klass && method.context) || "this";
920 Call.prototype.unfoldSoak = function(o) {
921 var call, ifn, left, list, rite, _i, _len, _ref2, _ref3;
924 if (ifn = unfoldSoak(o, this, 'variable')) {
927 _ref2 = new Value(this.variable).cacheReference(o), left = _ref2[0], rite = _ref2[1];
929 left = new Literal(this.superReference(o));
930 rite = new Value(left);
932 rite = new Call(rite, this.args);
933 rite.isNew = this.isNew;
934 left = new Literal("typeof " + (left.compile(o)) + " === \"function\"");
935 return new If(left, new Value(rite), {
942 if (call.variable instanceof Call) {
944 call = call.variable;
947 if (!(call.variable instanceof Value)) {
951 if (!((call = call.variable.base) instanceof Call)) {
955 _ref3 = list.reverse();
956 for (_i = 0, _len = _ref3.length; _i < _len; _i++) {
959 if (call.variable instanceof Call) {
962 call.variable.base = ifn;
965 ifn = unfoldSoak(o, call, 'variable');
970 Call.prototype.compileNode = function(o) {
971 var arg, argIndex, compiledArgs, compiledArray, fragments, preface, _i, _len, _ref2, _ref3;
972 if ((_ref2 = this.variable) != null) {
973 _ref2.front = this.front;
975 compiledArray = Splat.compileSplattedArray(o, this.args, true);
976 if (compiledArray.length) {
977 return this.compileSplat(o, compiledArray);
981 for (argIndex = _i = 0, _len = _ref3.length; _i < _len; argIndex = ++_i) {
982 arg = _ref3[argIndex];
984 compiledArgs.push(this.makeCode(", "));
986 compiledArgs.push.apply(compiledArgs, arg.compileToFragments(o, LEVEL_LIST));
990 preface = this.superReference(o) + (".call(" + (this.superThis(o)));
991 if (compiledArgs.length) {
994 fragments.push(this.makeCode(preface));
997 fragments.push(this.makeCode('new '));
999 fragments.push.apply(fragments, this.variable.compileToFragments(o, LEVEL_ACCESS));
1000 fragments.push(this.makeCode("("));
1002 fragments.push.apply(fragments, compiledArgs);
1003 fragments.push(this.makeCode(")"));
1007 Call.prototype.compileSplat = function(o, splatArgs) {
1008 var answer, base, fun, idt, name, ref;
1010 return [].concat(this.makeCode("" + (this.superReference(o)) + ".apply(" + (this.superThis(o)) + ", "), splatArgs, this.makeCode(")"));
1013 idt = this.tab + TAB;
1014 return [].concat(this.makeCode("(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.compileToFragments(o, LEVEL_LIST), this.makeCode(", "), splatArgs, this.makeCode(", function(){})"));
1017 base = new Value(this.variable);
1018 if ((name = base.properties.pop()) && base.isComplex()) {
1019 ref = o.scope.freeVariable('ref');
1020 answer = answer.concat(this.makeCode("(" + ref + " = "), base.compileToFragments(o, LEVEL_LIST), this.makeCode(")"), name.compileToFragments(o));
1022 fun = base.compileToFragments(o, LEVEL_ACCESS);
1023 if (SIMPLENUM.test(fragmentsToText(fun))) {
1024 fun = this.wrapInBraces(fun);
1027 ref = fragmentsToText(fun);
1028 fun.push.apply(fun, name.compileToFragments(o));
1032 answer = answer.concat(fun);
1034 return answer = answer.concat(this.makeCode(".apply(" + ref + ", "), splatArgs, this.makeCode(")"));
1041 exports.Extends = Extends = (function(_super) {
1042 __extends(Extends, _super);
1044 function Extends(child, parent) {
1046 this.parent = parent;
1049 Extends.prototype.children = ['child', 'parent'];
1051 Extends.prototype.compileToFragments = function(o) {
1052 return new Call(new Value(new Literal(utility('extends'))), [this.child, this.parent]).compileToFragments(o);
1059 exports.Access = Access = (function(_super) {
1060 __extends(Access, _super);
1062 function Access(name, tag) {
1064 this.name.asKey = true;
1065 this.soak = tag === 'soak';
1068 Access.prototype.children = ['name'];
1070 Access.prototype.compileToFragments = function(o) {
1072 name = this.name.compileToFragments(o);
1073 if (IDENTIFIER.test(fragmentsToText(name))) {
1074 name.unshift(this.makeCode("."));
1076 name.unshift(this.makeCode("["));
1077 name.push(this.makeCode("]"));
1082 Access.prototype.isComplex = NO;
1088 exports.Index = Index = (function(_super) {
1089 __extends(Index, _super);
1091 function Index(index) {
1095 Index.prototype.children = ['index'];
1097 Index.prototype.compileToFragments = function(o) {
1098 return [].concat(this.makeCode("["), this.index.compileToFragments(o, LEVEL_PAREN), this.makeCode("]"));
1101 Index.prototype.isComplex = function() {
1102 return this.index.isComplex();
1109 exports.Range = Range = (function(_super) {
1110 __extends(Range, _super);
1112 Range.prototype.children = ['from', 'to'];
1114 function Range(from, to, tag) {
1117 this.exclusive = tag === 'exclusive';
1118 this.equals = this.exclusive ? '' : '=';
1121 Range.prototype.compileVariables = function(o) {
1122 var step, _ref2, _ref3, _ref4, _ref5;
1126 _ref2 = this.cacheToCodeFragments(this.from.cache(o, LEVEL_LIST)), this.fromC = _ref2[0], this.fromVar = _ref2[1];
1127 _ref3 = this.cacheToCodeFragments(this.to.cache(o, LEVEL_LIST)), this.toC = _ref3[0], this.toVar = _ref3[1];
1128 if (step = del(o, 'step')) {
1129 _ref4 = this.cacheToCodeFragments(step.cache(o, LEVEL_LIST)), this.step = _ref4[0], this.stepVar = _ref4[1];
1131 _ref5 = [this.fromVar.match(NUMBER), this.toVar.match(NUMBER)], this.fromNum = _ref5[0], this.toNum = _ref5[1];
1133 return this.stepNum = this.stepVar.match(NUMBER);
1137 Range.prototype.compileNode = function(o) {
1138 var cond, condPart, from, gt, idx, idxName, known, lt, namedIndex, stepPart, to, varPart, _ref2, _ref3;
1139 if (!this.fromVar) {
1140 this.compileVariables(o);
1143 return this.compileArray(o);
1145 known = this.fromNum && this.toNum;
1146 idx = del(o, 'index');
1147 idxName = del(o, 'name');
1148 namedIndex = idxName && idxName !== idx;
1149 varPart = "" + idx + " = " + this.fromC;
1150 if (this.toC !== this.toVar) {
1151 varPart += ", " + this.toC;
1153 if (this.step !== this.stepVar) {
1154 varPart += ", " + this.step;
1156 _ref2 = ["" + idx + " <" + this.equals, "" + idx + " >" + this.equals], lt = _ref2[0], gt = _ref2[1];
1157 condPart = this.stepNum ? parseNum(this.stepNum[0]) > 0 ? "" + lt + " " + this.toVar : "" + gt + " " + this.toVar : known ? ((_ref3 = [parseNum(this.fromNum[0]), parseNum(this.toNum[0])], from = _ref3[0], to = _ref3[1], _ref3), from <= to ? "" + lt + " " + to : "" + gt + " " + to) : (cond = this.stepVar ? "" + this.stepVar + " > 0" : "" + this.fromVar + " <= " + this.toVar, "" + cond + " ? " + lt + " " + this.toVar + " : " + gt + " " + this.toVar);
1158 stepPart = this.stepVar ? "" + idx + " += " + this.stepVar : known ? namedIndex ? from <= to ? "++" + idx : "--" + idx : from <= to ? "" + idx + "++" : "" + idx + "--" : namedIndex ? "" + cond + " ? ++" + idx + " : --" + idx : "" + cond + " ? " + idx + "++ : " + idx + "--";
1160 varPart = "" + idxName + " = " + varPart;
1163 stepPart = "" + idxName + " = " + stepPart;
1165 return [this.makeCode("" + varPart + "; " + condPart + "; " + stepPart)];
1168 Range.prototype.compileArray = function(o) {
1169 var args, body, cond, hasArgs, i, idt, post, pre, range, result, vars, _i, _ref2, _ref3, _results;
1170 if (this.fromNum && this.toNum && Math.abs(this.fromNum - this.toNum) <= 20) {
1171 range = (function() {
1173 for (var _i = _ref2 = +this.fromNum, _ref3 = +this.toNum; _ref2 <= _ref3 ? _i <= _ref3 : _i >= _ref3; _ref2 <= _ref3 ? _i++ : _i--){ _results.push(_i); }
1176 if (this.exclusive) {
1179 return [this.makeCode("[" + (range.join(', ')) + "]")];
1181 idt = this.tab + TAB;
1182 i = o.scope.freeVariable('i');
1183 result = o.scope.freeVariable('results');
1184 pre = "\n" + idt + result + " = [];";
1185 if (this.fromNum && this.toNum) {
1187 body = fragmentsToText(this.compileNode(o));
1189 vars = ("" + i + " = " + this.fromC) + (this.toC !== this.toVar ? ", " + this.toC : '');
1190 cond = "" + this.fromVar + " <= " + this.toVar;
1191 body = "var " + vars + "; " + cond + " ? " + i + " <" + this.equals + " " + this.toVar + " : " + i + " >" + this.equals + " " + this.toVar + "; " + cond + " ? " + i + "++ : " + i + "--";
1193 post = "{ " + result + ".push(" + i + "); }\n" + idt + "return " + result + ";\n" + o.indent;
1194 hasArgs = function(node) {
1195 return node != null ? node.contains(isLiteralArguments) : void 0;
1197 if (hasArgs(this.from) || hasArgs(this.to)) {
1198 args = ', arguments';
1200 return [this.makeCode("(function() {" + pre + "\n" + idt + "for (" + body + ")" + post + "}).apply(this" + (args != null ? args : '') + ")")];
1207 exports.Slice = Slice = (function(_super) {
1208 __extends(Slice, _super);
1210 Slice.prototype.children = ['range'];
1212 function Slice(range) {
1214 Slice.__super__.constructor.call(this);
1217 Slice.prototype.compileNode = function(o) {
1218 var compiled, compiledText, from, fromCompiled, to, toStr, _ref2;
1219 _ref2 = this.range, to = _ref2.to, from = _ref2.from;
1220 fromCompiled = from && from.compileToFragments(o, LEVEL_PAREN) || [this.makeCode('0')];
1222 compiled = to.compileToFragments(o, LEVEL_PAREN);
1223 compiledText = fragmentsToText(compiled);
1224 if (!(!this.range.exclusive && +compiledText === -1)) {
1225 toStr = ', ' + (this.range.exclusive ? compiledText : SIMPLENUM.test(compiledText) ? "" + (+compiledText + 1) : (compiled = to.compileToFragments(o, LEVEL_ACCESS), "+" + (fragmentsToText(compiled)) + " + 1 || 9e9"));
1228 return [this.makeCode(".slice(" + (fragmentsToText(fromCompiled)) + (toStr || '') + ")")];
1235 exports.Obj = Obj = (function(_super) {
1236 __extends(Obj, _super);
1238 function Obj(props, generated) {
1239 this.generated = generated != null ? generated : false;
1240 this.objects = this.properties = props || [];
1243 Obj.prototype.children = ['properties'];
1245 Obj.prototype.compileNode = function(o) {
1246 var answer, i, idt, indent, join, lastNoncom, node, prop, props, _i, _j, _len, _len1;
1247 props = this.properties;
1248 if (!props.length) {
1249 return [this.makeCode(this.front ? '({})' : '{}')];
1251 if (this.generated) {
1252 for (_i = 0, _len = props.length; _i < _len; _i++) {
1254 if (node instanceof Value) {
1255 node.error('cannot have an implicit value in an implicit object');
1259 idt = o.indent += TAB;
1260 lastNoncom = this.lastNonComment(this.properties);
1262 for (i = _j = 0, _len1 = props.length; _j < _len1; i = ++_j) {
1264 join = i === props.length - 1 ? '' : prop === lastNoncom || prop instanceof Comment ? '\n' : ',\n';
1265 indent = prop instanceof Comment ? '' : idt;
1266 if (prop instanceof Assign && prop.variable instanceof Value && prop.variable.hasProperties()) {
1267 prop.variable.error('Invalid object key');
1269 if (prop instanceof Value && prop["this"]) {
1270 prop = new Assign(prop.properties[0].name, prop, 'object');
1272 if (!(prop instanceof Comment)) {
1273 if (!(prop instanceof Assign)) {
1274 prop = new Assign(prop, prop, 'object');
1276 (prop.variable.base || prop.variable).asKey = true;
1279 answer.push(this.makeCode(indent));
1281 answer.push.apply(answer, prop.compileToFragments(o, LEVEL_TOP));
1283 answer.push(this.makeCode(join));
1286 answer.unshift(this.makeCode("{" + (props.length && '\n')));
1287 answer.push(this.makeCode("" + (props.length && '\n' + this.tab) + "}"));
1289 return this.wrapInBraces(answer);
1295 Obj.prototype.assigns = function(name) {
1296 var prop, _i, _len, _ref2;
1297 _ref2 = this.properties;
1298 for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
1300 if (prop.assigns(name)) {
1311 exports.Arr = Arr = (function(_super) {
1312 __extends(Arr, _super);
1314 function Arr(objs) {
1315 this.objects = objs || [];
1318 Arr.prototype.children = ['objects'];
1320 Arr.prototype.compileNode = function(o) {
1321 var answer, compiledObjs, fragments, index, obj, _i, _len;
1322 if (!this.objects.length) {
1323 return [this.makeCode('[]')];
1326 answer = Splat.compileSplattedArray(o, this.objects);
1327 if (answer.length) {
1331 compiledObjs = (function() {
1332 var _i, _len, _ref2, _results;
1333 _ref2 = this.objects;
1335 for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
1337 _results.push(obj.compileToFragments(o, LEVEL_LIST));
1341 for (index = _i = 0, _len = compiledObjs.length; _i < _len; index = ++_i) {
1342 fragments = compiledObjs[index];
1344 answer.push(this.makeCode(", "));
1346 answer.push.apply(answer, fragments);
1348 if (fragmentsToText(answer).indexOf('\n') >= 0) {
1349 answer.unshift(this.makeCode("[\n" + o.indent));
1350 answer.push(this.makeCode("\n" + this.tab + "]"));
1352 answer.unshift(this.makeCode("["));
1353 answer.push(this.makeCode("]"));
1358 Arr.prototype.assigns = function(name) {
1359 var obj, _i, _len, _ref2;
1360 _ref2 = this.objects;
1361 for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
1363 if (obj.assigns(name)) {
1374 exports.Class = Class = (function(_super) {
1375 __extends(Class, _super);
1377 function Class(variable, parent, body) {
1378 this.variable = variable;
1379 this.parent = parent;
1380 this.body = body != null ? body : new Block;
1381 this.boundFuncs = [];
1382 this.body.classBody = true;
1385 Class.prototype.children = ['variable', 'parent', 'body'];
1387 Class.prototype.determineName = function() {
1389 if (!this.variable) {
1392 decl = (tail = last(this.variable.properties)) ? tail instanceof Access && tail.name.value : this.variable.base.value;
1393 if (__indexOf.call(STRICT_PROSCRIBED, decl) >= 0) {
1394 this.variable.error("class variable name may not be " + decl);
1396 return decl && (decl = IDENTIFIER.test(decl) && decl);
1399 Class.prototype.setContext = function(name) {
1400 return this.body.traverseChildren(false, function(node) {
1401 if (node.classBody) {
1404 if (node instanceof Literal && node.value === 'this') {
1405 return node.value = name;
1406 } else if (node instanceof Code) {
1409 return node.context = name;
1415 Class.prototype.addBoundFunctions = function(o) {
1416 var bvar, lhs, _i, _len, _ref2;
1417 _ref2 = this.boundFuncs;
1418 for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
1420 lhs = (new Value(new Literal("this"), [new Access(bvar)])).compile(o);
1421 this.ctor.body.unshift(new Literal("" + lhs + " = " + (utility('bind')) + "(" + lhs + ", this)"));
1425 Class.prototype.addProperties = function(node, name, o) {
1426 var assign, base, exprs, func, props;
1427 props = node.base.properties.slice(0);
1428 exprs = (function() {
1431 while (assign = props.shift()) {
1432 if (assign instanceof Assign) {
1433 base = assign.variable.base;
1434 delete assign.context;
1435 func = assign.value;
1436 if (base.value === 'constructor') {
1438 assign.error('cannot define more than one constructor in a class');
1441 assign.error('cannot define a constructor as a bound function');
1443 if (func instanceof Code) {
1444 assign = this.ctor = func;
1446 this.externalCtor = o.classScope.freeVariable('class');
1447 assign = new Assign(new Literal(this.externalCtor), func);
1450 if (assign.variable["this"]) {
1451 func["static"] = true;
1453 assign.variable = new Value(new Literal(name), [new Access(new Literal('prototype')), new Access(base)]);
1454 if (func instanceof Code && func.bound) {
1455 this.boundFuncs.push(base);
1461 _results.push(assign);
1465 return compact(exprs);
1468 Class.prototype.walkBody = function(name, o) {
1469 return this.traverseChildren(false, (function(_this) {
1470 return function(child) {
1471 var cont, exps, i, node, _i, _len, _ref2;
1473 if (child instanceof Class) {
1476 if (child instanceof Block) {
1477 _ref2 = exps = child.expressions;
1478 for (i = _i = 0, _len = _ref2.length; _i < _len; i = ++_i) {
1480 if (node instanceof Assign && node.variable.looksStatic(name)) {
1481 node.value["static"] = true;
1482 } else if (node instanceof Value && node.isObject(true)) {
1484 exps[i] = _this.addProperties(node, name, o);
1487 child.expressions = exps = flatten(exps);
1489 return cont && !(child instanceof Class);
1494 Class.prototype.hoistDirectivePrologue = function() {
1495 var expressions, index, node;
1497 expressions = this.body.expressions;
1498 while ((node = expressions[index]) && node instanceof Comment || node instanceof Value && node.isString()) {
1501 return this.directives = expressions.splice(0, index);
1504 Class.prototype.ensureConstructor = function(name) {
1506 this.ctor = new Code;
1507 if (this.externalCtor) {
1508 this.ctor.body.push(new Literal("" + this.externalCtor + ".apply(this, arguments)"));
1509 } else if (this.parent) {
1510 this.ctor.body.push(new Literal("" + name + ".__super__.constructor.apply(this, arguments)"));
1512 this.ctor.body.makeReturn();
1513 this.body.expressions.unshift(this.ctor);
1515 this.ctor.ctor = this.ctor.name = name;
1516 this.ctor.klass = null;
1517 return this.ctor.noReturn = true;
1520 Class.prototype.compileNode = function(o) {
1521 var args, argumentsNode, func, jumpNode, klass, lname, name, superClass, _ref2;
1522 if (jumpNode = this.body.jumps()) {
1523 jumpNode.error('Class bodies cannot contain pure statements');
1525 if (argumentsNode = this.body.contains(isLiteralArguments)) {
1526 argumentsNode.error("Class bodies shouldn't reference arguments");
1528 name = this.determineName() || '_Class';
1529 if (name.reserved) {
1532 lname = new Literal(name);
1533 func = new Code([], Block.wrap([this.body]));
1535 o.classScope = func.makeScope(o.scope);
1536 this.hoistDirectivePrologue();
1537 this.setContext(name);
1538 this.walkBody(name, o);
1539 this.ensureConstructor(name);
1540 this.addBoundFunctions(o);
1541 this.body.spaced = true;
1542 this.body.expressions.push(lname);
1544 superClass = new Literal(o.classScope.freeVariable('super', false));
1545 this.body.expressions.unshift(new Extends(lname, superClass));
1546 func.params.push(new Param(superClass));
1547 args.push(this.parent);
1549 (_ref2 = this.body.expressions).unshift.apply(_ref2, this.directives);
1550 klass = new Parens(new Call(func, args));
1551 if (this.variable) {
1552 klass = new Assign(this.variable, klass);
1554 return klass.compileToFragments(o);
1561 exports.Assign = Assign = (function(_super) {
1562 __extends(Assign, _super);
1564 function Assign(variable, value, context, options) {
1565 var forbidden, name, _ref2;
1566 this.variable = variable;
1568 this.context = context;
1569 this.param = options && options.param;
1570 this.subpattern = options && options.subpattern;
1571 forbidden = (_ref2 = (name = this.variable.unwrapAll().value), __indexOf.call(STRICT_PROSCRIBED, _ref2) >= 0);
1572 if (forbidden && this.context !== 'object') {
1573 this.variable.error("variable name may not be \"" + name + "\"");
1577 Assign.prototype.children = ['variable', 'value'];
1579 Assign.prototype.isStatement = function(o) {
1580 return (o != null ? o.level : void 0) === LEVEL_TOP && (this.context != null) && __indexOf.call(this.context, "?") >= 0;
1583 Assign.prototype.assigns = function(name) {
1584 return this[this.context === 'object' ? 'value' : 'variable'].assigns(name);
1587 Assign.prototype.unfoldSoak = function(o) {
1588 return unfoldSoak(o, this, 'variable');
1591 Assign.prototype.compileNode = function(o) {
1592 var answer, compiledName, isValue, match, name, val, varBase, _ref2, _ref3, _ref4, _ref5;
1593 if (isValue = this.variable instanceof Value) {
1594 if (this.variable.isArray() || this.variable.isObject()) {
1595 return this.compilePatternMatch(o);
1597 if (this.variable.isSplice()) {
1598 return this.compileSplice(o);
1600 if ((_ref2 = this.context) === '||=' || _ref2 === '&&=' || _ref2 === '?=') {
1601 return this.compileConditional(o);
1603 if ((_ref3 = this.context) === '**=' || _ref3 === '//=' || _ref3 === '%%=') {
1604 return this.compileSpecialMath(o);
1607 compiledName = this.variable.compileToFragments(o, LEVEL_LIST);
1608 name = fragmentsToText(compiledName);
1609 if (!this.context) {
1610 varBase = this.variable.unwrapAll();
1611 if (!varBase.isAssignable()) {
1612 this.variable.error("\"" + (this.variable.compile(o)) + "\" cannot be assigned");
1614 if (!(typeof varBase.hasProperties === "function" ? varBase.hasProperties() : void 0)) {
1616 o.scope.add(name, 'var');
1622 if (this.value instanceof Code && (match = METHOD_DEF.exec(name))) {
1624 this.value.klass = match[1];
1626 this.value.name = (_ref4 = (_ref5 = match[3]) != null ? _ref5 : match[4]) != null ? _ref4 : match[5];
1628 val = this.value.compileToFragments(o, LEVEL_LIST);
1629 if (this.context === 'object') {
1630 return compiledName.concat(this.makeCode(": "), val);
1632 answer = compiledName.concat(this.makeCode(" " + (this.context || '=') + " "), val);
1633 if (o.level <= LEVEL_LIST) {
1636 return this.wrapInBraces(answer);
1640 Assign.prototype.compilePatternMatch = function(o) {
1641 var acc, assigns, code, expandedIdx, fragments, i, idx, isObject, ivar, name, obj, objects, olen, ref, rest, top, val, value, vvar, vvarText, _i, _len, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7;
1642 top = o.level === LEVEL_TOP;
1644 objects = this.variable.base.objects;
1645 if (!(olen = objects.length)) {
1646 code = value.compileToFragments(o);
1647 if (o.level >= LEVEL_OP) {
1648 return this.wrapInBraces(code);
1653 isObject = this.variable.isObject();
1654 if (top && olen === 1 && !((obj = objects[0]) instanceof Splat)) {
1655 if (obj instanceof Assign) {
1656 _ref2 = obj, (_ref3 = _ref2.variable, idx = _ref3.base), obj = _ref2.value;
1658 idx = isObject ? obj["this"] ? obj.properties[0].name : obj : new Literal(0);
1660 acc = IDENTIFIER.test(idx.unwrap().value || 0);
1661 value = new Value(value);
1662 value.properties.push(new (acc ? Access : Index)(idx));
1663 if (_ref4 = obj.unwrap().value, __indexOf.call(RESERVED, _ref4) >= 0) {
1664 obj.error("assignment to a reserved word: " + (obj.compile(o)));
1666 return new Assign(obj, value, null, {
1668 }).compileToFragments(o, LEVEL_TOP);
1670 vvar = value.compileToFragments(o, LEVEL_LIST);
1671 vvarText = fragmentsToText(vvar);
1673 expandedIdx = false;
1674 if (!IDENTIFIER.test(vvarText) || this.variable.assigns(vvarText)) {
1675 assigns.push([this.makeCode("" + (ref = o.scope.freeVariable('ref')) + " = ")].concat(__slice.call(vvar)));
1676 vvar = [this.makeCode(ref)];
1679 for (i = _i = 0, _len = objects.length; _i < _len; i = ++_i) {
1683 if (obj instanceof Assign) {
1684 _ref5 = obj, (_ref6 = _ref5.variable, idx = _ref6.base), obj = _ref5.value;
1686 if (obj.base instanceof Parens) {
1687 _ref7 = new Value(obj.unwrapAll()).cacheReference(o), obj = _ref7[0], idx = _ref7[1];
1689 idx = obj["this"] ? obj.properties[0].name : obj;
1693 if (!expandedIdx && obj instanceof Splat) {
1694 name = obj.name.unwrap().value;
1696 val = "" + olen + " <= " + vvarText + ".length ? " + (utility('slice')) + ".call(" + vvarText + ", " + i;
1697 if (rest = olen - i - 1) {
1698 ivar = o.scope.freeVariable('i');
1699 val += ", " + ivar + " = " + vvarText + ".length - " + rest + ") : (" + ivar + " = " + i + ", [])";
1703 val = new Literal(val);
1704 expandedIdx = "" + ivar + "++";
1705 } else if (!expandedIdx && obj instanceof Expansion) {
1706 if (rest = olen - i - 1) {
1708 expandedIdx = "" + vvarText + ".length - 1";
1710 ivar = o.scope.freeVariable('i');
1711 val = new Literal("" + ivar + " = " + vvarText + ".length - " + rest);
1712 expandedIdx = "" + ivar + "++";
1713 assigns.push(val.compileToFragments(o, LEVEL_LIST));
1718 name = obj.unwrap().value;
1719 if (obj instanceof Splat || obj instanceof Expansion) {
1720 obj.error("multiple splats/expansions are disallowed in an assignment");
1722 if (typeof idx === 'number') {
1723 idx = new Literal(expandedIdx || idx);
1726 acc = isObject && IDENTIFIER.test(idx.unwrap().value || 0);
1728 val = new Value(new Literal(vvarText), [new (acc ? Access : Index)(idx)]);
1730 if ((name != null) && __indexOf.call(RESERVED, name) >= 0) {
1731 obj.error("assignment to a reserved word: " + (obj.compile(o)));
1733 assigns.push(new Assign(obj, val, null, {
1736 }).compileToFragments(o, LEVEL_LIST));
1738 if (!(top || this.subpattern)) {
1741 fragments = this.joinFragmentArrays(assigns, ', ');
1742 if (o.level < LEVEL_LIST) {
1745 return this.wrapInBraces(fragments);
1749 Assign.prototype.compileConditional = function(o) {
1750 var fragments, left, right, _ref2;
1751 _ref2 = this.variable.cacheReference(o), left = _ref2[0], right = _ref2[1];
1752 if (!left.properties.length && left.base instanceof Literal && left.base.value !== "this" && !o.scope.check(left.base.value)) {
1753 this.variable.error("the variable \"" + left.base.value + "\" can't be assigned with " + this.context + " because it has not been declared before");
1755 if (__indexOf.call(this.context, "?") >= 0) {
1756 o.isExistentialEquals = true;
1757 return new If(new Existence(left), right, {
1759 }).addElse(new Assign(right, this.value, '=')).compileToFragments(o);
1761 fragments = new Op(this.context.slice(0, -1), left, new Assign(right, this.value, '=')).compileToFragments(o);
1762 if (o.level <= LEVEL_LIST) {
1765 return this.wrapInBraces(fragments);
1770 Assign.prototype.compileSpecialMath = function(o) {
1771 var left, right, _ref2;
1772 _ref2 = this.variable.cacheReference(o), left = _ref2[0], right = _ref2[1];
1773 return new Assign(left, new Op(this.context.slice(0, -1), right, this.value)).compileToFragments(o);
1776 Assign.prototype.compileSplice = function(o) {
1777 var answer, exclusive, from, fromDecl, fromRef, name, to, valDef, valRef, _ref2, _ref3, _ref4;
1778 _ref2 = this.variable.properties.pop().range, from = _ref2.from, to = _ref2.to, exclusive = _ref2.exclusive;
1779 name = this.variable.compile(o);
1781 _ref3 = this.cacheToCodeFragments(from.cache(o, LEVEL_OP)), fromDecl = _ref3[0], fromRef = _ref3[1];
1783 fromDecl = fromRef = '0';
1786 if (from instanceof Value && from.isSimpleNumber() && to instanceof Value && to.isSimpleNumber()) {
1787 to = to.compile(o) - fromRef;
1792 to = to.compile(o, LEVEL_ACCESS) + ' - ' + fromRef;
1800 _ref4 = this.value.cache(o, LEVEL_LIST), valDef = _ref4[0], valRef = _ref4[1];
1801 answer = [].concat(this.makeCode("[].splice.apply(" + name + ", [" + fromDecl + ", " + to + "].concat("), valDef, this.makeCode(")), "), valRef);
1802 if (o.level > LEVEL_TOP) {
1803 return this.wrapInBraces(answer);
1813 exports.Code = Code = (function(_super) {
1814 __extends(Code, _super);
1816 function Code(params, body, tag) {
1817 this.params = params || [];
1818 this.body = body || new Block;
1819 this.bound = tag === 'boundfunc';
1822 Code.prototype.children = ['params', 'body'];
1824 Code.prototype.isStatement = function() {
1828 Code.prototype.jumps = NO;
1830 Code.prototype.makeScope = function(parentScope) {
1831 return new Scope(parentScope, this.body, this);
1834 Code.prototype.compileNode = function(o) {
1835 var answer, boundfunc, code, exprs, i, lit, p, param, params, ref, splats, uniqs, val, wasEmpty, wrapper, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _len5, _m, _n, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7;
1836 if (this.bound && ((_ref2 = o.scope.method) != null ? _ref2.bound : void 0)) {
1837 this.context = o.scope.method.context;
1839 if (this.bound && !this.context) {
1840 this.context = '_this';
1841 wrapper = new Code([new Param(new Literal(this.context))], new Block([this]));
1842 boundfunc = new Call(wrapper, [new Literal('this')]);
1843 boundfunc.updateLocationDataIfMissing(this.locationData);
1844 return boundfunc.compileNode(o);
1846 o.scope = del(o, 'classScope') || this.makeScope(o.scope);
1847 o.scope.shared = del(o, 'sharedScope');
1850 delete o.isExistentialEquals;
1853 _ref3 = this.params;
1854 for (_i = 0, _len = _ref3.length; _i < _len; _i++) {
1856 if (!(param instanceof Expansion)) {
1857 o.scope.parameter(param.asReference(o));
1860 _ref4 = this.params;
1861 for (_j = 0, _len1 = _ref4.length; _j < _len1; _j++) {
1863 if (!(param.splat || param instanceof Expansion)) {
1866 _ref5 = this.params;
1867 for (_k = 0, _len2 = _ref5.length; _k < _len2; _k++) {
1869 if (!(!(param instanceof Expansion))) {
1873 p = p.properties[0].name;
1876 o.scope.add(p.value, 'var', true);
1879 splats = new Assign(new Value(new Arr((function() {
1880 var _l, _len3, _ref6, _results;
1881 _ref6 = this.params;
1883 for (_l = 0, _len3 = _ref6.length; _l < _len3; _l++) {
1885 _results.push(p.asReference(o));
1888 }).call(this))), new Value(new Literal('arguments')));
1891 _ref6 = this.params;
1892 for (_l = 0, _len3 = _ref6.length; _l < _len3; _l++) {
1894 if (param.isComplex()) {
1895 val = ref = param.asReference(o);
1897 val = new Op('?', ref, param.value);
1899 exprs.push(new Assign(new Value(param.name), val, '=', {
1905 lit = new Literal(ref.name.value + ' == null');
1906 val = new Assign(new Value(param.name), param.value, '=');
1907 exprs.push(new If(lit, val));
1914 wasEmpty = this.body.isEmpty();
1916 exprs.unshift(splats);
1919 (_ref7 = this.body.expressions).unshift.apply(_ref7, exprs);
1921 for (i = _m = 0, _len4 = params.length; _m < _len4; i = ++_m) {
1923 params[i] = p.compileToFragments(o);
1924 o.scope.parameter(fragmentsToText(params[i]));
1927 this.eachParamName(function(name, node) {
1928 if (__indexOf.call(uniqs, name) >= 0) {
1929 node.error("multiple parameters named '" + name + "'");
1931 return uniqs.push(name);
1933 if (!(wasEmpty || this.noReturn)) {
1934 this.body.makeReturn();
1938 code += ' ' + this.name;
1941 answer = [this.makeCode(code)];
1942 for (i = _n = 0, _len5 = params.length; _n < _len5; i = ++_n) {
1945 answer.push(this.makeCode(", "));
1947 answer.push.apply(answer, p);
1949 answer.push(this.makeCode(') {'));
1950 if (!this.body.isEmpty()) {
1951 answer = answer.concat(this.makeCode("\n"), this.body.compileWithDeclarations(o), this.makeCode("\n" + this.tab));
1953 answer.push(this.makeCode('}'));
1955 return [this.makeCode(this.tab)].concat(__slice.call(answer));
1957 if (this.front || (o.level >= LEVEL_ACCESS)) {
1958 return this.wrapInBraces(answer);
1964 Code.prototype.eachParamName = function(iterator) {
1965 var param, _i, _len, _ref2, _results;
1966 _ref2 = this.params;
1968 for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
1970 _results.push(param.eachName(iterator));
1975 Code.prototype.traverseChildren = function(crossScope, func) {
1977 return Code.__super__.traverseChildren.call(this, crossScope, func);
1985 exports.Param = Param = (function(_super) {
1986 __extends(Param, _super);
1988 function Param(name, value, splat) {
1993 if (_ref2 = (name = this.name.unwrapAll().value), __indexOf.call(STRICT_PROSCRIBED, _ref2) >= 0) {
1994 this.name.error("parameter name \"" + name + "\" is not allowed");
1998 Param.prototype.children = ['name', 'value'];
2000 Param.prototype.compileToFragments = function(o) {
2001 return this.name.compileToFragments(o, LEVEL_LIST);
2004 Param.prototype.asReference = function(o) {
2006 if (this.reference) {
2007 return this.reference;
2011 node = node.properties[0].name;
2012 if (node.value.reserved) {
2013 node = new Literal(o.scope.freeVariable(node.value));
2015 } else if (node.isComplex()) {
2016 node = new Literal(o.scope.freeVariable('arg'));
2018 node = new Value(node);
2020 node = new Splat(node);
2022 node.updateLocationDataIfMissing(this.locationData);
2023 return this.reference = node;
2026 Param.prototype.isComplex = function() {
2027 return this.name.isComplex();
2030 Param.prototype.eachName = function(iterator, name) {
2031 var atParam, node, obj, _i, _len, _ref2;
2035 atParam = function(obj) {
2037 node = obj.properties[0].name;
2038 if (!node.value.reserved) {
2039 return iterator(node.value, node);
2042 if (name instanceof Literal) {
2043 return iterator(name.value, name);
2045 if (name instanceof Value) {
2046 return atParam(name);
2048 _ref2 = name.objects;
2049 for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
2051 if (obj instanceof Assign) {
2052 this.eachName(iterator, obj.value.unwrap());
2053 } else if (obj instanceof Splat) {
2054 node = obj.name.unwrap();
2055 iterator(node.value, node);
2056 } else if (obj instanceof Value) {
2057 if (obj.isArray() || obj.isObject()) {
2058 this.eachName(iterator, obj.base);
2059 } else if (obj["this"]) {
2062 iterator(obj.base.value, obj.base);
2064 } else if (!(obj instanceof Expansion)) {
2065 obj.error("illegal parameter " + (obj.compile()));
2074 exports.Splat = Splat = (function(_super) {
2075 __extends(Splat, _super);
2077 Splat.prototype.children = ['name'];
2079 Splat.prototype.isAssignable = YES;
2081 function Splat(name) {
2082 this.name = name.compile ? name : new Literal(name);
2085 Splat.prototype.assigns = function(name) {
2086 return this.name.assigns(name);
2089 Splat.prototype.compileToFragments = function(o) {
2090 return this.name.compileToFragments(o);
2093 Splat.prototype.unwrap = function() {
2097 Splat.compileSplattedArray = function(o, list, apply) {
2098 var args, base, compiledNode, concatPart, fragments, i, index, node, _i, _len;
2100 while ((node = list[++index]) && !(node instanceof Splat)) {
2103 if (index >= list.length) {
2106 if (list.length === 1) {
2108 fragments = node.compileToFragments(o, LEVEL_LIST);
2112 return [].concat(node.makeCode("" + (utility('slice')) + ".call("), fragments, node.makeCode(")"));
2114 args = list.slice(index);
2115 for (i = _i = 0, _len = args.length; _i < _len; i = ++_i) {
2117 compiledNode = node.compileToFragments(o, LEVEL_LIST);
2118 args[i] = node instanceof Splat ? [].concat(node.makeCode("" + (utility('slice')) + ".call("), compiledNode, node.makeCode(")")) : [].concat(node.makeCode("["), compiledNode, node.makeCode("]"));
2122 concatPart = node.joinFragmentArrays(args.slice(1), ', ');
2123 return args[0].concat(node.makeCode(".concat("), concatPart, node.makeCode(")"));
2125 base = (function() {
2126 var _j, _len1, _ref2, _results;
2127 _ref2 = list.slice(0, index);
2129 for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {
2131 _results.push(node.compileToFragments(o, LEVEL_LIST));
2135 base = list[0].joinFragmentArrays(base, ', ');
2136 concatPart = list[index].joinFragmentArrays(args, ', ');
2137 return [].concat(list[0].makeCode("["), base, list[index].makeCode("].concat("), concatPart, (last(list)).makeCode(")"));
2144 exports.Expansion = Expansion = (function(_super) {
2145 __extends(Expansion, _super);
2147 function Expansion() {
2148 return Expansion.__super__.constructor.apply(this, arguments);
2151 Expansion.prototype.isComplex = NO;
2153 Expansion.prototype.compileNode = function(o) {
2154 return this.error('Expansion must be used inside a destructuring assignment or parameter list');
2157 Expansion.prototype.asReference = function(o) {
2161 Expansion.prototype.eachName = function(iterator) {};
2167 exports.While = While = (function(_super) {
2168 __extends(While, _super);
2170 function While(condition, options) {
2171 this.condition = (options != null ? options.invert : void 0) ? condition.invert() : condition;
2172 this.guard = options != null ? options.guard : void 0;
2175 While.prototype.children = ['condition', 'guard', 'body'];
2177 While.prototype.isStatement = YES;
2179 While.prototype.makeReturn = function(res) {
2181 return While.__super__.makeReturn.apply(this, arguments);
2183 this.returns = !this.jumps({
2190 While.prototype.addBody = function(body) {
2195 While.prototype.jumps = function() {
2196 var expressions, jumpNode, node, _i, _len;
2197 expressions = this.body.expressions;
2198 if (!expressions.length) {
2201 for (_i = 0, _len = expressions.length; _i < _len; _i++) {
2202 node = expressions[_i];
2203 if (jumpNode = node.jumps({
2212 While.prototype.compileNode = function(o) {
2213 var answer, body, rvar, set;
2217 if (body.isEmpty()) {
2218 body = this.makeCode('');
2221 body.makeReturn(rvar = o.scope.freeVariable('results'));
2222 set = "" + this.tab + rvar + " = [];\n";
2225 if (body.expressions.length > 1) {
2226 body.expressions.unshift(new If((new Parens(this.guard)).invert(), new Literal("continue")));
2229 body = Block.wrap([new If(this.guard, body)]);
2233 body = [].concat(this.makeCode("\n"), body.compileToFragments(o, LEVEL_TOP), this.makeCode("\n" + this.tab));
2235 answer = [].concat(this.makeCode(set + this.tab + "while ("), this.condition.compileToFragments(o, LEVEL_PAREN), this.makeCode(") {"), body, this.makeCode("}"));
2237 answer.push(this.makeCode("\n" + this.tab + "return " + rvar + ";"));
2246 exports.Op = Op = (function(_super) {
2247 var CONVERSIONS, INVERSIONS;
2249 __extends(Op, _super);
2251 function Op(op, first, second, flip) {
2253 return new In(first, second);
2256 return this.generateDo(first);
2259 if (first instanceof Call && !first["do"] && !first.isNew) {
2260 return first.newInstance();
2262 if (first instanceof Code && first.bound || first["do"]) {
2263 first = new Parens(first);
2266 this.operator = CONVERSIONS[op] || op;
2268 this.second = second;
2284 Op.prototype.children = ['first', 'second'];
2286 Op.prototype.isSimpleNumber = NO;
2288 Op.prototype.isUnary = function() {
2289 return !this.second;
2292 Op.prototype.isComplex = function() {
2294 return !(this.isUnary() && ((_ref2 = this.operator) === '+' || _ref2 === '-')) || this.first.isComplex();
2297 Op.prototype.isChainable = function() {
2299 return (_ref2 = this.operator) === '<' || _ref2 === '>' || _ref2 === '>=' || _ref2 === '<=' || _ref2 === '===' || _ref2 === '!==';
2302 Op.prototype.invert = function() {
2303 var allInvertable, curr, fst, op, _ref2;
2304 if (this.isChainable() && this.first.isChainable()) {
2305 allInvertable = true;
2307 while (curr && curr.operator) {
2308 allInvertable && (allInvertable = curr.operator in INVERSIONS);
2311 if (!allInvertable) {
2312 return new Parens(this).invert();
2315 while (curr && curr.operator) {
2316 curr.invert = !curr.invert;
2317 curr.operator = INVERSIONS[curr.operator];
2321 } else if (op = INVERSIONS[this.operator]) {
2323 if (this.first.unwrap() instanceof Op) {
2324 this.first.invert();
2327 } else if (this.second) {
2328 return new Parens(this).invert();
2329 } else if (this.operator === '!' && (fst = this.first.unwrap()) instanceof Op && ((_ref2 = fst.operator) === '!' || _ref2 === 'in' || _ref2 === 'instanceof')) {
2332 return new Op('!', this);
2336 Op.prototype.unfoldSoak = function(o) {
2338 return ((_ref2 = this.operator) === '++' || _ref2 === '--' || _ref2 === 'delete') && unfoldSoak(o, this, 'first');
2341 Op.prototype.generateDo = function(exp) {
2342 var call, func, param, passedParams, ref, _i, _len, _ref2;
2344 func = exp instanceof Assign && (ref = exp.value.unwrap()) instanceof Code ? ref : exp;
2345 _ref2 = func.params || [];
2346 for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
2349 passedParams.push(param.value);
2352 passedParams.push(param);
2355 call = new Call(exp, passedParams);
2360 Op.prototype.compileNode = function(o) {
2361 var answer, isChain, lhs, rhs, _ref2, _ref3;
2362 isChain = this.isChainable() && this.first.isChainable();
2364 this.first.front = this.front;
2366 if (this.operator === 'delete' && o.scope.check(this.first.unwrapAll().value)) {
2367 this.error('delete operand may not be argument or var');
2369 if (((_ref2 = this.operator) === '--' || _ref2 === '++') && (_ref3 = this.first.unwrapAll().value, __indexOf.call(STRICT_PROSCRIBED, _ref3) >= 0)) {
2370 this.error("cannot increment/decrement \"" + (this.first.unwrapAll().value) + "\"");
2372 if (this.isUnary()) {
2373 return this.compileUnary(o);
2376 return this.compileChain(o);
2378 switch (this.operator) {
2380 return this.compileExistence(o);
2382 return this.compilePower(o);
2384 return this.compileFloorDivision(o);
2386 return this.compileModulo(o);
2388 lhs = this.first.compileToFragments(o, LEVEL_OP);
2389 rhs = this.second.compileToFragments(o, LEVEL_OP);
2390 answer = [].concat(lhs, this.makeCode(" " + this.operator + " "), rhs);
2391 if (o.level <= LEVEL_OP) {
2394 return this.wrapInBraces(answer);
2399 Op.prototype.compileChain = function(o) {
2400 var fragments, fst, shared, _ref2;
2401 _ref2 = this.first.second.cache(o), this.first.second = _ref2[0], shared = _ref2[1];
2402 fst = this.first.compileToFragments(o, LEVEL_OP);
2403 fragments = fst.concat(this.makeCode(" " + (this.invert ? '&&' : '||') + " "), shared.compileToFragments(o), this.makeCode(" " + this.operator + " "), this.second.compileToFragments(o, LEVEL_OP));
2404 return this.wrapInBraces(fragments);
2407 Op.prototype.compileExistence = function(o) {
2409 if (this.first.isComplex()) {
2410 ref = new Literal(o.scope.freeVariable('ref'));
2411 fst = new Parens(new Assign(ref, this.first));
2416 return new If(new Existence(fst), ref, {
2418 }).addElse(this.second).compileToFragments(o);
2421 Op.prototype.compileUnary = function(o) {
2422 var op, parts, plusMinus;
2425 parts.push([this.makeCode(op)]);
2426 if (op === '!' && this.first instanceof Existence) {
2427 this.first.negated = !this.first.negated;
2428 return this.first.compileToFragments(o);
2430 if (o.level >= LEVEL_ACCESS) {
2431 return (new Parens(this)).compileToFragments(o);
2433 plusMinus = op === '+' || op === '-';
2434 if ((op === 'new' || op === 'typeof' || op === 'delete') || plusMinus && this.first instanceof Op && this.first.operator === op) {
2435 parts.push([this.makeCode(' ')]);
2437 if ((plusMinus && this.first instanceof Op) || (op === 'new' && this.first.isStatement(o))) {
2438 this.first = new Parens(this.first);
2440 parts.push(this.first.compileToFragments(o, LEVEL_OP));
2444 return this.joinFragmentArrays(parts, '');
2447 Op.prototype.compilePower = function(o) {
2449 pow = new Value(new Literal('Math'), [new Access(new Literal('pow'))]);
2450 return new Call(pow, [this.first, this.second]).compileToFragments(o);
2453 Op.prototype.compileFloorDivision = function(o) {
2455 floor = new Value(new Literal('Math'), [new Access(new Literal('floor'))]);
2456 div = new Op('/', this.first, this.second);
2457 return new Call(floor, [div]).compileToFragments(o);
2460 Op.prototype.compileModulo = function(o) {
2462 mod = new Value(new Literal(utility('modulo')));
2463 return new Call(mod, [this.first, this.second]).compileToFragments(o);
2466 Op.prototype.toString = function(idt) {
2467 return Op.__super__.toString.call(this, idt, this.constructor.name + ' ' + this.operator);
2474 exports.In = In = (function(_super) {
2475 __extends(In, _super);
2477 function In(object, array) {
2478 this.object = object;
2482 In.prototype.children = ['object', 'array'];
2484 In.prototype.invert = NEGATE;
2486 In.prototype.compileNode = function(o) {
2487 var hasSplat, obj, _i, _len, _ref2;
2488 if (this.array instanceof Value && this.array.isArray() && this.array.base.objects.length) {
2489 _ref2 = this.array.base.objects;
2490 for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
2492 if (!(obj instanceof Splat)) {
2499 return this.compileOrTest(o);
2502 return this.compileLoopTest(o);
2505 In.prototype.compileOrTest = function(o) {
2506 var cmp, cnj, i, item, ref, sub, tests, _i, _len, _ref2, _ref3, _ref4;
2507 _ref2 = this.object.cache(o, LEVEL_OP), sub = _ref2[0], ref = _ref2[1];
2508 _ref3 = this.negated ? [' !== ', ' && '] : [' === ', ' || '], cmp = _ref3[0], cnj = _ref3[1];
2510 _ref4 = this.array.base.objects;
2511 for (i = _i = 0, _len = _ref4.length; _i < _len; i = ++_i) {
2514 tests.push(this.makeCode(cnj));
2516 tests = tests.concat((i ? ref : sub), this.makeCode(cmp), item.compileToFragments(o, LEVEL_ACCESS));
2518 if (o.level < LEVEL_OP) {
2521 return this.wrapInBraces(tests);
2525 In.prototype.compileLoopTest = function(o) {
2526 var fragments, ref, sub, _ref2;
2527 _ref2 = this.object.cache(o, LEVEL_LIST), sub = _ref2[0], ref = _ref2[1];
2528 fragments = [].concat(this.makeCode(utility('indexOf') + ".call("), this.array.compileToFragments(o, LEVEL_LIST), this.makeCode(", "), ref, this.makeCode(") " + (this.negated ? '< 0' : '>= 0')));
2529 if (fragmentsToText(sub) === fragmentsToText(ref)) {
2532 fragments = sub.concat(this.makeCode(', '), fragments);
2533 if (o.level < LEVEL_LIST) {
2536 return this.wrapInBraces(fragments);
2540 In.prototype.toString = function(idt) {
2541 return In.__super__.toString.call(this, idt, this.constructor.name + (this.negated ? '!' : ''));
2548 exports.Try = Try = (function(_super) {
2549 __extends(Try, _super);
2551 function Try(attempt, errorVariable, recovery, ensure) {
2552 this.attempt = attempt;
2553 this.errorVariable = errorVariable;
2554 this.recovery = recovery;
2555 this.ensure = ensure;
2558 Try.prototype.children = ['attempt', 'recovery', 'ensure'];
2560 Try.prototype.isStatement = YES;
2562 Try.prototype.jumps = function(o) {
2564 return this.attempt.jumps(o) || ((_ref2 = this.recovery) != null ? _ref2.jumps(o) : void 0);
2567 Try.prototype.makeReturn = function(res) {
2569 this.attempt = this.attempt.makeReturn(res);
2571 if (this.recovery) {
2572 this.recovery = this.recovery.makeReturn(res);
2577 Try.prototype.compileNode = function(o) {
2578 var catchPart, ensurePart, placeholder, tryPart;
2580 tryPart = this.attempt.compileToFragments(o, LEVEL_TOP);
2581 catchPart = this.recovery ? (placeholder = new Literal('_error'), this.errorVariable ? this.recovery.unshift(new Assign(this.errorVariable, placeholder)) : void 0, [].concat(this.makeCode(" catch ("), placeholder.compileToFragments(o), this.makeCode(") {\n"), this.recovery.compileToFragments(o, LEVEL_TOP), this.makeCode("\n" + this.tab + "}"))) : !(this.ensure || this.recovery) ? [this.makeCode(' catch (_error) {}')] : [];
2582 ensurePart = this.ensure ? [].concat(this.makeCode(" finally {\n"), this.ensure.compileToFragments(o, LEVEL_TOP), this.makeCode("\n" + this.tab + "}")) : [];
2583 return [].concat(this.makeCode("" + this.tab + "try {\n"), tryPart, this.makeCode("\n" + this.tab + "}"), catchPart, ensurePart);
2590 exports.Throw = Throw = (function(_super) {
2591 __extends(Throw, _super);
2593 function Throw(expression) {
2594 this.expression = expression;
2597 Throw.prototype.children = ['expression'];
2599 Throw.prototype.isStatement = YES;
2601 Throw.prototype.jumps = NO;
2603 Throw.prototype.makeReturn = THIS;
2605 Throw.prototype.compileNode = function(o) {
2606 return [].concat(this.makeCode(this.tab + "throw "), this.expression.compileToFragments(o), this.makeCode(";"));
2613 exports.Existence = Existence = (function(_super) {
2614 __extends(Existence, _super);
2616 function Existence(expression) {
2617 this.expression = expression;
2620 Existence.prototype.children = ['expression'];
2622 Existence.prototype.invert = NEGATE;
2624 Existence.prototype.compileNode = function(o) {
2625 var cmp, cnj, code, _ref2;
2626 this.expression.front = this.front;
2627 code = this.expression.compile(o, LEVEL_OP);
2628 if (IDENTIFIER.test(code) && !o.scope.check(code)) {
2629 _ref2 = this.negated ? ['===', '||'] : ['!==', '&&'], cmp = _ref2[0], cnj = _ref2[1];
2630 code = "typeof " + code + " " + cmp + " \"undefined\" " + cnj + " " + code + " " + cmp + " null";
2632 code = "" + code + " " + (this.negated ? '==' : '!=') + " null";
2634 return [this.makeCode(o.level <= LEVEL_COND ? code : "(" + code + ")")];
2641 exports.Parens = Parens = (function(_super) {
2642 __extends(Parens, _super);
2644 function Parens(body) {
2648 Parens.prototype.children = ['body'];
2650 Parens.prototype.unwrap = function() {
2654 Parens.prototype.isComplex = function() {
2655 return this.body.isComplex();
2658 Parens.prototype.compileNode = function(o) {
2659 var bare, expr, fragments;
2660 expr = this.body.unwrap();
2661 if (expr instanceof Value && expr.isAtomic()) {
2662 expr.front = this.front;
2663 return expr.compileToFragments(o);
2665 fragments = expr.compileToFragments(o, LEVEL_PAREN);
2666 bare = o.level < LEVEL_OP && (expr instanceof Op || expr instanceof Call || (expr instanceof For && expr.returns));
2670 return this.wrapInBraces(fragments);
2678 exports.For = For = (function(_super) {
2679 __extends(For, _super);
2681 function For(body, source) {
2683 this.source = source.source, this.guard = source.guard, this.step = source.step, this.name = source.name, this.index = source.index;
2684 this.body = Block.wrap([body]);
2685 this.own = !!source.own;
2686 this.object = !!source.object;
2688 _ref2 = [this.index, this.name], this.name = _ref2[0], this.index = _ref2[1];
2690 if (this.index instanceof Value) {
2691 this.index.error('index cannot be a pattern matching expression');
2693 this.range = this.source instanceof Value && this.source.base instanceof Range && !this.source.properties.length;
2694 this.pattern = this.name instanceof Value;
2695 if (this.range && this.index) {
2696 this.index.error('indexes do not apply to range loops');
2698 if (this.range && this.pattern) {
2699 this.name.error('cannot pattern match over range loops');
2701 if (this.own && !this.object) {
2702 this.name.error('cannot use own with for-in');
2704 this.returns = false;
2707 For.prototype.children = ['body', 'source', 'guard', 'step'];
2709 For.prototype.compileNode = function(o) {
2710 var body, bodyFragments, compare, compareDown, declare, declareDown, defPart, defPartFragments, down, forPartFragments, guardPart, idt1, increment, index, ivar, kvar, kvarAssign, lastJumps, lvar, name, namePart, ref, resultPart, returnResult, rvar, scope, source, step, stepNum, stepVar, svar, varPart, _ref2, _ref3;
2711 body = Block.wrap([this.body]);
2712 lastJumps = (_ref2 = last(body.expressions)) != null ? _ref2.jumps() : void 0;
2713 if (lastJumps && lastJumps instanceof Return) {
2714 this.returns = false;
2716 source = this.range ? this.source.base : this.source;
2718 if (!this.pattern) {
2719 name = this.name && (this.name.compile(o, LEVEL_LIST));
2721 index = this.index && (this.index.compile(o, LEVEL_LIST));
2722 if (name && !this.pattern) {
2729 rvar = scope.freeVariable('results');
2731 ivar = (this.object && index) || scope.freeVariable('i');
2732 kvar = (this.range && name) || index || ivar;
2733 kvarAssign = kvar !== ivar ? "" + kvar + " = " : "";
2734 if (this.step && !this.range) {
2735 _ref3 = this.cacheToCodeFragments(this.step.cache(o, LEVEL_LIST)), step = _ref3[0], stepVar = _ref3[1];
2736 stepNum = stepVar.match(NUMBER);
2744 idt1 = this.tab + TAB;
2746 forPartFragments = source.compileToFragments(merge(o, {
2752 svar = this.source.compile(o, LEVEL_LIST);
2753 if ((name || this.own) && !IDENTIFIER.test(svar)) {
2754 defPart += "" + this.tab + (ref = scope.freeVariable('ref')) + " = " + svar + ";\n";
2757 if (name && !this.pattern) {
2758 namePart = "" + name + " = " + svar + "[" + kvar + "]";
2761 if (step !== stepVar) {
2762 defPart += "" + this.tab + step + ";\n";
2764 if (!(this.step && stepNum && (down = parseNum(stepNum[0]) < 0))) {
2765 lvar = scope.freeVariable('len');
2767 declare = "" + kvarAssign + ivar + " = 0, " + lvar + " = " + svar + ".length";
2768 declareDown = "" + kvarAssign + ivar + " = " + svar + ".length - 1";
2769 compare = "" + ivar + " < " + lvar;
2770 compareDown = "" + ivar + " >= 0";
2774 compare = compareDown;
2775 declare = declareDown;
2778 compare = "" + stepVar + " > 0 ? " + compare + " : " + compareDown;
2779 declare = "(" + stepVar + " > 0 ? (" + declare + ") : " + declareDown + ")";
2781 increment = "" + ivar + " += " + stepVar;
2783 increment = "" + (kvar !== ivar ? "++" + ivar : "" + ivar + "++");
2785 forPartFragments = [this.makeCode("" + declare + "; " + compare + "; " + kvarAssign + increment)];
2789 resultPart = "" + this.tab + rvar + " = [];\n";
2790 returnResult = "\n" + this.tab + "return " + rvar + ";";
2791 body.makeReturn(rvar);
2794 if (body.expressions.length > 1) {
2795 body.expressions.unshift(new If((new Parens(this.guard)).invert(), new Literal("continue")));
2798 body = Block.wrap([new If(this.guard, body)]);
2803 body.expressions.unshift(new Assign(this.name, new Literal("" + svar + "[" + kvar + "]")));
2805 defPartFragments = [].concat(this.makeCode(defPart), this.pluckDirectCall(o, body));
2807 varPart = "\n" + idt1 + namePart + ";";
2810 forPartFragments = [this.makeCode("" + kvar + " in " + svar)];
2812 guardPart = "\n" + idt1 + "if (!" + (utility('hasProp')) + ".call(" + svar + ", " + kvar + ")) continue;";
2815 bodyFragments = body.compileToFragments(merge(o, {
2818 if (bodyFragments && (bodyFragments.length > 0)) {
2819 bodyFragments = [].concat(this.makeCode("\n"), bodyFragments, this.makeCode("\n"));
2821 return [].concat(defPartFragments, this.makeCode("" + (resultPart || '') + this.tab + "for ("), forPartFragments, this.makeCode(") {" + guardPart + varPart), bodyFragments, this.makeCode("" + this.tab + "}" + (returnResult || '')));
2824 For.prototype.pluckDirectCall = function(o, body) {
2825 var base, defs, expr, fn, idx, ref, val, _i, _len, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8;
2827 _ref2 = body.expressions;
2828 for (idx = _i = 0, _len = _ref2.length; _i < _len; idx = ++_i) {
2830 expr = expr.unwrapAll();
2831 if (!(expr instanceof Call)) {
2834 val = (_ref3 = expr.variable) != null ? _ref3.unwrapAll() : void 0;
2835 if (!((val instanceof Code) || (val instanceof Value && ((_ref4 = val.base) != null ? _ref4.unwrapAll() : void 0) instanceof Code && val.properties.length === 1 && ((_ref5 = (_ref6 = val.properties[0].name) != null ? _ref6.value : void 0) === 'call' || _ref5 === 'apply')))) {
2838 fn = ((_ref7 = val.base) != null ? _ref7.unwrapAll() : void 0) || val;
2839 ref = new Literal(o.scope.freeVariable('fn'));
2840 base = new Value(ref);
2842 _ref8 = [base, val], val.base = _ref8[0], base = _ref8[1];
2844 body.expressions[idx] = new Call(base, expr.args);
2845 defs = defs.concat(this.makeCode(this.tab), new Assign(ref, fn).compileToFragments(o, LEVEL_TOP), this.makeCode(';\n'));
2854 exports.Switch = Switch = (function(_super) {
2855 __extends(Switch, _super);
2857 function Switch(subject, cases, otherwise) {
2858 this.subject = subject;
2860 this.otherwise = otherwise;
2863 Switch.prototype.children = ['subject', 'cases', 'otherwise'];
2865 Switch.prototype.isStatement = YES;
2867 Switch.prototype.jumps = function(o) {
2868 var block, conds, jumpNode, _i, _len, _ref2, _ref3, _ref4;
2875 for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
2876 _ref3 = _ref2[_i], conds = _ref3[0], block = _ref3[1];
2877 if (jumpNode = block.jumps(o)) {
2881 return (_ref4 = this.otherwise) != null ? _ref4.jumps(o) : void 0;
2884 Switch.prototype.makeReturn = function(res) {
2885 var pair, _i, _len, _ref2, _ref3;
2887 for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
2889 pair[1].makeReturn(res);
2892 this.otherwise || (this.otherwise = new Block([new Literal('void 0')]));
2894 if ((_ref3 = this.otherwise) != null) {
2895 _ref3.makeReturn(res);
2900 Switch.prototype.compileNode = function(o) {
2901 var block, body, cond, conditions, expr, fragments, i, idt1, idt2, _i, _j, _len, _len1, _ref2, _ref3, _ref4;
2902 idt1 = o.indent + TAB;
2903 idt2 = o.indent = idt1 + TAB;
2904 fragments = [].concat(this.makeCode(this.tab + "switch ("), (this.subject ? this.subject.compileToFragments(o, LEVEL_PAREN) : this.makeCode("false")), this.makeCode(") {\n"));
2906 for (i = _i = 0, _len = _ref2.length; _i < _len; i = ++_i) {
2907 _ref3 = _ref2[i], conditions = _ref3[0], block = _ref3[1];
2908 _ref4 = flatten([conditions]);
2909 for (_j = 0, _len1 = _ref4.length; _j < _len1; _j++) {
2911 if (!this.subject) {
2912 cond = cond.invert();
2914 fragments = fragments.concat(this.makeCode(idt1 + "case "), cond.compileToFragments(o, LEVEL_PAREN), this.makeCode(":\n"));
2916 if ((body = block.compileToFragments(o, LEVEL_TOP)).length > 0) {
2917 fragments = fragments.concat(body, this.makeCode('\n'));
2919 if (i === this.cases.length - 1 && !this.otherwise) {
2922 expr = this.lastNonComment(block.expressions);
2923 if (expr instanceof Return || (expr instanceof Literal && expr.jumps() && expr.value !== 'debugger')) {
2926 fragments.push(cond.makeCode(idt2 + 'break;\n'));
2928 if (this.otherwise && this.otherwise.expressions.length) {
2929 fragments.push.apply(fragments, [this.makeCode(idt1 + "default:\n")].concat(__slice.call(this.otherwise.compileToFragments(o, LEVEL_TOP)), [this.makeCode("\n")]));
2931 fragments.push(this.makeCode(this.tab + '}'));
2939 exports.If = If = (function(_super) {
2940 __extends(If, _super);
2942 function If(condition, body, options) {
2944 if (options == null) {
2947 this.condition = options.type === 'unless' ? condition.invert() : condition;
2948 this.elseBody = null;
2949 this.isChain = false;
2950 this.soak = options.soak;
2953 If.prototype.children = ['condition', 'body', 'elseBody'];
2955 If.prototype.bodyNode = function() {
2957 return (_ref2 = this.body) != null ? _ref2.unwrap() : void 0;
2960 If.prototype.elseBodyNode = function() {
2962 return (_ref2 = this.elseBody) != null ? _ref2.unwrap() : void 0;
2965 If.prototype.addElse = function(elseBody) {
2967 this.elseBodyNode().addElse(elseBody);
2969 this.isChain = elseBody instanceof If;
2970 this.elseBody = this.ensureBlock(elseBody);
2971 this.elseBody.updateLocationDataIfMissing(elseBody.locationData);
2976 If.prototype.isStatement = function(o) {
2978 return (o != null ? o.level : void 0) === LEVEL_TOP || this.bodyNode().isStatement(o) || ((_ref2 = this.elseBodyNode()) != null ? _ref2.isStatement(o) : void 0);
2981 If.prototype.jumps = function(o) {
2983 return this.body.jumps(o) || ((_ref2 = this.elseBody) != null ? _ref2.jumps(o) : void 0);
2986 If.prototype.compileNode = function(o) {
2987 if (this.isStatement(o)) {
2988 return this.compileStatement(o);
2990 return this.compileExpression(o);
2994 If.prototype.makeReturn = function(res) {
2996 this.elseBody || (this.elseBody = new Block([new Literal('void 0')]));
2998 this.body && (this.body = new Block([this.body.makeReturn(res)]));
2999 this.elseBody && (this.elseBody = new Block([this.elseBody.makeReturn(res)]));
3003 If.prototype.ensureBlock = function(node) {
3004 if (node instanceof Block) {
3007 return new Block([node]);
3011 If.prototype.compileStatement = function(o) {
3012 var answer, body, child, cond, exeq, ifPart, indent;
3013 child = del(o, 'chainChild');
3014 exeq = del(o, 'isExistentialEquals');
3016 return new If(this.condition.invert(), this.elseBodyNode(), {
3018 }).compileToFragments(o);
3020 indent = o.indent + TAB;
3021 cond = this.condition.compileToFragments(o, LEVEL_PAREN);
3022 body = this.ensureBlock(this.body).compileToFragments(merge(o, {
3025 ifPart = [].concat(this.makeCode("if ("), cond, this.makeCode(") {\n"), body, this.makeCode("\n" + this.tab + "}"));
3027 ifPart.unshift(this.makeCode(this.tab));
3029 if (!this.elseBody) {
3032 answer = ifPart.concat(this.makeCode(' else '));
3034 o.chainChild = true;
3035 answer = answer.concat(this.elseBody.unwrap().compileToFragments(o, LEVEL_TOP));
3037 answer = answer.concat(this.makeCode("{\n"), this.elseBody.compileToFragments(merge(o, {
3039 }), LEVEL_TOP), this.makeCode("\n" + this.tab + "}"));
3044 If.prototype.compileExpression = function(o) {
3045 var alt, body, cond, fragments;
3046 cond = this.condition.compileToFragments(o, LEVEL_COND);
3047 body = this.bodyNode().compileToFragments(o, LEVEL_LIST);
3048 alt = this.elseBodyNode() ? this.elseBodyNode().compileToFragments(o, LEVEL_LIST) : [this.makeCode('void 0')];
3049 fragments = cond.concat(this.makeCode(" ? "), body, this.makeCode(" : "), alt);
3050 if (o.level >= LEVEL_COND) {
3051 return this.wrapInBraces(fragments);
3057 If.prototype.unfoldSoak = function() {
3058 return this.soak && this;
3066 "extends": function() {
3067 return "function(child, parent) { for (var key in parent) { if (" + (utility('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; }";
3070 return 'function(fn, me){ return function(){ return fn.apply(me, arguments); }; }';
3072 indexOf: function() {
3073 return "[].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }";
3075 modulo: function() {
3076 return "function(a, b) { return (+a % (b = +b) + b) % b; }";
3078 hasProp: function() {
3079 return '{}.hasOwnProperty';
3100 IDENTIFIER_STR = "[$A-Za-z_\\x7f-\\uffff][$\\w\\x7f-\\uffff]*";
3102 IDENTIFIER = RegExp("^" + IDENTIFIER_STR + "$");
3104 SIMPLENUM = /^[+-]?\d+$/;
3106 HEXNUM = /^[+-]?0x[\da-f]+/i;
3108 NUMBER = /^[+-]?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)$/i;
3110 METHOD_DEF = RegExp("^(" + IDENTIFIER_STR + ")(\\.prototype)?(?:\\.(" + IDENTIFIER_STR + ")|\\[(\"(?:[^\\\\\"\\r\\n]|\\\\.)*\"|'(?:[^\\\\'\\r\\n]|\\\\.)*')\\]|\\[(0x[\\da-fA-F]+|\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\])$");
3112 IS_STRING = /^['"]/;
3116 utility = function(name) {
3119 Scope.root.assign(ref, UTILITIES[name]());
3123 multident = function(code, tab) {
3124 code = code.replace(/\n/g, '$&' + tab);
3125 return code.replace(/\s+$/, '');
3128 parseNum = function(x) {
3131 } else if (x.match(HEXNUM)) {
3132 return parseInt(x, 16);
3134 return parseFloat(x);
3138 isLiteralArguments = function(node) {
3139 return node instanceof Literal && node.value === 'arguments' && !node.asKey;
3142 isLiteralThis = function(node) {
3143 return (node instanceof Literal && node.value === 'this' && !node.asKey) || (node instanceof Code && node.bound) || (node instanceof Call && node.isSuper);
3146 unfoldSoak = function(o, parent, name) {
3148 if (!(ifn = parent[name].unfoldSoak(o))) {
3151 parent[name] = ifn.body;
3152 ifn.body = new Value(parent);