1 // Generated by CoffeeScript 1.10.0
3 var Access, Arr, Assign, Base, Block, Call, Class, Code, CodeFragment, Comment, Existence, Expansion, Extends, For, HEXNUM, IDENTIFIER, IS_REGEX, IS_STRING, If, In, Index, LEVEL_ACCESS, LEVEL_COND, LEVEL_LIST, LEVEL_OP, LEVEL_PAREN, LEVEL_TOP, Literal, 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, isComplexOrAssignable, isLiteralArguments, isLiteralThis, locationDataToString, merge, multident, parseNum, ref1, ref2, some, starts, throwSyntaxError, unfoldSoak, utility,
4 extend1 = 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; },
5 hasProp = {}.hasOwnProperty,
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 ref1 = require('./lexer'), RESERVED = ref1.RESERVED, STRICT_PROSCRIBED = ref1.STRICT_PROSCRIBED;
15 ref2 = require('./helpers'), compact = ref2.compact, flatten = ref2.flatten, extend = ref2.extend, merge = ref2.merge, del = ref2.del, starts = ref2.starts, ends = ref2.ends, some = ref2.some, addLocationDataFn = ref2.addLocationDataFn, locationDataToString = ref2.locationDataToString, throwSyntaxError = ref2.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 ? (ref3 = parent.constructor) != null ? ref3.name : void 0 : void 0) || 'unknown';
46 CodeFragment.prototype.toString = function() {
47 return "" + this.code + (this.locationData ? ": " + locationDataToString(this.locationData) : '');
54 fragmentsToText = function(fragments) {
59 for (j = 0, len1 = fragments.length; j < len1; j++) {
60 fragment = fragments[j];
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, parts, ref3;
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 parts = (new Call(func, args)).compileNode(o);
108 if (func.isGenerator || ((ref3 = func.base) != null ? ref3.isGenerator : void 0)) {
109 parts.unshift(this.makeCode("(yield* "));
110 parts.push(this.makeCode(")"));
115 Base.prototype.cache = function(o, level, isComplex) {
116 var complex, ref, sub;
117 complex = isComplex != null ? isComplex(this) : this.isComplex();
119 ref = new Literal(o.scope.freeVariable('ref'));
120 sub = new Assign(ref, this);
122 return [sub.compileToFragments(o, level), [this.makeCode(ref.value)]];
127 ref = level ? this.compileToFragments(o, level) : this;
132 Base.prototype.cacheToCodeFragments = function(cacheValues) {
133 return [fragmentsToText(cacheValues[0]), fragmentsToText(cacheValues[1])];
136 Base.prototype.makeReturn = function(res) {
138 me = this.unwrapAll();
140 return new Call(new Literal(res + ".push"), [me]);
142 return new Return(me);
146 Base.prototype.contains = function(pred) {
149 this.traverseChildren(false, function(n) {
158 Base.prototype.lastNonComment = function(list) {
162 if (!(list[i] instanceof Comment)) {
169 Base.prototype.toString = function(idt, name) {
175 name = this.constructor.name;
177 tree = '\n' + idt + name;
181 this.eachChild(function(node) {
182 return tree += node.toString(idt + TAB);
187 Base.prototype.eachChild = function(func) {
188 var attr, child, j, k, len1, len2, ref3, ref4;
189 if (!this.children) {
192 ref3 = this.children;
193 for (j = 0, len1 = ref3.length; j < len1; j++) {
196 ref4 = flatten([this[attr]]);
197 for (k = 0, len2 = ref4.length; k < len2; k++) {
199 if (func(child) === false) {
208 Base.prototype.traverseChildren = function(crossScope, func) {
209 return this.eachChild(function(child) {
212 if (recur !== false) {
213 return child.traverseChildren(crossScope, func);
218 Base.prototype.invert = function() {
219 return new Op('!', this);
222 Base.prototype.unwrapAll = function() {
225 while (node !== (node = node.unwrap())) {
231 Base.prototype.children = [];
233 Base.prototype.isStatement = NO;
235 Base.prototype.jumps = NO;
237 Base.prototype.isComplex = YES;
239 Base.prototype.isChainable = NO;
241 Base.prototype.isAssignable = NO;
243 Base.prototype.unwrap = THIS;
245 Base.prototype.unfoldSoak = NO;
247 Base.prototype.assigns = NO;
249 Base.prototype.updateLocationDataIfMissing = function(locationData) {
250 if (this.locationData) {
253 this.locationData = locationData;
254 return this.eachChild(function(child) {
255 return child.updateLocationDataIfMissing(locationData);
259 Base.prototype.error = function(message) {
260 return throwSyntaxError(message, this.locationData);
263 Base.prototype.makeCode = function(code) {
264 return new CodeFragment(this, code);
267 Base.prototype.wrapInBraces = function(fragments) {
268 return [].concat(this.makeCode('('), fragments, this.makeCode(')'));
271 Base.prototype.joinFragmentArrays = function(fragmentsList, joinStr) {
272 var answer, fragments, i, j, len1;
274 for (i = j = 0, len1 = fragmentsList.length; j < len1; i = ++j) {
275 fragments = fragmentsList[i];
277 answer.push(this.makeCode(joinStr));
279 answer = answer.concat(fragments);
288 exports.Block = Block = (function(superClass1) {
289 extend1(Block, superClass1);
291 function Block(nodes) {
292 this.expressions = compact(flatten(nodes || []));
295 Block.prototype.children = ['expressions'];
297 Block.prototype.push = function(node) {
298 this.expressions.push(node);
302 Block.prototype.pop = function() {
303 return this.expressions.pop();
306 Block.prototype.unshift = function(node) {
307 this.expressions.unshift(node);
311 Block.prototype.unwrap = function() {
312 if (this.expressions.length === 1) {
313 return this.expressions[0];
319 Block.prototype.isEmpty = function() {
320 return !this.expressions.length;
323 Block.prototype.isStatement = function(o) {
324 var exp, j, len1, ref3;
325 ref3 = this.expressions;
326 for (j = 0, len1 = ref3.length; j < len1; j++) {
328 if (exp.isStatement(o)) {
335 Block.prototype.jumps = function(o) {
336 var exp, j, jumpNode, len1, ref3;
337 ref3 = this.expressions;
338 for (j = 0, len1 = ref3.length; j < len1; j++) {
340 if (jumpNode = exp.jumps(o)) {
346 Block.prototype.makeReturn = function(res) {
348 len = this.expressions.length;
350 expr = this.expressions[len];
351 if (!(expr instanceof Comment)) {
352 this.expressions[len] = expr.makeReturn(res);
353 if (expr instanceof Return && !expr.expression) {
354 this.expressions.splice(len, 1);
362 Block.prototype.compileToFragments = function(o, level) {
367 return Block.__super__.compileToFragments.call(this, o, level);
369 return this.compileRoot(o);
373 Block.prototype.compileNode = function(o) {
374 var answer, compiledNodes, fragments, index, j, len1, node, ref3, top;
376 top = o.level === LEVEL_TOP;
378 ref3 = this.expressions;
379 for (index = j = 0, len1 = ref3.length; j < len1; index = ++j) {
381 node = node.unwrapAll();
382 node = node.unfoldSoak(o) || node;
383 if (node instanceof Block) {
384 compiledNodes.push(node.compileNode(o));
387 fragments = node.compileToFragments(o);
388 if (!node.isStatement(o)) {
389 fragments.unshift(this.makeCode("" + this.tab));
390 fragments.push(this.makeCode(";"));
392 compiledNodes.push(fragments);
394 compiledNodes.push(node.compileToFragments(o, LEVEL_LIST));
399 return [].concat(this.joinFragmentArrays(compiledNodes, '\n\n'), this.makeCode("\n"));
401 return this.joinFragmentArrays(compiledNodes, '\n');
404 if (compiledNodes.length) {
405 answer = this.joinFragmentArrays(compiledNodes, ', ');
407 answer = [this.makeCode("void 0")];
409 if (compiledNodes.length > 1 && o.level >= LEVEL_LIST) {
410 return this.wrapInBraces(answer);
416 Block.prototype.compileRoot = function(o) {
417 var exp, fragments, i, j, len1, name, prelude, preludeExps, ref3, ref4, rest;
418 o.indent = o.bare ? '' : TAB;
421 o.scope = new Scope(null, this, null, (ref3 = o.referencedVars) != null ? ref3 : []);
422 ref4 = o.locals || [];
423 for (j = 0, len1 = ref4.length; j < len1; j++) {
425 o.scope.parameter(name);
429 preludeExps = (function() {
430 var k, len2, ref5, results;
431 ref5 = this.expressions;
433 for (i = k = 0, len2 = ref5.length; k < len2; i = ++k) {
435 if (!(exp.unwrap() instanceof Comment)) {
442 rest = this.expressions.slice(preludeExps.length);
443 this.expressions = preludeExps;
444 if (preludeExps.length) {
445 prelude = this.compileNode(merge(o, {
448 prelude.push(this.makeCode("\n"));
450 this.expressions = rest;
452 fragments = this.compileWithDeclarations(o);
456 return [].concat(prelude, this.makeCode("(function() {\n"), fragments, this.makeCode("\n}).call(this);\n"));
459 Block.prototype.compileWithDeclarations = function(o) {
460 var assigns, declars, exp, fragments, i, j, len1, post, ref3, ref4, ref5, rest, scope, spaced;
463 ref3 = this.expressions;
464 for (i = j = 0, len1 = ref3.length; j < len1; i = ++j) {
467 if (!(exp instanceof Comment || exp instanceof Literal)) {
475 rest = this.expressions.splice(i, 9e9);
476 ref4 = [this.spaced, false], spaced = ref4[0], this.spaced = ref4[1];
477 ref5 = [this.compileNode(o), spaced], fragments = ref5[0], this.spaced = ref5[1];
478 this.expressions = rest;
480 post = this.compileNode(o);
482 if (scope.expressions === this) {
483 declars = o.scope.hasDeclarations();
484 assigns = scope.hasAssignments;
485 if (declars || assigns) {
487 fragments.push(this.makeCode('\n'));
489 fragments.push(this.makeCode(this.tab + "var "));
491 fragments.push(this.makeCode(scope.declaredVariables().join(', ')));
495 fragments.push(this.makeCode(",\n" + (this.tab + TAB)));
497 fragments.push(this.makeCode(scope.assignedVariables().join(",\n" + (this.tab + TAB))));
499 fragments.push(this.makeCode(";\n" + (this.spaced ? '\n' : '')));
500 } else if (fragments.length && post.length) {
501 fragments.push(this.makeCode("\n"));
504 return fragments.concat(post);
507 Block.wrap = function(nodes) {
508 if (nodes.length === 1 && nodes[0] instanceof Block) {
511 return new Block(nodes);
518 exports.Literal = Literal = (function(superClass1) {
519 extend1(Literal, superClass1);
521 function Literal(value1) {
525 Literal.prototype.makeReturn = function() {
526 if (this.isStatement()) {
529 return Literal.__super__.makeReturn.apply(this, arguments);
533 Literal.prototype.isAssignable = function() {
534 return IDENTIFIER.test(this.value);
537 Literal.prototype.isStatement = function() {
539 return (ref3 = this.value) === 'break' || ref3 === 'continue' || ref3 === 'debugger';
542 Literal.prototype.isComplex = NO;
544 Literal.prototype.assigns = function(name) {
545 return name === this.value;
548 Literal.prototype.jumps = function(o) {
549 if (this.value === 'break' && !((o != null ? o.loop : void 0) || (o != null ? o.block : void 0))) {
552 if (this.value === 'continue' && !(o != null ? o.loop : void 0)) {
557 Literal.prototype.compileNode = function(o) {
558 var answer, code, ref3;
559 code = this.value === 'this' ? ((ref3 = o.scope.method) != null ? ref3.bound : void 0) ? o.scope.method.context : this.value : this.value.reserved ? "\"" + this.value + "\"" : this.value;
560 answer = this.isStatement() ? "" + this.tab + code + ";" : code;
561 return [this.makeCode(answer)];
564 Literal.prototype.toString = function() {
565 return ' "' + this.value + '"';
572 exports.Undefined = (function(superClass1) {
573 extend1(Undefined, superClass1);
575 function Undefined() {
576 return Undefined.__super__.constructor.apply(this, arguments);
579 Undefined.prototype.isAssignable = NO;
581 Undefined.prototype.isComplex = NO;
583 Undefined.prototype.compileNode = function(o) {
584 return [this.makeCode(o.level >= LEVEL_ACCESS ? '(void 0)' : 'void 0')];
591 exports.Null = (function(superClass1) {
592 extend1(Null, superClass1);
595 return Null.__super__.constructor.apply(this, arguments);
598 Null.prototype.isAssignable = NO;
600 Null.prototype.isComplex = NO;
602 Null.prototype.compileNode = function() {
603 return [this.makeCode("null")];
610 exports.Bool = (function(superClass1) {
611 extend1(Bool, superClass1);
613 Bool.prototype.isAssignable = NO;
615 Bool.prototype.isComplex = NO;
617 Bool.prototype.compileNode = function() {
618 return [this.makeCode(this.val)];
621 function Bool(val1) {
629 exports.Return = Return = (function(superClass1) {
630 extend1(Return, superClass1);
632 function Return(expression) {
633 this.expression = expression;
636 Return.prototype.children = ['expression'];
638 Return.prototype.isStatement = YES;
640 Return.prototype.makeReturn = THIS;
642 Return.prototype.jumps = THIS;
644 Return.prototype.compileToFragments = function(o, level) {
646 expr = (ref3 = this.expression) != null ? ref3.makeReturn() : void 0;
647 if (expr && !(expr instanceof Return)) {
648 return expr.compileToFragments(o, level);
650 return Return.__super__.compileToFragments.call(this, o, level);
654 Return.prototype.compileNode = function(o) {
655 var answer, exprIsYieldReturn, ref3;
657 exprIsYieldReturn = (ref3 = this.expression) != null ? typeof ref3.isYieldReturn === "function" ? ref3.isYieldReturn() : void 0 : void 0;
658 if (!exprIsYieldReturn) {
659 answer.push(this.makeCode(this.tab + ("return" + (this.expression ? " " : ""))));
661 if (this.expression) {
662 answer = answer.concat(this.expression.compileToFragments(o, LEVEL_PAREN));
664 if (!exprIsYieldReturn) {
665 answer.push(this.makeCode(";"));
674 exports.Value = Value = (function(superClass1) {
675 extend1(Value, superClass1);
677 function Value(base, props, tag) {
678 if (!props && base instanceof Value) {
682 this.properties = props || [];
689 Value.prototype.children = ['base', 'properties'];
691 Value.prototype.add = function(props) {
692 this.properties = this.properties.concat(props);
696 Value.prototype.hasProperties = function() {
697 return !!this.properties.length;
700 Value.prototype.bareLiteral = function(type) {
701 return !this.properties.length && this.base instanceof type;
704 Value.prototype.isArray = function() {
705 return this.bareLiteral(Arr);
708 Value.prototype.isRange = function() {
709 return this.bareLiteral(Range);
712 Value.prototype.isComplex = function() {
713 return this.hasProperties() || this.base.isComplex();
716 Value.prototype.isAssignable = function() {
717 return this.hasProperties() || this.base.isAssignable();
720 Value.prototype.isSimpleNumber = function() {
721 return this.bareLiteral(Literal) && SIMPLENUM.test(this.base.value);
724 Value.prototype.isString = function() {
725 return this.bareLiteral(Literal) && IS_STRING.test(this.base.value);
728 Value.prototype.isRegex = function() {
729 return this.bareLiteral(Literal) && IS_REGEX.test(this.base.value);
732 Value.prototype.isAtomic = function() {
733 var j, len1, node, ref3;
734 ref3 = this.properties.concat(this.base);
735 for (j = 0, len1 = ref3.length; j < len1; j++) {
737 if (node.soak || node instanceof Call) {
744 Value.prototype.isNotCallable = function() {
745 return this.isSimpleNumber() || this.isString() || this.isRegex() || this.isArray() || this.isRange() || this.isSplice() || this.isObject();
748 Value.prototype.isStatement = function(o) {
749 return !this.properties.length && this.base.isStatement(o);
752 Value.prototype.assigns = function(name) {
753 return !this.properties.length && this.base.assigns(name);
756 Value.prototype.jumps = function(o) {
757 return !this.properties.length && this.base.jumps(o);
760 Value.prototype.isObject = function(onlyGenerated) {
761 if (this.properties.length) {
764 return (this.base instanceof Obj) && (!onlyGenerated || this.base.generated);
767 Value.prototype.isSplice = function() {
769 ref3 = this.properties, lastProp = ref3[ref3.length - 1];
770 return lastProp instanceof Slice;
773 Value.prototype.looksStatic = function(className) {
775 return this.base.value === className && this.properties.length === 1 && ((ref3 = this.properties[0].name) != null ? ref3.value : void 0) !== 'prototype';
778 Value.prototype.unwrap = function() {
779 if (this.properties.length) {
786 Value.prototype.cacheReference = function(o) {
787 var base, bref, name, nref, ref3;
788 ref3 = this.properties, name = ref3[ref3.length - 1];
789 if (this.properties.length < 2 && !this.base.isComplex() && !(name != null ? name.isComplex() : void 0)) {
792 base = new Value(this.base, this.properties.slice(0, -1));
793 if (base.isComplex()) {
794 bref = new Literal(o.scope.freeVariable('base'));
795 base = new Value(new Parens(new Assign(bref, base)));
800 if (name.isComplex()) {
801 nref = new Literal(o.scope.freeVariable('name'));
802 name = new Index(new Assign(nref, name.index));
803 nref = new Index(nref);
805 return [base.add(name), new Value(bref || base.base, [nref || name])];
808 Value.prototype.compileNode = function(o) {
809 var fragments, j, len1, prop, props;
810 this.base.front = this.front;
811 props = this.properties;
812 fragments = this.base.compileToFragments(o, (props.length ? LEVEL_ACCESS : null));
813 if ((this.base instanceof Parens || props.length) && SIMPLENUM.test(fragmentsToText(fragments))) {
814 fragments.push(this.makeCode('.'));
816 for (j = 0, len1 = props.length; j < len1; j++) {
818 fragments.push.apply(fragments, prop.compileToFragments(o));
823 Value.prototype.unfoldSoak = function(o) {
824 return this.unfoldedSoak != null ? this.unfoldedSoak : this.unfoldedSoak = (function(_this) {
826 var fst, i, ifn, j, len1, prop, ref, ref3, ref4, snd;
827 if (ifn = _this.base.unfoldSoak(o)) {
828 (ref3 = ifn.body.properties).push.apply(ref3, _this.properties);
831 ref4 = _this.properties;
832 for (i = j = 0, len1 = ref4.length; j < len1; i = ++j) {
838 fst = new Value(_this.base, _this.properties.slice(0, i));
839 snd = new Value(_this.base, _this.properties.slice(i));
840 if (fst.isComplex()) {
841 ref = new Literal(o.scope.freeVariable('ref'));
842 fst = new Parens(new Assign(ref, fst));
845 return new If(new Existence(fst), snd, {
858 exports.Comment = Comment = (function(superClass1) {
859 extend1(Comment, superClass1);
861 function Comment(comment1) {
862 this.comment = comment1;
865 Comment.prototype.isStatement = YES;
867 Comment.prototype.makeReturn = THIS;
869 Comment.prototype.compileNode = function(o, level) {
871 comment = this.comment.replace(/^(\s*)#(?=\s)/gm, "$1 *");
872 code = "/*" + (multident(comment, this.tab)) + (indexOf.call(comment, '\n') >= 0 ? "\n" + this.tab : '') + " */";
873 if ((level || o.level) === LEVEL_TOP) {
874 code = o.indent + code;
876 return [this.makeCode("\n"), this.makeCode(code)];
883 exports.Call = Call = (function(superClass1) {
884 extend1(Call, superClass1);
886 function Call(variable, args1, soak) {
887 this.args = args1 != null ? args1 : [];
890 this.isSuper = variable === 'super';
891 this.variable = this.isSuper ? null : variable;
892 if (variable instanceof Value && variable.isNotCallable()) {
893 variable.error("literal is not a function");
897 Call.prototype.children = ['variable', 'args'];
899 Call.prototype.newInstance = function() {
901 base = ((ref3 = this.variable) != null ? ref3.base : void 0) || this.variable;
902 if (base instanceof Call && !base.isNew) {
910 Call.prototype.superReference = function(o) {
911 var accesses, base, bref, klass, method, name, nref, variable;
912 method = o.scope.namedMethod();
913 if (method != null ? method.klass : void 0) {
914 klass = method.klass, name = method.name, variable = method.variable;
915 if (klass.isComplex()) {
916 bref = new Literal(o.scope.parent.freeVariable('base'));
917 base = new Value(new Parens(new Assign(bref, klass)));
918 variable.base = base;
919 variable.properties.splice(0, klass.properties.length);
921 if (name.isComplex() || (name instanceof Index && name.index.isAssignable())) {
922 nref = new Literal(o.scope.parent.freeVariable('name'));
923 name = new Index(new Assign(nref, name.index));
924 variable.properties.pop();
925 variable.properties.push(name);
927 accesses = [new Access(new Literal('__super__'))];
928 if (method["static"]) {
929 accesses.push(new Access(new Literal('constructor')));
931 accesses.push(nref != null ? new Index(nref) : name);
932 return (new Value(bref != null ? bref : klass, accesses)).compile(o);
933 } else if (method != null ? method.ctor : void 0) {
934 return method.name + ".__super__.constructor";
936 return this.error('cannot call super outside of an instance method.');
940 Call.prototype.superThis = function(o) {
942 method = o.scope.method;
943 return (method && !method.klass && method.context) || "this";
946 Call.prototype.unfoldSoak = function(o) {
947 var call, ifn, j, left, len1, list, ref3, ref4, rite;
950 if (ifn = unfoldSoak(o, this, 'variable')) {
953 ref3 = new Value(this.variable).cacheReference(o), left = ref3[0], rite = ref3[1];
955 left = new Literal(this.superReference(o));
956 rite = new Value(left);
958 rite = new Call(rite, this.args);
959 rite.isNew = this.isNew;
960 left = new Literal("typeof " + (left.compile(o)) + " === \"function\"");
961 return new If(left, new Value(rite), {
968 if (call.variable instanceof Call) {
970 call = call.variable;
973 if (!(call.variable instanceof Value)) {
977 if (!((call = call.variable.base) instanceof Call)) {
981 ref4 = list.reverse();
982 for (j = 0, len1 = ref4.length; j < len1; j++) {
985 if (call.variable instanceof Call) {
988 call.variable.base = ifn;
991 ifn = unfoldSoak(o, call, 'variable');
996 Call.prototype.compileNode = function(o) {
997 var arg, argIndex, compiledArgs, compiledArray, fragments, j, len1, preface, ref3, ref4;
998 if ((ref3 = this.variable) != null) {
999 ref3.front = this.front;
1001 compiledArray = Splat.compileSplattedArray(o, this.args, true);
1002 if (compiledArray.length) {
1003 return this.compileSplat(o, compiledArray);
1007 for (argIndex = j = 0, len1 = ref4.length; j < len1; argIndex = ++j) {
1008 arg = ref4[argIndex];
1010 compiledArgs.push(this.makeCode(", "));
1012 compiledArgs.push.apply(compiledArgs, arg.compileToFragments(o, LEVEL_LIST));
1016 preface = this.superReference(o) + (".call(" + (this.superThis(o)));
1017 if (compiledArgs.length) {
1020 fragments.push(this.makeCode(preface));
1023 fragments.push(this.makeCode('new '));
1025 fragments.push.apply(fragments, this.variable.compileToFragments(o, LEVEL_ACCESS));
1026 fragments.push(this.makeCode("("));
1028 fragments.push.apply(fragments, compiledArgs);
1029 fragments.push(this.makeCode(")"));
1033 Call.prototype.compileSplat = function(o, splatArgs) {
1034 var answer, base, fun, idt, name, ref;
1036 return [].concat(this.makeCode((this.superReference(o)) + ".apply(" + (this.superThis(o)) + ", "), splatArgs, this.makeCode(")"));
1039 idt = this.tab + TAB;
1040 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(){})"));
1043 base = new Value(this.variable);
1044 if ((name = base.properties.pop()) && base.isComplex()) {
1045 ref = o.scope.freeVariable('ref');
1046 answer = answer.concat(this.makeCode("(" + ref + " = "), base.compileToFragments(o, LEVEL_LIST), this.makeCode(")"), name.compileToFragments(o));
1048 fun = base.compileToFragments(o, LEVEL_ACCESS);
1049 if (SIMPLENUM.test(fragmentsToText(fun))) {
1050 fun = this.wrapInBraces(fun);
1053 ref = fragmentsToText(fun);
1054 fun.push.apply(fun, name.compileToFragments(o));
1058 answer = answer.concat(fun);
1060 return answer = answer.concat(this.makeCode(".apply(" + ref + ", "), splatArgs, this.makeCode(")"));
1067 exports.Extends = Extends = (function(superClass1) {
1068 extend1(Extends, superClass1);
1070 function Extends(child1, parent1) {
1071 this.child = child1;
1072 this.parent = parent1;
1075 Extends.prototype.children = ['child', 'parent'];
1077 Extends.prototype.compileToFragments = function(o) {
1078 return new Call(new Value(new Literal(utility('extend', o))), [this.child, this.parent]).compileToFragments(o);
1085 exports.Access = Access = (function(superClass1) {
1086 extend1(Access, superClass1);
1088 function Access(name1, tag) {
1090 this.name.asKey = true;
1091 this.soak = tag === 'soak';
1094 Access.prototype.children = ['name'];
1096 Access.prototype.compileToFragments = function(o) {
1098 name = this.name.compileToFragments(o);
1099 if (IDENTIFIER.test(fragmentsToText(name))) {
1100 name.unshift(this.makeCode("."));
1102 name.unshift(this.makeCode("["));
1103 name.push(this.makeCode("]"));
1108 Access.prototype.isComplex = NO;
1114 exports.Index = Index = (function(superClass1) {
1115 extend1(Index, superClass1);
1117 function Index(index1) {
1118 this.index = index1;
1121 Index.prototype.children = ['index'];
1123 Index.prototype.compileToFragments = function(o) {
1124 return [].concat(this.makeCode("["), this.index.compileToFragments(o, LEVEL_PAREN), this.makeCode("]"));
1127 Index.prototype.isComplex = function() {
1128 return this.index.isComplex();
1135 exports.Range = Range = (function(superClass1) {
1136 extend1(Range, superClass1);
1138 Range.prototype.children = ['from', 'to'];
1140 function Range(from1, to1, tag) {
1143 this.exclusive = tag === 'exclusive';
1144 this.equals = this.exclusive ? '' : '=';
1147 Range.prototype.compileVariables = function(o) {
1148 var isComplex, ref3, ref4, ref5, ref6, step;
1152 isComplex = del(o, 'isComplex');
1153 ref3 = this.cacheToCodeFragments(this.from.cache(o, LEVEL_LIST, isComplex)), this.fromC = ref3[0], this.fromVar = ref3[1];
1154 ref4 = this.cacheToCodeFragments(this.to.cache(o, LEVEL_LIST, isComplex)), this.toC = ref4[0], this.toVar = ref4[1];
1155 if (step = del(o, 'step')) {
1156 ref5 = this.cacheToCodeFragments(step.cache(o, LEVEL_LIST, isComplex)), this.step = ref5[0], this.stepVar = ref5[1];
1158 ref6 = [this.fromVar.match(NUMBER), this.toVar.match(NUMBER)], this.fromNum = ref6[0], this.toNum = ref6[1];
1160 return this.stepNum = this.stepVar.match(NUMBER);
1164 Range.prototype.compileNode = function(o) {
1165 var cond, condPart, from, gt, idx, idxName, known, lt, namedIndex, ref3, ref4, stepPart, to, varPart;
1166 if (!this.fromVar) {
1167 this.compileVariables(o);
1170 return this.compileArray(o);
1172 known = this.fromNum && this.toNum;
1173 idx = del(o, 'index');
1174 idxName = del(o, 'name');
1175 namedIndex = idxName && idxName !== idx;
1176 varPart = idx + " = " + this.fromC;
1177 if (this.toC !== this.toVar) {
1178 varPart += ", " + this.toC;
1180 if (this.step !== this.stepVar) {
1181 varPart += ", " + this.step;
1183 ref3 = [idx + " <" + this.equals, idx + " >" + this.equals], lt = ref3[0], gt = ref3[1];
1184 condPart = this.stepNum ? parseNum(this.stepNum[0]) > 0 ? lt + " " + this.toVar : gt + " " + this.toVar : known ? ((ref4 = [parseNum(this.fromNum[0]), parseNum(this.toNum[0])], from = ref4[0], to = ref4[1], ref4), from <= to ? lt + " " + to : gt + " " + to) : (cond = this.stepVar ? this.stepVar + " > 0" : this.fromVar + " <= " + this.toVar, cond + " ? " + lt + " " + this.toVar + " : " + gt + " " + this.toVar);
1185 stepPart = this.stepVar ? idx + " += " + this.stepVar : known ? namedIndex ? from <= to ? "++" + idx : "--" + idx : from <= to ? idx + "++" : idx + "--" : namedIndex ? cond + " ? ++" + idx + " : --" + idx : cond + " ? " + idx + "++ : " + idx + "--";
1187 varPart = idxName + " = " + varPart;
1190 stepPart = idxName + " = " + stepPart;
1192 return [this.makeCode(varPart + "; " + condPart + "; " + stepPart)];
1195 Range.prototype.compileArray = function(o) {
1196 var args, body, cond, hasArgs, i, idt, j, post, pre, range, ref3, ref4, result, results, vars;
1197 if (this.fromNum && this.toNum && Math.abs(this.fromNum - this.toNum) <= 20) {
1198 range = (function() {
1200 for (var j = ref3 = +this.fromNum, ref4 = +this.toNum; ref3 <= ref4 ? j <= ref4 : j >= ref4; ref3 <= ref4 ? j++ : j--){ results.push(j); }
1203 if (this.exclusive) {
1206 return [this.makeCode("[" + (range.join(', ')) + "]")];
1208 idt = this.tab + TAB;
1209 i = o.scope.freeVariable('i', {
1212 result = o.scope.freeVariable('results');
1213 pre = "\n" + idt + result + " = [];";
1214 if (this.fromNum && this.toNum) {
1216 body = fragmentsToText(this.compileNode(o));
1218 vars = (i + " = " + this.fromC) + (this.toC !== this.toVar ? ", " + this.toC : '');
1219 cond = this.fromVar + " <= " + this.toVar;
1220 body = "var " + vars + "; " + cond + " ? " + i + " <" + this.equals + " " + this.toVar + " : " + i + " >" + this.equals + " " + this.toVar + "; " + cond + " ? " + i + "++ : " + i + "--";
1222 post = "{ " + result + ".push(" + i + "); }\n" + idt + "return " + result + ";\n" + o.indent;
1223 hasArgs = function(node) {
1224 return node != null ? node.contains(isLiteralArguments) : void 0;
1226 if (hasArgs(this.from) || hasArgs(this.to)) {
1227 args = ', arguments';
1229 return [this.makeCode("(function() {" + pre + "\n" + idt + "for (" + body + ")" + post + "}).apply(this" + (args != null ? args : '') + ")")];
1236 exports.Slice = Slice = (function(superClass1) {
1237 extend1(Slice, superClass1);
1239 Slice.prototype.children = ['range'];
1241 function Slice(range1) {
1242 this.range = range1;
1243 Slice.__super__.constructor.call(this);
1246 Slice.prototype.compileNode = function(o) {
1247 var compiled, compiledText, from, fromCompiled, ref3, to, toStr;
1248 ref3 = this.range, to = ref3.to, from = ref3.from;
1249 fromCompiled = from && from.compileToFragments(o, LEVEL_PAREN) || [this.makeCode('0')];
1251 compiled = to.compileToFragments(o, LEVEL_PAREN);
1252 compiledText = fragmentsToText(compiled);
1253 if (!(!this.range.exclusive && +compiledText === -1)) {
1254 toStr = ', ' + (this.range.exclusive ? compiledText : SIMPLENUM.test(compiledText) ? "" + (+compiledText + 1) : (compiled = to.compileToFragments(o, LEVEL_ACCESS), "+" + (fragmentsToText(compiled)) + " + 1 || 9e9"));
1257 return [this.makeCode(".slice(" + (fragmentsToText(fromCompiled)) + (toStr || '') + ")")];
1264 exports.Obj = Obj = (function(superClass1) {
1265 extend1(Obj, superClass1);
1267 function Obj(props, generated) {
1268 this.generated = generated != null ? generated : false;
1269 this.objects = this.properties = props || [];
1272 Obj.prototype.children = ['properties'];
1274 Obj.prototype.compileNode = function(o) {
1275 var answer, dynamicIndex, hasDynamic, i, idt, indent, j, join, k, key, l, lastNoncom, len1, len2, len3, node, oref, prop, props, ref3, value;
1276 props = this.properties;
1277 if (this.generated) {
1278 for (j = 0, len1 = props.length; j < len1; j++) {
1280 if (node instanceof Value) {
1281 node.error('cannot have an implicit value in an implicit object');
1285 for (dynamicIndex = k = 0, len2 = props.length; k < len2; dynamicIndex = ++k) {
1286 prop = props[dynamicIndex];
1287 if ((prop.variable || prop).base instanceof Parens) {
1291 hasDynamic = dynamicIndex < props.length;
1292 idt = o.indent += TAB;
1293 lastNoncom = this.lastNonComment(this.properties);
1296 oref = o.scope.freeVariable('obj');
1297 answer.push(this.makeCode("(\n" + idt + oref + " = "));
1299 answer.push(this.makeCode("{" + (props.length === 0 || dynamicIndex === 0 ? '}' : '\n')));
1300 for (i = l = 0, len3 = props.length; l < len3; i = ++l) {
1302 if (i === dynamicIndex) {
1304 answer.push(this.makeCode("\n" + idt + "}"));
1306 answer.push(this.makeCode(',\n'));
1308 join = i === props.length - 1 || i === dynamicIndex - 1 ? '' : prop === lastNoncom || prop instanceof Comment ? '\n' : ',\n';
1309 indent = prop instanceof Comment ? '' : idt;
1310 if (hasDynamic && i < dynamicIndex) {
1313 if (prop instanceof Assign) {
1314 if (prop.context !== 'object') {
1315 prop.operatorToken.error("unexpected " + prop.operatorToken.value);
1317 if (prop.variable instanceof Value && prop.variable.hasProperties()) {
1318 prop.variable.error('invalid object key');
1321 if (prop instanceof Value && prop["this"]) {
1322 prop = new Assign(prop.properties[0].name, prop, 'object');
1324 if (!(prop instanceof Comment)) {
1325 if (i < dynamicIndex) {
1326 if (!(prop instanceof Assign)) {
1327 prop = new Assign(prop, prop, 'object');
1329 (prop.variable.base || prop.variable).asKey = true;
1331 if (prop instanceof Assign) {
1332 key = prop.variable;
1335 ref3 = prop.base.cache(o), key = ref3[0], value = ref3[1];
1337 prop = new Assign(new Value(new Literal(oref), [new Access(key)]), value);
1341 answer.push(this.makeCode(indent));
1343 answer.push.apply(answer, prop.compileToFragments(o, LEVEL_TOP));
1345 answer.push(this.makeCode(join));
1349 answer.push(this.makeCode(",\n" + idt + oref + "\n" + this.tab + ")"));
1351 if (props.length !== 0) {
1352 answer.push(this.makeCode("\n" + this.tab + "}"));
1355 if (this.front && !hasDynamic) {
1356 return this.wrapInBraces(answer);
1362 Obj.prototype.assigns = function(name) {
1363 var j, len1, prop, ref3;
1364 ref3 = this.properties;
1365 for (j = 0, len1 = ref3.length; j < len1; j++) {
1367 if (prop.assigns(name)) {
1378 exports.Arr = Arr = (function(superClass1) {
1379 extend1(Arr, superClass1);
1381 function Arr(objs) {
1382 this.objects = objs || [];
1385 Arr.prototype.children = ['objects'];
1387 Arr.prototype.compileNode = function(o) {
1388 var answer, compiledObjs, fragments, index, j, len1, obj;
1389 if (!this.objects.length) {
1390 return [this.makeCode('[]')];
1393 answer = Splat.compileSplattedArray(o, this.objects);
1394 if (answer.length) {
1398 compiledObjs = (function() {
1399 var j, len1, ref3, results;
1400 ref3 = this.objects;
1402 for (j = 0, len1 = ref3.length; j < len1; j++) {
1404 results.push(obj.compileToFragments(o, LEVEL_LIST));
1408 for (index = j = 0, len1 = compiledObjs.length; j < len1; index = ++j) {
1409 fragments = compiledObjs[index];
1411 answer.push(this.makeCode(", "));
1413 answer.push.apply(answer, fragments);
1415 if (fragmentsToText(answer).indexOf('\n') >= 0) {
1416 answer.unshift(this.makeCode("[\n" + o.indent));
1417 answer.push(this.makeCode("\n" + this.tab + "]"));
1419 answer.unshift(this.makeCode("["));
1420 answer.push(this.makeCode("]"));
1425 Arr.prototype.assigns = function(name) {
1426 var j, len1, obj, ref3;
1427 ref3 = this.objects;
1428 for (j = 0, len1 = ref3.length; j < len1; j++) {
1430 if (obj.assigns(name)) {
1441 exports.Class = Class = (function(superClass1) {
1442 extend1(Class, superClass1);
1444 function Class(variable1, parent1, body1) {
1445 this.variable = variable1;
1446 this.parent = parent1;
1447 this.body = body1 != null ? body1 : new Block;
1448 this.boundFuncs = [];
1449 this.body.classBody = true;
1452 Class.prototype.children = ['variable', 'parent', 'body'];
1454 Class.prototype.determineName = function() {
1455 var decl, ref3, tail;
1456 if (!this.variable) {
1459 ref3 = this.variable.properties, tail = ref3[ref3.length - 1];
1460 decl = tail ? tail instanceof Access && tail.name.value : this.variable.base.value;
1461 if (indexOf.call(STRICT_PROSCRIBED, decl) >= 0) {
1462 this.variable.error("class variable name may not be " + decl);
1464 return decl && (decl = IDENTIFIER.test(decl) && decl);
1467 Class.prototype.setContext = function(name) {
1468 return this.body.traverseChildren(false, function(node) {
1469 if (node.classBody) {
1472 if (node instanceof Literal && node.value === 'this') {
1473 return node.value = name;
1474 } else if (node instanceof Code) {
1476 return node.context = name;
1482 Class.prototype.addBoundFunctions = function(o) {
1483 var bvar, j, len1, lhs, ref3;
1484 ref3 = this.boundFuncs;
1485 for (j = 0, len1 = ref3.length; j < len1; j++) {
1487 lhs = (new Value(new Literal("this"), [new Access(bvar)])).compile(o);
1488 this.ctor.body.unshift(new Literal(lhs + " = " + (utility('bind', o)) + "(" + lhs + ", this)"));
1492 Class.prototype.addProperties = function(node, name, o) {
1493 var acc, assign, base, exprs, func, props;
1494 props = node.base.properties.slice(0);
1495 exprs = (function() {
1498 while (assign = props.shift()) {
1499 if (assign instanceof Assign) {
1500 base = assign.variable.base;
1501 delete assign.context;
1502 func = assign.value;
1503 if (base.value === 'constructor') {
1505 assign.error('cannot define more than one constructor in a class');
1508 assign.error('cannot define a constructor as a bound function');
1510 if (func instanceof Code) {
1511 assign = this.ctor = func;
1513 this.externalCtor = o.classScope.freeVariable('class');
1514 assign = new Assign(new Literal(this.externalCtor), func);
1517 if (assign.variable["this"]) {
1518 func["static"] = true;
1520 acc = base.isComplex() ? new Index(base) : new Access(base);
1521 assign.variable = new Value(new Literal(name), [new Access(new Literal('prototype')), acc]);
1522 if (func instanceof Code && func.bound) {
1523 this.boundFuncs.push(base);
1529 results.push(assign);
1533 return compact(exprs);
1536 Class.prototype.walkBody = function(name, o) {
1537 return this.traverseChildren(false, (function(_this) {
1538 return function(child) {
1539 var cont, exps, i, j, len1, node, ref3;
1541 if (child instanceof Class) {
1544 if (child instanceof Block) {
1545 ref3 = exps = child.expressions;
1546 for (i = j = 0, len1 = ref3.length; j < len1; i = ++j) {
1548 if (node instanceof Assign && node.variable.looksStatic(name)) {
1549 node.value["static"] = true;
1550 } else if (node instanceof Value && node.isObject(true)) {
1552 exps[i] = _this.addProperties(node, name, o);
1555 child.expressions = exps = flatten(exps);
1557 return cont && !(child instanceof Class);
1562 Class.prototype.hoistDirectivePrologue = function() {
1563 var expressions, index, node;
1565 expressions = this.body.expressions;
1566 while ((node = expressions[index]) && node instanceof Comment || node instanceof Value && node.isString()) {
1569 return this.directives = expressions.splice(0, index);
1572 Class.prototype.ensureConstructor = function(name) {
1574 this.ctor = new Code;
1575 if (this.externalCtor) {
1576 this.ctor.body.push(new Literal(this.externalCtor + ".apply(this, arguments)"));
1577 } else if (this.parent) {
1578 this.ctor.body.push(new Literal(name + ".__super__.constructor.apply(this, arguments)"));
1580 this.ctor.body.makeReturn();
1581 this.body.expressions.unshift(this.ctor);
1583 this.ctor.ctor = this.ctor.name = name;
1584 this.ctor.klass = null;
1585 return this.ctor.noReturn = true;
1588 Class.prototype.compileNode = function(o) {
1589 var args, argumentsNode, func, jumpNode, klass, lname, name, ref3, superClass;
1590 if (jumpNode = this.body.jumps()) {
1591 jumpNode.error('Class bodies cannot contain pure statements');
1593 if (argumentsNode = this.body.contains(isLiteralArguments)) {
1594 argumentsNode.error("Class bodies shouldn't reference arguments");
1596 name = this.determineName() || '_Class';
1597 if (name.reserved) {
1600 lname = new Literal(name);
1601 func = new Code([], Block.wrap([this.body]));
1603 o.classScope = func.makeScope(o.scope);
1604 this.hoistDirectivePrologue();
1605 this.setContext(name);
1606 this.walkBody(name, o);
1607 this.ensureConstructor(name);
1608 this.addBoundFunctions(o);
1609 this.body.spaced = true;
1610 this.body.expressions.push(lname);
1612 superClass = new Literal(o.classScope.freeVariable('superClass', {
1615 this.body.expressions.unshift(new Extends(lname, superClass));
1616 func.params.push(new Param(superClass));
1617 args.push(this.parent);
1619 (ref3 = this.body.expressions).unshift.apply(ref3, this.directives);
1620 klass = new Parens(new Call(func, args));
1621 if (this.variable) {
1622 klass = new Assign(this.variable, klass);
1624 return klass.compileToFragments(o);
1631 exports.Assign = Assign = (function(superClass1) {
1632 extend1(Assign, superClass1);
1634 function Assign(variable1, value1, context, options) {
1635 var forbidden, name, ref3;
1636 this.variable = variable1;
1637 this.value = value1;
1638 this.context = context;
1639 if (options == null) {
1642 this.param = options.param, this.subpattern = options.subpattern, this.operatorToken = options.operatorToken;
1643 forbidden = (ref3 = (name = this.variable.unwrapAll().value), indexOf.call(STRICT_PROSCRIBED, ref3) >= 0);
1644 if (forbidden && this.context !== 'object') {
1645 this.variable.error("variable name may not be \"" + name + "\"");
1649 Assign.prototype.children = ['variable', 'value'];
1651 Assign.prototype.isStatement = function(o) {
1652 return (o != null ? o.level : void 0) === LEVEL_TOP && (this.context != null) && indexOf.call(this.context, "?") >= 0;
1655 Assign.prototype.assigns = function(name) {
1656 return this[this.context === 'object' ? 'value' : 'variable'].assigns(name);
1659 Assign.prototype.unfoldSoak = function(o) {
1660 return unfoldSoak(o, this, 'variable');
1663 Assign.prototype.compileNode = function(o) {
1664 var answer, compiledName, isValue, j, name, properties, prototype, ref3, ref4, ref5, ref6, ref7, val, varBase;
1665 if (isValue = this.variable instanceof Value) {
1666 if (this.variable.isArray() || this.variable.isObject()) {
1667 return this.compilePatternMatch(o);
1669 if (this.variable.isSplice()) {
1670 return this.compileSplice(o);
1672 if ((ref3 = this.context) === '||=' || ref3 === '&&=' || ref3 === '?=') {
1673 return this.compileConditional(o);
1675 if ((ref4 = this.context) === '**=' || ref4 === '//=' || ref4 === '%%=') {
1676 return this.compileSpecialMath(o);
1679 if (this.value instanceof Code) {
1680 if (this.value["static"]) {
1681 this.value.klass = this.variable.base;
1682 this.value.name = this.variable.properties[0];
1683 this.value.variable = this.variable;
1684 } else if (((ref5 = this.variable.properties) != null ? ref5.length : void 0) >= 2) {
1685 ref6 = this.variable.properties, properties = 3 <= ref6.length ? slice.call(ref6, 0, j = ref6.length - 2) : (j = 0, []), prototype = ref6[j++], name = ref6[j++];
1686 if (((ref7 = prototype.name) != null ? ref7.value : void 0) === 'prototype') {
1687 this.value.klass = new Value(this.variable.base, properties);
1688 this.value.name = name;
1689 this.value.variable = this.variable;
1693 if (!this.context) {
1694 varBase = this.variable.unwrapAll();
1695 if (!varBase.isAssignable()) {
1696 this.variable.error("\"" + (this.variable.compile(o)) + "\" cannot be assigned");
1698 if (!(typeof varBase.hasProperties === "function" ? varBase.hasProperties() : void 0)) {
1700 o.scope.add(varBase.value, 'var');
1702 o.scope.find(varBase.value);
1706 val = this.value.compileToFragments(o, LEVEL_LIST);
1707 if (isValue && this.variable.base instanceof Obj) {
1708 this.variable.front = true;
1710 compiledName = this.variable.compileToFragments(o, LEVEL_LIST);
1711 if (this.context === 'object') {
1712 return compiledName.concat(this.makeCode(": "), val);
1714 answer = compiledName.concat(this.makeCode(" " + (this.context || '=') + " "), val);
1715 if (o.level <= LEVEL_LIST) {
1718 return this.wrapInBraces(answer);
1722 Assign.prototype.compilePatternMatch = function(o) {
1723 var acc, assigns, code, defaultValue, expandedIdx, fragments, i, idx, isObject, ivar, j, len1, name, obj, objects, olen, ref, ref3, ref4, ref5, ref6, ref7, rest, top, val, value, vvar, vvarText;
1724 top = o.level === LEVEL_TOP;
1726 objects = this.variable.base.objects;
1727 if (!(olen = objects.length)) {
1728 code = value.compileToFragments(o);
1729 if (o.level >= LEVEL_OP) {
1730 return this.wrapInBraces(code);
1736 if (olen === 1 && obj instanceof Expansion) {
1737 obj.error('Destructuring assignment has no target');
1739 isObject = this.variable.isObject();
1740 if (top && olen === 1 && !(obj instanceof Splat)) {
1741 defaultValue = null;
1742 if (obj instanceof Assign && obj.context === 'object') {
1743 ref3 = obj, (ref4 = ref3.variable, idx = ref4.base), obj = ref3.value;
1744 if (obj instanceof Assign) {
1745 defaultValue = obj.value;
1749 if (obj instanceof Assign) {
1750 defaultValue = obj.value;
1753 idx = isObject ? obj["this"] ? obj.properties[0].name : obj : new Literal(0);
1755 acc = IDENTIFIER.test(idx.unwrap().value);
1756 value = new Value(value);
1757 value.properties.push(new (acc ? Access : Index)(idx));
1758 if (ref5 = obj.unwrap().value, indexOf.call(RESERVED, ref5) >= 0) {
1759 obj.error("assignment to a reserved word: " + (obj.compile(o)));
1762 value = new Op('?', value, defaultValue);
1764 return new Assign(obj, value, null, {
1766 }).compileToFragments(o, LEVEL_TOP);
1768 vvar = value.compileToFragments(o, LEVEL_LIST);
1769 vvarText = fragmentsToText(vvar);
1771 expandedIdx = false;
1772 if (!IDENTIFIER.test(vvarText) || this.variable.assigns(vvarText)) {
1773 assigns.push([this.makeCode((ref = o.scope.freeVariable('ref')) + " = ")].concat(slice.call(vvar)));
1774 vvar = [this.makeCode(ref)];
1777 for (i = j = 0, len1 = objects.length; j < len1; i = ++j) {
1780 if (!expandedIdx && obj instanceof Splat) {
1781 name = obj.name.unwrap().value;
1783 val = olen + " <= " + vvarText + ".length ? " + (utility('slice', o)) + ".call(" + vvarText + ", " + i;
1784 if (rest = olen - i - 1) {
1785 ivar = o.scope.freeVariable('i', {
1788 val += ", " + ivar + " = " + vvarText + ".length - " + rest + ") : (" + ivar + " = " + i + ", [])";
1792 val = new Literal(val);
1793 expandedIdx = ivar + "++";
1794 } else if (!expandedIdx && obj instanceof Expansion) {
1795 if (rest = olen - i - 1) {
1797 expandedIdx = vvarText + ".length - 1";
1799 ivar = o.scope.freeVariable('i', {
1802 val = new Literal(ivar + " = " + vvarText + ".length - " + rest);
1803 expandedIdx = ivar + "++";
1804 assigns.push(val.compileToFragments(o, LEVEL_LIST));
1809 if (obj instanceof Splat || obj instanceof Expansion) {
1810 obj.error("multiple splats/expansions are disallowed in an assignment");
1812 defaultValue = null;
1813 if (obj instanceof Assign && obj.context === 'object') {
1814 ref6 = obj, (ref7 = ref6.variable, idx = ref7.base), obj = ref6.value;
1815 if (obj instanceof Assign) {
1816 defaultValue = obj.value;
1820 if (obj instanceof Assign) {
1821 defaultValue = obj.value;
1824 idx = isObject ? obj["this"] ? obj.properties[0].name : obj : new Literal(expandedIdx || idx);
1826 name = obj.unwrap().value;
1827 acc = IDENTIFIER.test(idx.unwrap().value);
1828 val = new Value(new Literal(vvarText), [new (acc ? Access : Index)(idx)]);
1830 val = new Op('?', val, defaultValue);
1833 if ((name != null) && indexOf.call(RESERVED, name) >= 0) {
1834 obj.error("assignment to a reserved word: " + (obj.compile(o)));
1836 assigns.push(new Assign(obj, val, null, {
1839 }).compileToFragments(o, LEVEL_LIST));
1841 if (!(top || this.subpattern)) {
1844 fragments = this.joinFragmentArrays(assigns, ', ');
1845 if (o.level < LEVEL_LIST) {
1848 return this.wrapInBraces(fragments);
1852 Assign.prototype.compileConditional = function(o) {
1853 var fragments, left, ref3, right;
1854 ref3 = this.variable.cacheReference(o), left = ref3[0], right = ref3[1];
1855 if (!left.properties.length && left.base instanceof Literal && left.base.value !== "this" && !o.scope.check(left.base.value)) {
1856 this.variable.error("the variable \"" + left.base.value + "\" can't be assigned with " + this.context + " because it has not been declared before");
1858 if (indexOf.call(this.context, "?") >= 0) {
1859 o.isExistentialEquals = true;
1860 return new If(new Existence(left), right, {
1862 }).addElse(new Assign(right, this.value, '=')).compileToFragments(o);
1864 fragments = new Op(this.context.slice(0, -1), left, new Assign(right, this.value, '=')).compileToFragments(o);
1865 if (o.level <= LEVEL_LIST) {
1868 return this.wrapInBraces(fragments);
1873 Assign.prototype.compileSpecialMath = function(o) {
1874 var left, ref3, right;
1875 ref3 = this.variable.cacheReference(o), left = ref3[0], right = ref3[1];
1876 return new Assign(left, new Op(this.context.slice(0, -1), right, this.value)).compileToFragments(o);
1879 Assign.prototype.compileSplice = function(o) {
1880 var answer, exclusive, from, fromDecl, fromRef, name, ref3, ref4, ref5, to, valDef, valRef;
1881 ref3 = this.variable.properties.pop().range, from = ref3.from, to = ref3.to, exclusive = ref3.exclusive;
1882 name = this.variable.compile(o);
1884 ref4 = this.cacheToCodeFragments(from.cache(o, LEVEL_OP)), fromDecl = ref4[0], fromRef = ref4[1];
1886 fromDecl = fromRef = '0';
1889 if (from instanceof Value && from.isSimpleNumber() && to instanceof Value && to.isSimpleNumber()) {
1890 to = to.compile(o) - fromRef;
1895 to = to.compile(o, LEVEL_ACCESS) + ' - ' + fromRef;
1903 ref5 = this.value.cache(o, LEVEL_LIST), valDef = ref5[0], valRef = ref5[1];
1904 answer = [].concat(this.makeCode("[].splice.apply(" + name + ", [" + fromDecl + ", " + to + "].concat("), valDef, this.makeCode(")), "), valRef);
1905 if (o.level > LEVEL_TOP) {
1906 return this.wrapInBraces(answer);
1916 exports.Code = Code = (function(superClass1) {
1917 extend1(Code, superClass1);
1919 function Code(params, body, tag) {
1920 this.params = params || [];
1921 this.body = body || new Block;
1922 this.bound = tag === 'boundfunc';
1923 this.isGenerator = !!this.body.contains(function(node) {
1925 return node instanceof Op && ((ref3 = node.operator) === 'yield' || ref3 === 'yield*');
1929 Code.prototype.children = ['params', 'body'];
1931 Code.prototype.isStatement = function() {
1935 Code.prototype.jumps = NO;
1937 Code.prototype.makeScope = function(parentScope) {
1938 return new Scope(parentScope, this.body, this);
1941 Code.prototype.compileNode = function(o) {
1942 var answer, boundfunc, code, exprs, i, j, k, l, len1, len2, len3, len4, len5, len6, lit, m, p, param, params, q, r, ref, ref3, ref4, ref5, ref6, ref7, ref8, splats, uniqs, val, wasEmpty, wrapper;
1943 if (this.bound && ((ref3 = o.scope.method) != null ? ref3.bound : void 0)) {
1944 this.context = o.scope.method.context;
1946 if (this.bound && !this.context) {
1947 this.context = '_this';
1948 wrapper = new Code([new Param(new Literal(this.context))], new Block([this]));
1949 boundfunc = new Call(wrapper, [new Literal('this')]);
1950 boundfunc.updateLocationDataIfMissing(this.locationData);
1951 return boundfunc.compileNode(o);
1953 o.scope = del(o, 'classScope') || this.makeScope(o.scope);
1954 o.scope.shared = del(o, 'sharedScope');
1957 delete o.isExistentialEquals;
1961 for (j = 0, len1 = ref4.length; j < len1; j++) {
1963 if (!(param instanceof Expansion)) {
1964 o.scope.parameter(param.asReference(o));
1968 for (k = 0, len2 = ref5.length; k < len2; k++) {
1970 if (!(param.splat || param instanceof Expansion)) {
1974 for (l = 0, len3 = ref6.length; l < len3; l++) {
1976 if (!(p instanceof Expansion) && p.name.value) {
1977 o.scope.add(p.name.value, 'var', true);
1980 splats = new Assign(new Value(new Arr((function() {
1981 var len4, m, ref7, results;
1984 for (m = 0, len4 = ref7.length; m < len4; m++) {
1986 results.push(p.asReference(o));
1989 }).call(this))), new Value(new Literal('arguments')));
1993 for (m = 0, len4 = ref7.length; m < len4; m++) {
1995 if (param.isComplex()) {
1996 val = ref = param.asReference(o);
1998 val = new Op('?', ref, param.value);
2000 exprs.push(new Assign(new Value(param.name), val, '=', {
2006 lit = new Literal(ref.name.value + ' == null');
2007 val = new Assign(new Value(param.name), param.value, '=');
2008 exprs.push(new If(lit, val));
2015 wasEmpty = this.body.isEmpty();
2017 exprs.unshift(splats);
2020 (ref8 = this.body.expressions).unshift.apply(ref8, exprs);
2022 for (i = q = 0, len5 = params.length; q < len5; i = ++q) {
2024 params[i] = p.compileToFragments(o);
2025 o.scope.parameter(fragmentsToText(params[i]));
2028 this.eachParamName(function(name, node) {
2029 if (indexOf.call(uniqs, name) >= 0) {
2030 node.error("multiple parameters named " + name);
2032 return uniqs.push(name);
2034 if (!(wasEmpty || this.noReturn)) {
2035 this.body.makeReturn();
2038 if (this.isGenerator) {
2042 code += ' ' + this.name;
2045 answer = [this.makeCode(code)];
2046 for (i = r = 0, len6 = params.length; r < len6; i = ++r) {
2049 answer.push(this.makeCode(", "));
2051 answer.push.apply(answer, p);
2053 answer.push(this.makeCode(') {'));
2054 if (!this.body.isEmpty()) {
2055 answer = answer.concat(this.makeCode("\n"), this.body.compileWithDeclarations(o), this.makeCode("\n" + this.tab));
2057 answer.push(this.makeCode('}'));
2059 return [this.makeCode(this.tab)].concat(slice.call(answer));
2061 if (this.front || (o.level >= LEVEL_ACCESS)) {
2062 return this.wrapInBraces(answer);
2068 Code.prototype.eachParamName = function(iterator) {
2069 var j, len1, param, ref3, results;
2072 for (j = 0, len1 = ref3.length; j < len1; j++) {
2074 results.push(param.eachName(iterator));
2079 Code.prototype.traverseChildren = function(crossScope, func) {
2081 return Code.__super__.traverseChildren.call(this, crossScope, func);
2089 exports.Param = Param = (function(superClass1) {
2090 extend1(Param, superClass1);
2092 function Param(name1, value1, splat) {
2093 var name, ref3, token;
2095 this.value = value1;
2097 if (ref3 = (name = this.name.unwrapAll().value), indexOf.call(STRICT_PROSCRIBED, ref3) >= 0) {
2098 this.name.error("parameter name \"" + name + "\" is not allowed");
2100 if (this.name instanceof Obj && this.name.generated) {
2101 token = this.name.objects[0].operatorToken;
2102 token.error("unexpected " + token.value);
2106 Param.prototype.children = ['name', 'value'];
2108 Param.prototype.compileToFragments = function(o) {
2109 return this.name.compileToFragments(o, LEVEL_LIST);
2112 Param.prototype.asReference = function(o) {
2114 if (this.reference) {
2115 return this.reference;
2119 name = node.properties[0].name.value;
2120 if (name.reserved) {
2123 node = new Literal(o.scope.freeVariable(name));
2124 } else if (node.isComplex()) {
2125 node = new Literal(o.scope.freeVariable('arg'));
2127 node = new Value(node);
2129 node = new Splat(node);
2131 node.updateLocationDataIfMissing(this.locationData);
2132 return this.reference = node;
2135 Param.prototype.isComplex = function() {
2136 return this.name.isComplex();
2139 Param.prototype.eachName = function(iterator, name) {
2140 var atParam, j, len1, node, obj, ref3;
2144 atParam = function(obj) {
2145 return iterator("@" + obj.properties[0].name.value, obj);
2147 if (name instanceof Literal) {
2148 return iterator(name.value, name);
2150 if (name instanceof Value) {
2151 return atParam(name);
2153 ref3 = name.objects;
2154 for (j = 0, len1 = ref3.length; j < len1; j++) {
2156 if (obj instanceof Assign && (obj.context == null)) {
2159 if (obj instanceof Assign) {
2160 this.eachName(iterator, obj.value.unwrap());
2161 } else if (obj instanceof Splat) {
2162 node = obj.name.unwrap();
2163 iterator(node.value, node);
2164 } else if (obj instanceof Value) {
2165 if (obj.isArray() || obj.isObject()) {
2166 this.eachName(iterator, obj.base);
2167 } else if (obj["this"]) {
2170 iterator(obj.base.value, obj.base);
2172 } else if (!(obj instanceof Expansion)) {
2173 obj.error("illegal parameter " + (obj.compile()));
2182 exports.Splat = Splat = (function(superClass1) {
2183 extend1(Splat, superClass1);
2185 Splat.prototype.children = ['name'];
2187 Splat.prototype.isAssignable = YES;
2189 function Splat(name) {
2190 this.name = name.compile ? name : new Literal(name);
2193 Splat.prototype.assigns = function(name) {
2194 return this.name.assigns(name);
2197 Splat.prototype.compileToFragments = function(o) {
2198 return this.name.compileToFragments(o);
2201 Splat.prototype.unwrap = function() {
2205 Splat.compileSplattedArray = function(o, list, apply) {
2206 var args, base, compiledNode, concatPart, fragments, i, index, j, last, len1, node;
2208 while ((node = list[++index]) && !(node instanceof Splat)) {
2211 if (index >= list.length) {
2214 if (list.length === 1) {
2216 fragments = node.compileToFragments(o, LEVEL_LIST);
2220 return [].concat(node.makeCode((utility('slice', o)) + ".call("), fragments, node.makeCode(")"));
2222 args = list.slice(index);
2223 for (i = j = 0, len1 = args.length; j < len1; i = ++j) {
2225 compiledNode = node.compileToFragments(o, LEVEL_LIST);
2226 args[i] = node instanceof Splat ? [].concat(node.makeCode((utility('slice', o)) + ".call("), compiledNode, node.makeCode(")")) : [].concat(node.makeCode("["), compiledNode, node.makeCode("]"));
2230 concatPart = node.joinFragmentArrays(args.slice(1), ', ');
2231 return args[0].concat(node.makeCode(".concat("), concatPart, node.makeCode(")"));
2233 base = (function() {
2234 var k, len2, ref3, results;
2235 ref3 = list.slice(0, index);
2237 for (k = 0, len2 = ref3.length; k < len2; k++) {
2239 results.push(node.compileToFragments(o, LEVEL_LIST));
2243 base = list[0].joinFragmentArrays(base, ', ');
2244 concatPart = list[index].joinFragmentArrays(args, ', ');
2245 last = list[list.length - 1];
2246 return [].concat(list[0].makeCode("["), base, list[index].makeCode("].concat("), concatPart, last.makeCode(")"));
2253 exports.Expansion = Expansion = (function(superClass1) {
2254 extend1(Expansion, superClass1);
2256 function Expansion() {
2257 return Expansion.__super__.constructor.apply(this, arguments);
2260 Expansion.prototype.isComplex = NO;
2262 Expansion.prototype.compileNode = function(o) {
2263 return this.error('Expansion must be used inside a destructuring assignment or parameter list');
2266 Expansion.prototype.asReference = function(o) {
2270 Expansion.prototype.eachName = function(iterator) {};
2276 exports.While = While = (function(superClass1) {
2277 extend1(While, superClass1);
2279 function While(condition, options) {
2280 this.condition = (options != null ? options.invert : void 0) ? condition.invert() : condition;
2281 this.guard = options != null ? options.guard : void 0;
2284 While.prototype.children = ['condition', 'guard', 'body'];
2286 While.prototype.isStatement = YES;
2288 While.prototype.makeReturn = function(res) {
2290 return While.__super__.makeReturn.apply(this, arguments);
2292 this.returns = !this.jumps({
2299 While.prototype.addBody = function(body1) {
2304 While.prototype.jumps = function() {
2305 var expressions, j, jumpNode, len1, node;
2306 expressions = this.body.expressions;
2307 if (!expressions.length) {
2310 for (j = 0, len1 = expressions.length; j < len1; j++) {
2311 node = expressions[j];
2312 if (jumpNode = node.jumps({
2321 While.prototype.compileNode = function(o) {
2322 var answer, body, rvar, set;
2326 if (body.isEmpty()) {
2327 body = this.makeCode('');
2330 body.makeReturn(rvar = o.scope.freeVariable('results'));
2331 set = "" + this.tab + rvar + " = [];\n";
2334 if (body.expressions.length > 1) {
2335 body.expressions.unshift(new If((new Parens(this.guard)).invert(), new Literal("continue")));
2338 body = Block.wrap([new If(this.guard, body)]);
2342 body = [].concat(this.makeCode("\n"), body.compileToFragments(o, LEVEL_TOP), this.makeCode("\n" + this.tab));
2344 answer = [].concat(this.makeCode(set + this.tab + "while ("), this.condition.compileToFragments(o, LEVEL_PAREN), this.makeCode(") {"), body, this.makeCode("}"));
2346 answer.push(this.makeCode("\n" + this.tab + "return " + rvar + ";"));
2355 exports.Op = Op = (function(superClass1) {
2356 var CONVERSIONS, INVERSIONS;
2358 extend1(Op, superClass1);
2360 function Op(op, first, second, flip) {
2362 return new In(first, second);
2365 return this.generateDo(first);
2368 if (first instanceof Call && !first["do"] && !first.isNew) {
2369 return first.newInstance();
2371 if (first instanceof Code && first.bound || first["do"]) {
2372 first = new Parens(first);
2375 this.operator = CONVERSIONS[op] || op;
2377 this.second = second;
2386 'yieldfrom': 'yield*'
2394 Op.prototype.children = ['first', 'second'];
2396 Op.prototype.isSimpleNumber = NO;
2398 Op.prototype.isYield = function() {
2400 return (ref3 = this.operator) === 'yield' || ref3 === 'yield*';
2403 Op.prototype.isYieldReturn = function() {
2404 return this.isYield() && this.first instanceof Return;
2407 Op.prototype.isUnary = function() {
2408 return !this.second;
2411 Op.prototype.isComplex = function() {
2413 return !(this.isUnary() && ((ref3 = this.operator) === '+' || ref3 === '-') && this.first instanceof Value && this.first.isSimpleNumber());
2416 Op.prototype.isChainable = function() {
2418 return (ref3 = this.operator) === '<' || ref3 === '>' || ref3 === '>=' || ref3 === '<=' || ref3 === '===' || ref3 === '!==';
2421 Op.prototype.invert = function() {
2422 var allInvertable, curr, fst, op, ref3;
2423 if (this.isChainable() && this.first.isChainable()) {
2424 allInvertable = true;
2426 while (curr && curr.operator) {
2427 allInvertable && (allInvertable = curr.operator in INVERSIONS);
2430 if (!allInvertable) {
2431 return new Parens(this).invert();
2434 while (curr && curr.operator) {
2435 curr.invert = !curr.invert;
2436 curr.operator = INVERSIONS[curr.operator];
2440 } else if (op = INVERSIONS[this.operator]) {
2442 if (this.first.unwrap() instanceof Op) {
2443 this.first.invert();
2446 } else if (this.second) {
2447 return new Parens(this).invert();
2448 } else if (this.operator === '!' && (fst = this.first.unwrap()) instanceof Op && ((ref3 = fst.operator) === '!' || ref3 === 'in' || ref3 === 'instanceof')) {
2451 return new Op('!', this);
2455 Op.prototype.unfoldSoak = function(o) {
2457 return ((ref3 = this.operator) === '++' || ref3 === '--' || ref3 === 'delete') && unfoldSoak(o, this, 'first');
2460 Op.prototype.generateDo = function(exp) {
2461 var call, func, j, len1, param, passedParams, ref, ref3;
2463 func = exp instanceof Assign && (ref = exp.value.unwrap()) instanceof Code ? ref : exp;
2464 ref3 = func.params || [];
2465 for (j = 0, len1 = ref3.length; j < len1; j++) {
2468 passedParams.push(param.value);
2471 passedParams.push(param);
2474 call = new Call(exp, passedParams);
2479 Op.prototype.compileNode = function(o) {
2480 var answer, isChain, lhs, ref3, ref4, rhs;
2481 isChain = this.isChainable() && this.first.isChainable();
2483 this.first.front = this.front;
2485 if (this.operator === 'delete' && o.scope.check(this.first.unwrapAll().value)) {
2486 this.error('delete operand may not be argument or var');
2488 if (((ref3 = this.operator) === '--' || ref3 === '++') && (ref4 = this.first.unwrapAll().value, indexOf.call(STRICT_PROSCRIBED, ref4) >= 0)) {
2489 this.error("cannot increment/decrement \"" + (this.first.unwrapAll().value) + "\"");
2491 if (this.isYield()) {
2492 return this.compileYield(o);
2494 if (this.isUnary()) {
2495 return this.compileUnary(o);
2498 return this.compileChain(o);
2500 switch (this.operator) {
2502 return this.compileExistence(o);
2504 return this.compilePower(o);
2506 return this.compileFloorDivision(o);
2508 return this.compileModulo(o);
2510 lhs = this.first.compileToFragments(o, LEVEL_OP);
2511 rhs = this.second.compileToFragments(o, LEVEL_OP);
2512 answer = [].concat(lhs, this.makeCode(" " + this.operator + " "), rhs);
2513 if (o.level <= LEVEL_OP) {
2516 return this.wrapInBraces(answer);
2521 Op.prototype.compileChain = function(o) {
2522 var fragments, fst, ref3, shared;
2523 ref3 = this.first.second.cache(o), this.first.second = ref3[0], shared = ref3[1];
2524 fst = this.first.compileToFragments(o, LEVEL_OP);
2525 fragments = fst.concat(this.makeCode(" " + (this.invert ? '&&' : '||') + " "), shared.compileToFragments(o), this.makeCode(" " + this.operator + " "), this.second.compileToFragments(o, LEVEL_OP));
2526 return this.wrapInBraces(fragments);
2529 Op.prototype.compileExistence = function(o) {
2531 if (this.first.isComplex()) {
2532 ref = new Literal(o.scope.freeVariable('ref'));
2533 fst = new Parens(new Assign(ref, this.first));
2538 return new If(new Existence(fst), ref, {
2540 }).addElse(this.second).compileToFragments(o);
2543 Op.prototype.compileUnary = function(o) {
2544 var op, parts, plusMinus;
2547 parts.push([this.makeCode(op)]);
2548 if (op === '!' && this.first instanceof Existence) {
2549 this.first.negated = !this.first.negated;
2550 return this.first.compileToFragments(o);
2552 if (o.level >= LEVEL_ACCESS) {
2553 return (new Parens(this)).compileToFragments(o);
2555 plusMinus = op === '+' || op === '-';
2556 if ((op === 'new' || op === 'typeof' || op === 'delete') || plusMinus && this.first instanceof Op && this.first.operator === op) {
2557 parts.push([this.makeCode(' ')]);
2559 if ((plusMinus && this.first instanceof Op) || (op === 'new' && this.first.isStatement(o))) {
2560 this.first = new Parens(this.first);
2562 parts.push(this.first.compileToFragments(o, LEVEL_OP));
2566 return this.joinFragmentArrays(parts, '');
2569 Op.prototype.compileYield = function(o) {
2573 if (o.scope.parent == null) {
2574 this.error('yield statements must occur within a function generator.');
2576 if (indexOf.call(Object.keys(this.first), 'expression') >= 0 && !(this.first instanceof Throw)) {
2577 if (this.isYieldReturn()) {
2578 parts.push(this.first.compileToFragments(o, LEVEL_TOP));
2579 } else if (this.first.expression != null) {
2580 parts.push(this.first.expression.compileToFragments(o, LEVEL_OP));
2583 parts.push([this.makeCode("(" + op + " ")]);
2584 parts.push(this.first.compileToFragments(o, LEVEL_OP));
2585 parts.push([this.makeCode(")")]);
2587 return this.joinFragmentArrays(parts, '');
2590 Op.prototype.compilePower = function(o) {
2592 pow = new Value(new Literal('Math'), [new Access(new Literal('pow'))]);
2593 return new Call(pow, [this.first, this.second]).compileToFragments(o);
2596 Op.prototype.compileFloorDivision = function(o) {
2598 floor = new Value(new Literal('Math'), [new Access(new Literal('floor'))]);
2599 div = new Op('/', this.first, this.second);
2600 return new Call(floor, [div]).compileToFragments(o);
2603 Op.prototype.compileModulo = function(o) {
2605 mod = new Value(new Literal(utility('modulo', o)));
2606 return new Call(mod, [this.first, this.second]).compileToFragments(o);
2609 Op.prototype.toString = function(idt) {
2610 return Op.__super__.toString.call(this, idt, this.constructor.name + ' ' + this.operator);
2617 exports.In = In = (function(superClass1) {
2618 extend1(In, superClass1);
2620 function In(object, array) {
2621 this.object = object;
2625 In.prototype.children = ['object', 'array'];
2627 In.prototype.invert = NEGATE;
2629 In.prototype.compileNode = function(o) {
2630 var hasSplat, j, len1, obj, ref3;
2631 if (this.array instanceof Value && this.array.isArray() && this.array.base.objects.length) {
2632 ref3 = this.array.base.objects;
2633 for (j = 0, len1 = ref3.length; j < len1; j++) {
2635 if (!(obj instanceof Splat)) {
2642 return this.compileOrTest(o);
2645 return this.compileLoopTest(o);
2648 In.prototype.compileOrTest = function(o) {
2649 var cmp, cnj, i, item, j, len1, ref, ref3, ref4, ref5, sub, tests;
2650 ref3 = this.object.cache(o, LEVEL_OP), sub = ref3[0], ref = ref3[1];
2651 ref4 = this.negated ? [' !== ', ' && '] : [' === ', ' || '], cmp = ref4[0], cnj = ref4[1];
2653 ref5 = this.array.base.objects;
2654 for (i = j = 0, len1 = ref5.length; j < len1; i = ++j) {
2657 tests.push(this.makeCode(cnj));
2659 tests = tests.concat((i ? ref : sub), this.makeCode(cmp), item.compileToFragments(o, LEVEL_ACCESS));
2661 if (o.level < LEVEL_OP) {
2664 return this.wrapInBraces(tests);
2668 In.prototype.compileLoopTest = function(o) {
2669 var fragments, ref, ref3, sub;
2670 ref3 = this.object.cache(o, LEVEL_LIST), sub = ref3[0], ref = ref3[1];
2671 fragments = [].concat(this.makeCode(utility('indexOf', o) + ".call("), this.array.compileToFragments(o, LEVEL_LIST), this.makeCode(", "), ref, this.makeCode(") " + (this.negated ? '< 0' : '>= 0')));
2672 if (fragmentsToText(sub) === fragmentsToText(ref)) {
2675 fragments = sub.concat(this.makeCode(', '), fragments);
2676 if (o.level < LEVEL_LIST) {
2679 return this.wrapInBraces(fragments);
2683 In.prototype.toString = function(idt) {
2684 return In.__super__.toString.call(this, idt, this.constructor.name + (this.negated ? '!' : ''));
2691 exports.Try = Try = (function(superClass1) {
2692 extend1(Try, superClass1);
2694 function Try(attempt, errorVariable, recovery, ensure) {
2695 this.attempt = attempt;
2696 this.errorVariable = errorVariable;
2697 this.recovery = recovery;
2698 this.ensure = ensure;
2701 Try.prototype.children = ['attempt', 'recovery', 'ensure'];
2703 Try.prototype.isStatement = YES;
2705 Try.prototype.jumps = function(o) {
2707 return this.attempt.jumps(o) || ((ref3 = this.recovery) != null ? ref3.jumps(o) : void 0);
2710 Try.prototype.makeReturn = function(res) {
2712 this.attempt = this.attempt.makeReturn(res);
2714 if (this.recovery) {
2715 this.recovery = this.recovery.makeReturn(res);
2720 Try.prototype.compileNode = function(o) {
2721 var catchPart, ensurePart, generatedErrorVariableName, placeholder, tryPart;
2723 tryPart = this.attempt.compileToFragments(o, LEVEL_TOP);
2724 catchPart = this.recovery ? (generatedErrorVariableName = o.scope.freeVariable('error'), placeholder = new Literal(generatedErrorVariableName), 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 (" + generatedErrorVariableName + ") {}")] : [];
2725 ensurePart = this.ensure ? [].concat(this.makeCode(" finally {\n"), this.ensure.compileToFragments(o, LEVEL_TOP), this.makeCode("\n" + this.tab + "}")) : [];
2726 return [].concat(this.makeCode(this.tab + "try {\n"), tryPart, this.makeCode("\n" + this.tab + "}"), catchPart, ensurePart);
2733 exports.Throw = Throw = (function(superClass1) {
2734 extend1(Throw, superClass1);
2736 function Throw(expression) {
2737 this.expression = expression;
2740 Throw.prototype.children = ['expression'];
2742 Throw.prototype.isStatement = YES;
2744 Throw.prototype.jumps = NO;
2746 Throw.prototype.makeReturn = THIS;
2748 Throw.prototype.compileNode = function(o) {
2749 return [].concat(this.makeCode(this.tab + "throw "), this.expression.compileToFragments(o), this.makeCode(";"));
2756 exports.Existence = Existence = (function(superClass1) {
2757 extend1(Existence, superClass1);
2759 function Existence(expression) {
2760 this.expression = expression;
2763 Existence.prototype.children = ['expression'];
2765 Existence.prototype.invert = NEGATE;
2767 Existence.prototype.compileNode = function(o) {
2768 var cmp, cnj, code, ref3;
2769 this.expression.front = this.front;
2770 code = this.expression.compile(o, LEVEL_OP);
2771 if (IDENTIFIER.test(code) && !o.scope.check(code)) {
2772 ref3 = this.negated ? ['===', '||'] : ['!==', '&&'], cmp = ref3[0], cnj = ref3[1];
2773 code = "typeof " + code + " " + cmp + " \"undefined\" " + cnj + " " + code + " " + cmp + " null";
2775 code = code + " " + (this.negated ? '==' : '!=') + " null";
2777 return [this.makeCode(o.level <= LEVEL_COND ? code : "(" + code + ")")];
2784 exports.Parens = Parens = (function(superClass1) {
2785 extend1(Parens, superClass1);
2787 function Parens(body1) {
2791 Parens.prototype.children = ['body'];
2793 Parens.prototype.unwrap = function() {
2797 Parens.prototype.isComplex = function() {
2798 return this.body.isComplex();
2801 Parens.prototype.compileNode = function(o) {
2802 var bare, expr, fragments;
2803 expr = this.body.unwrap();
2804 if (expr instanceof Value && expr.isAtomic()) {
2805 expr.front = this.front;
2806 return expr.compileToFragments(o);
2808 fragments = expr.compileToFragments(o, LEVEL_PAREN);
2809 bare = o.level < LEVEL_OP && (expr instanceof Op || expr instanceof Call || (expr instanceof For && expr.returns));
2813 return this.wrapInBraces(fragments);
2821 exports.For = For = (function(superClass1) {
2822 extend1(For, superClass1);
2824 function For(body, source) {
2826 this.source = source.source, this.guard = source.guard, this.step = source.step, this.name = source.name, this.index = source.index;
2827 this.body = Block.wrap([body]);
2828 this.own = !!source.own;
2829 this.object = !!source.object;
2831 ref3 = [this.index, this.name], this.name = ref3[0], this.index = ref3[1];
2833 if (this.index instanceof Value) {
2834 this.index.error('index cannot be a pattern matching expression');
2836 this.range = this.source instanceof Value && this.source.base instanceof Range && !this.source.properties.length;
2837 this.pattern = this.name instanceof Value;
2838 if (this.range && this.index) {
2839 this.index.error('indexes do not apply to range loops');
2841 if (this.range && this.pattern) {
2842 this.name.error('cannot pattern match over range loops');
2844 if (this.own && !this.object) {
2845 this.name.error('cannot use own with for-in');
2847 this.returns = false;
2850 For.prototype.children = ['body', 'source', 'guard', 'step'];
2852 For.prototype.compileNode = function(o) {
2853 var body, bodyFragments, compare, compareDown, declare, declareDown, defPart, defPartFragments, down, forPartFragments, guardPart, idt1, increment, index, ivar, kvar, kvarAssign, last, lvar, name, namePart, ref, ref3, ref4, resultPart, returnResult, rvar, scope, source, step, stepNum, stepVar, svar, varPart;
2854 body = Block.wrap([this.body]);
2855 ref3 = body.expressions, last = ref3[ref3.length - 1];
2856 if ((last != null ? last.jumps() : void 0) instanceof Return) {
2857 this.returns = false;
2859 source = this.range ? this.source.base : this.source;
2861 if (!this.pattern) {
2862 name = this.name && (this.name.compile(o, LEVEL_LIST));
2864 index = this.index && (this.index.compile(o, LEVEL_LIST));
2865 if (name && !this.pattern) {
2872 rvar = scope.freeVariable('results');
2874 ivar = (this.object && index) || scope.freeVariable('i', {
2877 kvar = (this.range && name) || index || ivar;
2878 kvarAssign = kvar !== ivar ? kvar + " = " : "";
2879 if (this.step && !this.range) {
2880 ref4 = this.cacheToCodeFragments(this.step.cache(o, LEVEL_LIST, isComplexOrAssignable)), step = ref4[0], stepVar = ref4[1];
2881 stepNum = stepVar.match(NUMBER);
2889 idt1 = this.tab + TAB;
2891 forPartFragments = source.compileToFragments(merge(o, {
2895 isComplex: isComplexOrAssignable
2898 svar = this.source.compile(o, LEVEL_LIST);
2899 if ((name || this.own) && !IDENTIFIER.test(svar)) {
2900 defPart += "" + this.tab + (ref = scope.freeVariable('ref')) + " = " + svar + ";\n";
2903 if (name && !this.pattern) {
2904 namePart = name + " = " + svar + "[" + kvar + "]";
2907 if (step !== stepVar) {
2908 defPart += "" + this.tab + step + ";\n";
2910 if (!(this.step && stepNum && (down = parseNum(stepNum[0]) < 0))) {
2911 lvar = scope.freeVariable('len');
2913 declare = "" + kvarAssign + ivar + " = 0, " + lvar + " = " + svar + ".length";
2914 declareDown = "" + kvarAssign + ivar + " = " + svar + ".length - 1";
2915 compare = ivar + " < " + lvar;
2916 compareDown = ivar + " >= 0";
2920 compare = compareDown;
2921 declare = declareDown;
2924 compare = stepVar + " > 0 ? " + compare + " : " + compareDown;
2925 declare = "(" + stepVar + " > 0 ? (" + declare + ") : " + declareDown + ")";
2927 increment = ivar + " += " + stepVar;
2929 increment = "" + (kvar !== ivar ? "++" + ivar : ivar + "++");
2931 forPartFragments = [this.makeCode(declare + "; " + compare + "; " + kvarAssign + increment)];
2935 resultPart = "" + this.tab + rvar + " = [];\n";
2936 returnResult = "\n" + this.tab + "return " + rvar + ";";
2937 body.makeReturn(rvar);
2940 if (body.expressions.length > 1) {
2941 body.expressions.unshift(new If((new Parens(this.guard)).invert(), new Literal("continue")));
2944 body = Block.wrap([new If(this.guard, body)]);
2949 body.expressions.unshift(new Assign(this.name, new Literal(svar + "[" + kvar + "]")));
2951 defPartFragments = [].concat(this.makeCode(defPart), this.pluckDirectCall(o, body));
2953 varPart = "\n" + idt1 + namePart + ";";
2956 forPartFragments = [this.makeCode(kvar + " in " + svar)];
2958 guardPart = "\n" + idt1 + "if (!" + (utility('hasProp', o)) + ".call(" + svar + ", " + kvar + ")) continue;";
2961 bodyFragments = body.compileToFragments(merge(o, {
2964 if (bodyFragments && (bodyFragments.length > 0)) {
2965 bodyFragments = [].concat(this.makeCode("\n"), bodyFragments, this.makeCode("\n"));
2967 return [].concat(defPartFragments, this.makeCode("" + (resultPart || '') + this.tab + "for ("), forPartFragments, this.makeCode(") {" + guardPart + varPart), bodyFragments, this.makeCode(this.tab + "}" + (returnResult || '')));
2970 For.prototype.pluckDirectCall = function(o, body) {
2971 var base, defs, expr, fn, idx, j, len1, ref, ref3, ref4, ref5, ref6, ref7, ref8, ref9, val;
2973 ref3 = body.expressions;
2974 for (idx = j = 0, len1 = ref3.length; j < len1; idx = ++j) {
2976 expr = expr.unwrapAll();
2977 if (!(expr instanceof Call)) {
2980 val = (ref4 = expr.variable) != null ? ref4.unwrapAll() : void 0;
2981 if (!((val instanceof Code) || (val instanceof Value && ((ref5 = val.base) != null ? ref5.unwrapAll() : void 0) instanceof Code && val.properties.length === 1 && ((ref6 = (ref7 = val.properties[0].name) != null ? ref7.value : void 0) === 'call' || ref6 === 'apply')))) {
2984 fn = ((ref8 = val.base) != null ? ref8.unwrapAll() : void 0) || val;
2985 ref = new Literal(o.scope.freeVariable('fn'));
2986 base = new Value(ref);
2988 ref9 = [base, val], val.base = ref9[0], base = ref9[1];
2990 body.expressions[idx] = new Call(base, expr.args);
2991 defs = defs.concat(this.makeCode(this.tab), new Assign(ref, fn).compileToFragments(o, LEVEL_TOP), this.makeCode(';\n'));
3000 exports.Switch = Switch = (function(superClass1) {
3001 extend1(Switch, superClass1);
3003 function Switch(subject, cases, otherwise) {
3004 this.subject = subject;
3006 this.otherwise = otherwise;
3009 Switch.prototype.children = ['subject', 'cases', 'otherwise'];
3011 Switch.prototype.isStatement = YES;
3013 Switch.prototype.jumps = function(o) {
3014 var block, conds, j, jumpNode, len1, ref3, ref4, ref5;
3021 for (j = 0, len1 = ref3.length; j < len1; j++) {
3022 ref4 = ref3[j], conds = ref4[0], block = ref4[1];
3023 if (jumpNode = block.jumps(o)) {
3027 return (ref5 = this.otherwise) != null ? ref5.jumps(o) : void 0;
3030 Switch.prototype.makeReturn = function(res) {
3031 var j, len1, pair, ref3, ref4;
3033 for (j = 0, len1 = ref3.length; j < len1; j++) {
3035 pair[1].makeReturn(res);
3038 this.otherwise || (this.otherwise = new Block([new Literal('void 0')]));
3040 if ((ref4 = this.otherwise) != null) {
3041 ref4.makeReturn(res);
3046 Switch.prototype.compileNode = function(o) {
3047 var block, body, cond, conditions, expr, fragments, i, idt1, idt2, j, k, len1, len2, ref3, ref4, ref5;
3048 idt1 = o.indent + TAB;
3049 idt2 = o.indent = idt1 + TAB;
3050 fragments = [].concat(this.makeCode(this.tab + "switch ("), (this.subject ? this.subject.compileToFragments(o, LEVEL_PAREN) : this.makeCode("false")), this.makeCode(") {\n"));
3052 for (i = j = 0, len1 = ref3.length; j < len1; i = ++j) {
3053 ref4 = ref3[i], conditions = ref4[0], block = ref4[1];
3054 ref5 = flatten([conditions]);
3055 for (k = 0, len2 = ref5.length; k < len2; k++) {
3057 if (!this.subject) {
3058 cond = cond.invert();
3060 fragments = fragments.concat(this.makeCode(idt1 + "case "), cond.compileToFragments(o, LEVEL_PAREN), this.makeCode(":\n"));
3062 if ((body = block.compileToFragments(o, LEVEL_TOP)).length > 0) {
3063 fragments = fragments.concat(body, this.makeCode('\n'));
3065 if (i === this.cases.length - 1 && !this.otherwise) {
3068 expr = this.lastNonComment(block.expressions);
3069 if (expr instanceof Return || (expr instanceof Literal && expr.jumps() && expr.value !== 'debugger')) {
3072 fragments.push(cond.makeCode(idt2 + 'break;\n'));
3074 if (this.otherwise && this.otherwise.expressions.length) {
3075 fragments.push.apply(fragments, [this.makeCode(idt1 + "default:\n")].concat(slice.call(this.otherwise.compileToFragments(o, LEVEL_TOP)), [this.makeCode("\n")]));
3077 fragments.push(this.makeCode(this.tab + '}'));
3085 exports.If = If = (function(superClass1) {
3086 extend1(If, superClass1);
3088 function If(condition, body1, options) {
3090 if (options == null) {
3093 this.condition = options.type === 'unless' ? condition.invert() : condition;
3094 this.elseBody = null;
3095 this.isChain = false;
3096 this.soak = options.soak;
3099 If.prototype.children = ['condition', 'body', 'elseBody'];
3101 If.prototype.bodyNode = function() {
3103 return (ref3 = this.body) != null ? ref3.unwrap() : void 0;
3106 If.prototype.elseBodyNode = function() {
3108 return (ref3 = this.elseBody) != null ? ref3.unwrap() : void 0;
3111 If.prototype.addElse = function(elseBody) {
3113 this.elseBodyNode().addElse(elseBody);
3115 this.isChain = elseBody instanceof If;
3116 this.elseBody = this.ensureBlock(elseBody);
3117 this.elseBody.updateLocationDataIfMissing(elseBody.locationData);
3122 If.prototype.isStatement = function(o) {
3124 return (o != null ? o.level : void 0) === LEVEL_TOP || this.bodyNode().isStatement(o) || ((ref3 = this.elseBodyNode()) != null ? ref3.isStatement(o) : void 0);
3127 If.prototype.jumps = function(o) {
3129 return this.body.jumps(o) || ((ref3 = this.elseBody) != null ? ref3.jumps(o) : void 0);
3132 If.prototype.compileNode = function(o) {
3133 if (this.isStatement(o)) {
3134 return this.compileStatement(o);
3136 return this.compileExpression(o);
3140 If.prototype.makeReturn = function(res) {
3142 this.elseBody || (this.elseBody = new Block([new Literal('void 0')]));
3144 this.body && (this.body = new Block([this.body.makeReturn(res)]));
3145 this.elseBody && (this.elseBody = new Block([this.elseBody.makeReturn(res)]));
3149 If.prototype.ensureBlock = function(node) {
3150 if (node instanceof Block) {
3153 return new Block([node]);
3157 If.prototype.compileStatement = function(o) {
3158 var answer, body, child, cond, exeq, ifPart, indent;
3159 child = del(o, 'chainChild');
3160 exeq = del(o, 'isExistentialEquals');
3162 return new If(this.condition.invert(), this.elseBodyNode(), {
3164 }).compileToFragments(o);
3166 indent = o.indent + TAB;
3167 cond = this.condition.compileToFragments(o, LEVEL_PAREN);
3168 body = this.ensureBlock(this.body).compileToFragments(merge(o, {
3171 ifPart = [].concat(this.makeCode("if ("), cond, this.makeCode(") {\n"), body, this.makeCode("\n" + this.tab + "}"));
3173 ifPart.unshift(this.makeCode(this.tab));
3175 if (!this.elseBody) {
3178 answer = ifPart.concat(this.makeCode(' else '));
3180 o.chainChild = true;
3181 answer = answer.concat(this.elseBody.unwrap().compileToFragments(o, LEVEL_TOP));
3183 answer = answer.concat(this.makeCode("{\n"), this.elseBody.compileToFragments(merge(o, {
3185 }), LEVEL_TOP), this.makeCode("\n" + this.tab + "}"));
3190 If.prototype.compileExpression = function(o) {
3191 var alt, body, cond, fragments;
3192 cond = this.condition.compileToFragments(o, LEVEL_COND);
3193 body = this.bodyNode().compileToFragments(o, LEVEL_LIST);
3194 alt = this.elseBodyNode() ? this.elseBodyNode().compileToFragments(o, LEVEL_LIST) : [this.makeCode('void 0')];
3195 fragments = cond.concat(this.makeCode(" ? "), body, this.makeCode(" : "), alt);
3196 if (o.level >= LEVEL_COND) {
3197 return this.wrapInBraces(fragments);
3203 If.prototype.unfoldSoak = function() {
3204 return this.soak && this;
3212 extend: function(o) {
3213 return "function(child, parent) { for (var key in parent) { if (" + (utility('hasProp', o)) + ".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; }";
3216 return 'function(fn, me){ return function(){ return fn.apply(me, arguments); }; }';
3218 indexOf: function() {
3219 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; }";
3221 modulo: function() {
3222 return "function(a, b) { return (+a % (b = +b) + b) % b; }";
3224 hasProp: function() {
3225 return '{}.hasOwnProperty';
3246 IDENTIFIER = /^(?!\d)[$\w\x7f-\uffff]+$/;
3248 SIMPLENUM = /^[+-]?\d+$/;
3250 HEXNUM = /^[+-]?0x[\da-f]+/i;
3252 NUMBER = /^[+-]?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)$/i;
3254 IS_STRING = /^['"]/;
3258 utility = function(name, o) {
3260 root = o.scope.root;
3261 if (name in root.utilities) {
3262 return root.utilities[name];
3264 ref = root.freeVariable(name);
3265 root.assign(ref, UTILITIES[name](o));
3266 return root.utilities[name] = ref;
3270 multident = function(code, tab) {
3271 code = code.replace(/\n/g, '$&' + tab);
3272 return code.replace(/\s+$/, '');
3275 parseNum = function(x) {
3278 } else if (x.match(HEXNUM)) {
3279 return parseInt(x, 16);
3281 return parseFloat(x);
3285 isLiteralArguments = function(node) {
3286 return node instanceof Literal && node.value === 'arguments' && !node.asKey;
3289 isLiteralThis = function(node) {
3290 return (node instanceof Literal && node.value === 'this' && !node.asKey) || (node instanceof Code && node.bound) || (node instanceof Call && node.isSuper);
3293 isComplexOrAssignable = function(node) {
3294 return node.isComplex() || (typeof node.isAssignable === "function" ? node.isAssignable() : void 0);
3297 unfoldSoak = function(o, parent, name) {
3299 if (!(ifn = parent[name].unfoldSoak(o))) {
3302 parent[name] = ifn.body;
3303 ifn.body = new Value(parent);