]> git.r.bdr.sh - rbdr/dotfiles/blob
52c99a9f8a376c40f6ec6e78522a0bdc5691807c
[rbdr/dotfiles] /
1 // Generated by CoffeeScript 1.8.0
2 (function() {
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; },
7 __slice = [].slice;
8
9 Error.stackTraceLimit = Infinity;
10
11 Scope = require('./scope').Scope;
12
13 _ref = require('./lexer'), RESERVED = _ref.RESERVED, STRICT_PROSCRIBED = _ref.STRICT_PROSCRIBED;
14
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;
16
17 exports.extend = extend;
18
19 exports.addLocationDataFn = addLocationDataFn;
20
21 YES = function() {
22 return true;
23 };
24
25 NO = function() {
26 return false;
27 };
28
29 THIS = function() {
30 return this;
31 };
32
33 NEGATE = function() {
34 this.negated = !this.negated;
35 return this;
36 };
37
38 exports.CodeFragment = CodeFragment = (function() {
39 function CodeFragment(parent, code) {
40 var _ref2;
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';
44 }
45
46 CodeFragment.prototype.toString = function() {
47 return "" + this.code + (this.locationData ? ": " + locationDataToString(this.locationData) : '');
48 };
49
50 return CodeFragment;
51
52 })();
53
54 fragmentsToText = function(fragments) {
55 var fragment;
56 return ((function() {
57 var _i, _len, _results;
58 _results = [];
59 for (_i = 0, _len = fragments.length; _i < _len; _i++) {
60 fragment = fragments[_i];
61 _results.push(fragment.code);
62 }
63 return _results;
64 })()).join('');
65 };
66
67 exports.Base = Base = (function() {
68 function Base() {}
69
70 Base.prototype.compile = function(o, lvl) {
71 return fragmentsToText(this.compileToFragments(o, lvl));
72 };
73
74 Base.prototype.compileToFragments = function(o, lvl) {
75 var node;
76 o = extend({}, o);
77 if (lvl) {
78 o.level = lvl;
79 }
80 node = this.unfoldSoak(o) || this;
81 node.tab = o.indent;
82 if (o.level === LEVEL_TOP || !node.isStatement(o)) {
83 return node.compileNode(o);
84 } else {
85 return node.compileClosure(o);
86 }
87 };
88
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');
93 }
94 o.sharedScope = true;
95 func = new Code([], Block.wrap([this]));
96 args = [];
97 if ((argumentsNode = this.contains(isLiteralArguments)) || this.contains(isLiteralThis)) {
98 args = [new Literal('this')];
99 if (argumentsNode) {
100 meth = 'apply';
101 args.push(new Literal('arguments'));
102 } else {
103 meth = 'call';
104 }
105 func = new Value(func, [new Access(new Literal(meth))]);
106 }
107 return (new Call(func, args)).compileNode(o);
108 };
109
110 Base.prototype.cache = function(o, level, reused) {
111 var ref, sub;
112 if (!this.isComplex()) {
113 ref = level ? this.compileToFragments(o, level) : this;
114 return [ref, ref];
115 } else {
116 ref = new Literal(reused || o.scope.freeVariable('ref'));
117 sub = new Assign(ref, this);
118 if (level) {
119 return [sub.compileToFragments(o, level), [this.makeCode(ref.value)]];
120 } else {
121 return [sub, ref];
122 }
123 }
124 };
125
126 Base.prototype.cacheToCodeFragments = function(cacheValues) {
127 return [fragmentsToText(cacheValues[0]), fragmentsToText(cacheValues[1])];
128 };
129
130 Base.prototype.makeReturn = function(res) {
131 var me;
132 me = this.unwrapAll();
133 if (res) {
134 return new Call(new Literal("" + res + ".push"), [me]);
135 } else {
136 return new Return(me);
137 }
138 };
139
140 Base.prototype.contains = function(pred) {
141 var node;
142 node = void 0;
143 this.traverseChildren(false, function(n) {
144 if (pred(n)) {
145 node = n;
146 return false;
147 }
148 });
149 return node;
150 };
151
152 Base.prototype.lastNonComment = function(list) {
153 var i;
154 i = list.length;
155 while (i--) {
156 if (!(list[i] instanceof Comment)) {
157 return list[i];
158 }
159 }
160 return null;
161 };
162
163 Base.prototype.toString = function(idt, name) {
164 var tree;
165 if (idt == null) {
166 idt = '';
167 }
168 if (name == null) {
169 name = this.constructor.name;
170 }
171 tree = '\n' + idt + name;
172 if (this.soak) {
173 tree += '?';
174 }
175 this.eachChild(function(node) {
176 return tree += node.toString(idt + TAB);
177 });
178 return tree;
179 };
180
181 Base.prototype.eachChild = function(func) {
182 var attr, child, _i, _j, _len, _len1, _ref2, _ref3;
183 if (!this.children) {
184 return this;
185 }
186 _ref2 = this.children;
187 for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
188 attr = _ref2[_i];
189 if (this[attr]) {
190 _ref3 = flatten([this[attr]]);
191 for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) {
192 child = _ref3[_j];
193 if (func(child) === false) {
194 return this;
195 }
196 }
197 }
198 }
199 return this;
200 };
201
202 Base.prototype.traverseChildren = function(crossScope, func) {
203 return this.eachChild(function(child) {
204 var recur;
205 recur = func(child);
206 if (recur !== false) {
207 return child.traverseChildren(crossScope, func);
208 }
209 });
210 };
211
212 Base.prototype.invert = function() {
213 return new Op('!', this);
214 };
215
216 Base.prototype.unwrapAll = function() {
217 var node;
218 node = this;
219 while (node !== (node = node.unwrap())) {
220 continue;
221 }
222 return node;
223 };
224
225 Base.prototype.children = [];
226
227 Base.prototype.isStatement = NO;
228
229 Base.prototype.jumps = NO;
230
231 Base.prototype.isComplex = YES;
232
233 Base.prototype.isChainable = NO;
234
235 Base.prototype.isAssignable = NO;
236
237 Base.prototype.unwrap = THIS;
238
239 Base.prototype.unfoldSoak = NO;
240
241 Base.prototype.assigns = NO;
242
243 Base.prototype.updateLocationDataIfMissing = function(locationData) {
244 if (this.locationData) {
245 return this;
246 }
247 this.locationData = locationData;
248 return this.eachChild(function(child) {
249 return child.updateLocationDataIfMissing(locationData);
250 });
251 };
252
253 Base.prototype.error = function(message) {
254 return throwSyntaxError(message, this.locationData);
255 };
256
257 Base.prototype.makeCode = function(code) {
258 return new CodeFragment(this, code);
259 };
260
261 Base.prototype.wrapInBraces = function(fragments) {
262 return [].concat(this.makeCode('('), fragments, this.makeCode(')'));
263 };
264
265 Base.prototype.joinFragmentArrays = function(fragmentsList, joinStr) {
266 var answer, fragments, i, _i, _len;
267 answer = [];
268 for (i = _i = 0, _len = fragmentsList.length; _i < _len; i = ++_i) {
269 fragments = fragmentsList[i];
270 if (i) {
271 answer.push(this.makeCode(joinStr));
272 }
273 answer = answer.concat(fragments);
274 }
275 return answer;
276 };
277
278 return Base;
279
280 })();
281
282 exports.Block = Block = (function(_super) {
283 __extends(Block, _super);
284
285 function Block(nodes) {
286 this.expressions = compact(flatten(nodes || []));
287 }
288
289 Block.prototype.children = ['expressions'];
290
291 Block.prototype.push = function(node) {
292 this.expressions.push(node);
293 return this;
294 };
295
296 Block.prototype.pop = function() {
297 return this.expressions.pop();
298 };
299
300 Block.prototype.unshift = function(node) {
301 this.expressions.unshift(node);
302 return this;
303 };
304
305 Block.prototype.unwrap = function() {
306 if (this.expressions.length === 1) {
307 return this.expressions[0];
308 } else {
309 return this;
310 }
311 };
312
313 Block.prototype.isEmpty = function() {
314 return !this.expressions.length;
315 };
316
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++) {
321 exp = _ref2[_i];
322 if (exp.isStatement(o)) {
323 return true;
324 }
325 }
326 return false;
327 };
328
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++) {
333 exp = _ref2[_i];
334 if (jumpNode = exp.jumps(o)) {
335 return jumpNode;
336 }
337 }
338 };
339
340 Block.prototype.makeReturn = function(res) {
341 var expr, len;
342 len = this.expressions.length;
343 while (len--) {
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);
349 }
350 break;
351 }
352 }
353 return this;
354 };
355
356 Block.prototype.compileToFragments = function(o, level) {
357 if (o == null) {
358 o = {};
359 }
360 if (o.scope) {
361 return Block.__super__.compileToFragments.call(this, o, level);
362 } else {
363 return this.compileRoot(o);
364 }
365 };
366
367 Block.prototype.compileNode = function(o) {
368 var answer, compiledNodes, fragments, index, node, top, _i, _len, _ref2;
369 this.tab = o.indent;
370 top = o.level === LEVEL_TOP;
371 compiledNodes = [];
372 _ref2 = this.expressions;
373 for (index = _i = 0, _len = _ref2.length; _i < _len; index = ++_i) {
374 node = _ref2[index];
375 node = node.unwrapAll();
376 node = node.unfoldSoak(o) || node;
377 if (node instanceof Block) {
378 compiledNodes.push(node.compileNode(o));
379 } else if (top) {
380 node.front = true;
381 fragments = node.compileToFragments(o);
382 if (!node.isStatement(o)) {
383 fragments.unshift(this.makeCode("" + this.tab));
384 fragments.push(this.makeCode(";"));
385 }
386 compiledNodes.push(fragments);
387 } else {
388 compiledNodes.push(node.compileToFragments(o, LEVEL_LIST));
389 }
390 }
391 if (top) {
392 if (this.spaced) {
393 return [].concat(this.joinFragmentArrays(compiledNodes, '\n\n'), this.makeCode("\n"));
394 } else {
395 return this.joinFragmentArrays(compiledNodes, '\n');
396 }
397 }
398 if (compiledNodes.length) {
399 answer = this.joinFragmentArrays(compiledNodes, ', ');
400 } else {
401 answer = [this.makeCode("void 0")];
402 }
403 if (compiledNodes.length > 1 && o.level >= LEVEL_LIST) {
404 return this.wrapInBraces(answer);
405 } else {
406 return answer;
407 }
408 };
409
410 Block.prototype.compileRoot = function(o) {
411 var exp, fragments, i, name, prelude, preludeExps, rest, _i, _len, _ref2;
412 o.indent = o.bare ? '' : TAB;
413 o.level = LEVEL_TOP;
414 this.spaced = true;
415 o.scope = new Scope(null, this, null);
416 _ref2 = o.locals || [];
417 for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
418 name = _ref2[_i];
419 o.scope.parameter(name);
420 }
421 prelude = [];
422 if (!o.bare) {
423 preludeExps = (function() {
424 var _j, _len1, _ref3, _results;
425 _ref3 = this.expressions;
426 _results = [];
427 for (i = _j = 0, _len1 = _ref3.length; _j < _len1; i = ++_j) {
428 exp = _ref3[i];
429 if (!(exp.unwrap() instanceof Comment)) {
430 break;
431 }
432 _results.push(exp);
433 }
434 return _results;
435 }).call(this);
436 rest = this.expressions.slice(preludeExps.length);
437 this.expressions = preludeExps;
438 if (preludeExps.length) {
439 prelude = this.compileNode(merge(o, {
440 indent: ''
441 }));
442 prelude.push(this.makeCode("\n"));
443 }
444 this.expressions = rest;
445 }
446 fragments = this.compileWithDeclarations(o);
447 if (o.bare) {
448 return fragments;
449 }
450 return [].concat(prelude, this.makeCode("(function() {\n"), fragments, this.makeCode("\n}).call(this);\n"));
451 };
452
453 Block.prototype.compileWithDeclarations = function(o) {
454 var assigns, declars, exp, fragments, i, post, rest, scope, spaced, _i, _len, _ref2, _ref3, _ref4;
455 fragments = [];
456 post = [];
457 _ref2 = this.expressions;
458 for (i = _i = 0, _len = _ref2.length; _i < _len; i = ++_i) {
459 exp = _ref2[i];
460 exp = exp.unwrap();
461 if (!(exp instanceof Comment || exp instanceof Literal)) {
462 break;
463 }
464 }
465 o = merge(o, {
466 level: LEVEL_TOP
467 });
468 if (i) {
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;
473 }
474 post = this.compileNode(o);
475 scope = o.scope;
476 if (scope.expressions === this) {
477 declars = o.scope.hasDeclarations();
478 assigns = scope.hasAssignments;
479 if (declars || assigns) {
480 if (i) {
481 fragments.push(this.makeCode('\n'));
482 }
483 fragments.push(this.makeCode("" + this.tab + "var "));
484 if (declars) {
485 fragments.push(this.makeCode(scope.declaredVariables().join(', ')));
486 }
487 if (assigns) {
488 if (declars) {
489 fragments.push(this.makeCode(",\n" + (this.tab + TAB)));
490 }
491 fragments.push(this.makeCode(scope.assignedVariables().join(",\n" + (this.tab + TAB))));
492 }
493 fragments.push(this.makeCode(";\n" + (this.spaced ? '\n' : '')));
494 } else if (fragments.length && post.length) {
495 fragments.push(this.makeCode("\n"));
496 }
497 }
498 return fragments.concat(post);
499 };
500
501 Block.wrap = function(nodes) {
502 if (nodes.length === 1 && nodes[0] instanceof Block) {
503 return nodes[0];
504 }
505 return new Block(nodes);
506 };
507
508 return Block;
509
510 })(Base);
511
512 exports.Literal = Literal = (function(_super) {
513 __extends(Literal, _super);
514
515 function Literal(value) {
516 this.value = value;
517 }
518
519 Literal.prototype.makeReturn = function() {
520 if (this.isStatement()) {
521 return this;
522 } else {
523 return Literal.__super__.makeReturn.apply(this, arguments);
524 }
525 };
526
527 Literal.prototype.isAssignable = function() {
528 return IDENTIFIER.test(this.value);
529 };
530
531 Literal.prototype.isStatement = function() {
532 var _ref2;
533 return (_ref2 = this.value) === 'break' || _ref2 === 'continue' || _ref2 === 'debugger';
534 };
535
536 Literal.prototype.isComplex = NO;
537
538 Literal.prototype.assigns = function(name) {
539 return name === this.value;
540 };
541
542 Literal.prototype.jumps = function(o) {
543 if (this.value === 'break' && !((o != null ? o.loop : void 0) || (o != null ? o.block : void 0))) {
544 return this;
545 }
546 if (this.value === 'continue' && !(o != null ? o.loop : void 0)) {
547 return this;
548 }
549 };
550
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)];
556 };
557
558 Literal.prototype.toString = function() {
559 return ' "' + this.value + '"';
560 };
561
562 return Literal;
563
564 })(Base);
565
566 exports.Undefined = (function(_super) {
567 __extends(Undefined, _super);
568
569 function Undefined() {
570 return Undefined.__super__.constructor.apply(this, arguments);
571 }
572
573 Undefined.prototype.isAssignable = NO;
574
575 Undefined.prototype.isComplex = NO;
576
577 Undefined.prototype.compileNode = function(o) {
578 return [this.makeCode(o.level >= LEVEL_ACCESS ? '(void 0)' : 'void 0')];
579 };
580
581 return Undefined;
582
583 })(Base);
584
585 exports.Null = (function(_super) {
586 __extends(Null, _super);
587
588 function Null() {
589 return Null.__super__.constructor.apply(this, arguments);
590 }
591
592 Null.prototype.isAssignable = NO;
593
594 Null.prototype.isComplex = NO;
595
596 Null.prototype.compileNode = function() {
597 return [this.makeCode("null")];
598 };
599
600 return Null;
601
602 })(Base);
603
604 exports.Bool = (function(_super) {
605 __extends(Bool, _super);
606
607 Bool.prototype.isAssignable = NO;
608
609 Bool.prototype.isComplex = NO;
610
611 Bool.prototype.compileNode = function() {
612 return [this.makeCode(this.val)];
613 };
614
615 function Bool(val) {
616 this.val = val;
617 }
618
619 return Bool;
620
621 })(Base);
622
623 exports.Return = Return = (function(_super) {
624 __extends(Return, _super);
625
626 function Return(expression) {
627 this.expression = expression;
628 }
629
630 Return.prototype.children = ['expression'];
631
632 Return.prototype.isStatement = YES;
633
634 Return.prototype.makeReturn = THIS;
635
636 Return.prototype.jumps = THIS;
637
638 Return.prototype.compileToFragments = function(o, level) {
639 var expr, _ref2;
640 expr = (_ref2 = this.expression) != null ? _ref2.makeReturn() : void 0;
641 if (expr && !(expr instanceof Return)) {
642 return expr.compileToFragments(o, level);
643 } else {
644 return Return.__super__.compileToFragments.call(this, o, level);
645 }
646 };
647
648 Return.prototype.compileNode = function(o) {
649 var answer;
650 answer = [];
651 answer.push(this.makeCode(this.tab + ("return" + (this.expression ? " " : ""))));
652 if (this.expression) {
653 answer = answer.concat(this.expression.compileToFragments(o, LEVEL_PAREN));
654 }
655 answer.push(this.makeCode(";"));
656 return answer;
657 };
658
659 return Return;
660
661 })(Base);
662
663 exports.Value = Value = (function(_super) {
664 __extends(Value, _super);
665
666 function Value(base, props, tag) {
667 if (!props && base instanceof Value) {
668 return base;
669 }
670 this.base = base;
671 this.properties = props || [];
672 if (tag) {
673 this[tag] = true;
674 }
675 return this;
676 }
677
678 Value.prototype.children = ['base', 'properties'];
679
680 Value.prototype.add = function(props) {
681 this.properties = this.properties.concat(props);
682 return this;
683 };
684
685 Value.prototype.hasProperties = function() {
686 return !!this.properties.length;
687 };
688
689 Value.prototype.bareLiteral = function(type) {
690 return !this.properties.length && this.base instanceof type;
691 };
692
693 Value.prototype.isArray = function() {
694 return this.bareLiteral(Arr);
695 };
696
697 Value.prototype.isRange = function() {
698 return this.bareLiteral(Range);
699 };
700
701 Value.prototype.isComplex = function() {
702 return this.hasProperties() || this.base.isComplex();
703 };
704
705 Value.prototype.isAssignable = function() {
706 return this.hasProperties() || this.base.isAssignable();
707 };
708
709 Value.prototype.isSimpleNumber = function() {
710 return this.bareLiteral(Literal) && SIMPLENUM.test(this.base.value);
711 };
712
713 Value.prototype.isString = function() {
714 return this.bareLiteral(Literal) && IS_STRING.test(this.base.value);
715 };
716
717 Value.prototype.isRegex = function() {
718 return this.bareLiteral(Literal) && IS_REGEX.test(this.base.value);
719 };
720
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++) {
725 node = _ref2[_i];
726 if (node.soak || node instanceof Call) {
727 return false;
728 }
729 }
730 return true;
731 };
732
733 Value.prototype.isNotCallable = function() {
734 return this.isSimpleNumber() || this.isString() || this.isRegex() || this.isArray() || this.isRange() || this.isSplice() || this.isObject();
735 };
736
737 Value.prototype.isStatement = function(o) {
738 return !this.properties.length && this.base.isStatement(o);
739 };
740
741 Value.prototype.assigns = function(name) {
742 return !this.properties.length && this.base.assigns(name);
743 };
744
745 Value.prototype.jumps = function(o) {
746 return !this.properties.length && this.base.jumps(o);
747 };
748
749 Value.prototype.isObject = function(onlyGenerated) {
750 if (this.properties.length) {
751 return false;
752 }
753 return (this.base instanceof Obj) && (!onlyGenerated || this.base.generated);
754 };
755
756 Value.prototype.isSplice = function() {
757 return last(this.properties) instanceof Slice;
758 };
759
760 Value.prototype.looksStatic = function(className) {
761 var _ref2;
762 return this.base.value === className && this.properties.length && ((_ref2 = this.properties[0].name) != null ? _ref2.value : void 0) !== 'prototype';
763 };
764
765 Value.prototype.unwrap = function() {
766 if (this.properties.length) {
767 return this;
768 } else {
769 return this.base;
770 }
771 };
772
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)) {
777 return [this, this];
778 }
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)));
783 }
784 if (!name) {
785 return [base, bref];
786 }
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);
791 }
792 return [base.add(name), new Value(bref || base.base, [nref || name])];
793 };
794
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('.'));
802 }
803 for (_i = 0, _len = props.length; _i < _len; _i++) {
804 prop = props[_i];
805 fragments.push.apply(fragments, prop.compileToFragments(o));
806 }
807 return fragments;
808 };
809
810 Value.prototype.unfoldSoak = function(o) {
811 return this.unfoldedSoak != null ? this.unfoldedSoak : this.unfoldedSoak = (function(_this) {
812 return function() {
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);
816 return ifn;
817 }
818 _ref3 = _this.properties;
819 for (i = _i = 0, _len = _ref3.length; _i < _len; i = ++_i) {
820 prop = _ref3[i];
821 if (!prop.soak) {
822 continue;
823 }
824 prop.soak = false;
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));
830 snd.base = ref;
831 }
832 return new If(new Existence(fst), snd, {
833 soak: true
834 });
835 }
836 return false;
837 };
838 })(this)();
839 };
840
841 return Value;
842
843 })(Base);
844
845 exports.Comment = Comment = (function(_super) {
846 __extends(Comment, _super);
847
848 function Comment(comment) {
849 this.comment = comment;
850 }
851
852 Comment.prototype.isStatement = YES;
853
854 Comment.prototype.makeReturn = THIS;
855
856 Comment.prototype.compileNode = function(o, level) {
857 var code, comment;
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;
862 }
863 return [this.makeCode("\n"), this.makeCode(code)];
864 };
865
866 return Comment;
867
868 })(Base);
869
870 exports.Call = Call = (function(_super) {
871 __extends(Call, _super);
872
873 function Call(variable, args, soak) {
874 this.args = args != null ? args : [];
875 this.soak = soak;
876 this.isNew = false;
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");
881 }
882 }
883
884 Call.prototype.children = ['variable', 'args'];
885
886 Call.prototype.newInstance = function() {
887 var base, _ref2;
888 base = ((_ref2 = this.variable) != null ? _ref2.base : void 0) || this.variable;
889 if (base instanceof Call && !base.isNew) {
890 base.newInstance();
891 } else {
892 this.isNew = true;
893 }
894 return this;
895 };
896
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')));
904 }
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";
909 } else {
910 return this.error('cannot call super outside of an instance method.');
911 }
912 };
913
914 Call.prototype.superThis = function(o) {
915 var method;
916 method = o.scope.method;
917 return (method && !method.klass && method.context) || "this";
918 };
919
920 Call.prototype.unfoldSoak = function(o) {
921 var call, ifn, left, list, rite, _i, _len, _ref2, _ref3;
922 if (this.soak) {
923 if (this.variable) {
924 if (ifn = unfoldSoak(o, this, 'variable')) {
925 return ifn;
926 }
927 _ref2 = new Value(this.variable).cacheReference(o), left = _ref2[0], rite = _ref2[1];
928 } else {
929 left = new Literal(this.superReference(o));
930 rite = new Value(left);
931 }
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), {
936 soak: true
937 });
938 }
939 call = this;
940 list = [];
941 while (true) {
942 if (call.variable instanceof Call) {
943 list.push(call);
944 call = call.variable;
945 continue;
946 }
947 if (!(call.variable instanceof Value)) {
948 break;
949 }
950 list.push(call);
951 if (!((call = call.variable.base) instanceof Call)) {
952 break;
953 }
954 }
955 _ref3 = list.reverse();
956 for (_i = 0, _len = _ref3.length; _i < _len; _i++) {
957 call = _ref3[_i];
958 if (ifn) {
959 if (call.variable instanceof Call) {
960 call.variable = ifn;
961 } else {
962 call.variable.base = ifn;
963 }
964 }
965 ifn = unfoldSoak(o, call, 'variable');
966 }
967 return ifn;
968 };
969
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;
974 }
975 compiledArray = Splat.compileSplattedArray(o, this.args, true);
976 if (compiledArray.length) {
977 return this.compileSplat(o, compiledArray);
978 }
979 compiledArgs = [];
980 _ref3 = this.args;
981 for (argIndex = _i = 0, _len = _ref3.length; _i < _len; argIndex = ++_i) {
982 arg = _ref3[argIndex];
983 if (argIndex) {
984 compiledArgs.push(this.makeCode(", "));
985 }
986 compiledArgs.push.apply(compiledArgs, arg.compileToFragments(o, LEVEL_LIST));
987 }
988 fragments = [];
989 if (this.isSuper) {
990 preface = this.superReference(o) + (".call(" + (this.superThis(o)));
991 if (compiledArgs.length) {
992 preface += ", ";
993 }
994 fragments.push(this.makeCode(preface));
995 } else {
996 if (this.isNew) {
997 fragments.push(this.makeCode('new '));
998 }
999 fragments.push.apply(fragments, this.variable.compileToFragments(o, LEVEL_ACCESS));
1000 fragments.push(this.makeCode("("));
1001 }
1002 fragments.push.apply(fragments, compiledArgs);
1003 fragments.push(this.makeCode(")"));
1004 return fragments;
1005 };
1006
1007 Call.prototype.compileSplat = function(o, splatArgs) {
1008 var answer, base, fun, idt, name, ref;
1009 if (this.isSuper) {
1010 return [].concat(this.makeCode("" + (this.superReference(o)) + ".apply(" + (this.superThis(o)) + ", "), splatArgs, this.makeCode(")"));
1011 }
1012 if (this.isNew) {
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(){})"));
1015 }
1016 answer = [];
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));
1021 } else {
1022 fun = base.compileToFragments(o, LEVEL_ACCESS);
1023 if (SIMPLENUM.test(fragmentsToText(fun))) {
1024 fun = this.wrapInBraces(fun);
1025 }
1026 if (name) {
1027 ref = fragmentsToText(fun);
1028 fun.push.apply(fun, name.compileToFragments(o));
1029 } else {
1030 ref = 'null';
1031 }
1032 answer = answer.concat(fun);
1033 }
1034 return answer = answer.concat(this.makeCode(".apply(" + ref + ", "), splatArgs, this.makeCode(")"));
1035 };
1036
1037 return Call;
1038
1039 })(Base);
1040
1041 exports.Extends = Extends = (function(_super) {
1042 __extends(Extends, _super);
1043
1044 function Extends(child, parent) {
1045 this.child = child;
1046 this.parent = parent;
1047 }
1048
1049 Extends.prototype.children = ['child', 'parent'];
1050
1051 Extends.prototype.compileToFragments = function(o) {
1052 return new Call(new Value(new Literal(utility('extends'))), [this.child, this.parent]).compileToFragments(o);
1053 };
1054
1055 return Extends;
1056
1057 })(Base);
1058
1059 exports.Access = Access = (function(_super) {
1060 __extends(Access, _super);
1061
1062 function Access(name, tag) {
1063 this.name = name;
1064 this.name.asKey = true;
1065 this.soak = tag === 'soak';
1066 }
1067
1068 Access.prototype.children = ['name'];
1069
1070 Access.prototype.compileToFragments = function(o) {
1071 var name;
1072 name = this.name.compileToFragments(o);
1073 if (IDENTIFIER.test(fragmentsToText(name))) {
1074 name.unshift(this.makeCode("."));
1075 } else {
1076 name.unshift(this.makeCode("["));
1077 name.push(this.makeCode("]"));
1078 }
1079 return name;
1080 };
1081
1082 Access.prototype.isComplex = NO;
1083
1084 return Access;
1085
1086 })(Base);
1087
1088 exports.Index = Index = (function(_super) {
1089 __extends(Index, _super);
1090
1091 function Index(index) {
1092 this.index = index;
1093 }
1094
1095 Index.prototype.children = ['index'];
1096
1097 Index.prototype.compileToFragments = function(o) {
1098 return [].concat(this.makeCode("["), this.index.compileToFragments(o, LEVEL_PAREN), this.makeCode("]"));
1099 };
1100
1101 Index.prototype.isComplex = function() {
1102 return this.index.isComplex();
1103 };
1104
1105 return Index;
1106
1107 })(Base);
1108
1109 exports.Range = Range = (function(_super) {
1110 __extends(Range, _super);
1111
1112 Range.prototype.children = ['from', 'to'];
1113
1114 function Range(from, to, tag) {
1115 this.from = from;
1116 this.to = to;
1117 this.exclusive = tag === 'exclusive';
1118 this.equals = this.exclusive ? '' : '=';
1119 }
1120
1121 Range.prototype.compileVariables = function(o) {
1122 var step, _ref2, _ref3, _ref4, _ref5;
1123 o = merge(o, {
1124 top: true
1125 });
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];
1130 }
1131 _ref5 = [this.fromVar.match(NUMBER), this.toVar.match(NUMBER)], this.fromNum = _ref5[0], this.toNum = _ref5[1];
1132 if (this.stepVar) {
1133 return this.stepNum = this.stepVar.match(NUMBER);
1134 }
1135 };
1136
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);
1141 }
1142 if (!o.index) {
1143 return this.compileArray(o);
1144 }
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;
1152 }
1153 if (this.step !== this.stepVar) {
1154 varPart += ", " + this.step;
1155 }
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 + "--";
1159 if (namedIndex) {
1160 varPart = "" + idxName + " = " + varPart;
1161 }
1162 if (namedIndex) {
1163 stepPart = "" + idxName + " = " + stepPart;
1164 }
1165 return [this.makeCode("" + varPart + "; " + condPart + "; " + stepPart)];
1166 };
1167
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() {
1172 _results = [];
1173 for (var _i = _ref2 = +this.fromNum, _ref3 = +this.toNum; _ref2 <= _ref3 ? _i <= _ref3 : _i >= _ref3; _ref2 <= _ref3 ? _i++ : _i--){ _results.push(_i); }
1174 return _results;
1175 }).apply(this);
1176 if (this.exclusive) {
1177 range.pop();
1178 }
1179 return [this.makeCode("[" + (range.join(', ')) + "]")];
1180 }
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) {
1186 o.index = i;
1187 body = fragmentsToText(this.compileNode(o));
1188 } else {
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 + "--";
1192 }
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;
1196 };
1197 if (hasArgs(this.from) || hasArgs(this.to)) {
1198 args = ', arguments';
1199 }
1200 return [this.makeCode("(function() {" + pre + "\n" + idt + "for (" + body + ")" + post + "}).apply(this" + (args != null ? args : '') + ")")];
1201 };
1202
1203 return Range;
1204
1205 })(Base);
1206
1207 exports.Slice = Slice = (function(_super) {
1208 __extends(Slice, _super);
1209
1210 Slice.prototype.children = ['range'];
1211
1212 function Slice(range) {
1213 this.range = range;
1214 Slice.__super__.constructor.call(this);
1215 }
1216
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')];
1221 if (to) {
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"));
1226 }
1227 }
1228 return [this.makeCode(".slice(" + (fragmentsToText(fromCompiled)) + (toStr || '') + ")")];
1229 };
1230
1231 return Slice;
1232
1233 })(Base);
1234
1235 exports.Obj = Obj = (function(_super) {
1236 __extends(Obj, _super);
1237
1238 function Obj(props, generated) {
1239 this.generated = generated != null ? generated : false;
1240 this.objects = this.properties = props || [];
1241 }
1242
1243 Obj.prototype.children = ['properties'];
1244
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 ? '({})' : '{}')];
1250 }
1251 if (this.generated) {
1252 for (_i = 0, _len = props.length; _i < _len; _i++) {
1253 node = props[_i];
1254 if (node instanceof Value) {
1255 node.error('cannot have an implicit value in an implicit object');
1256 }
1257 }
1258 }
1259 idt = o.indent += TAB;
1260 lastNoncom = this.lastNonComment(this.properties);
1261 answer = [];
1262 for (i = _j = 0, _len1 = props.length; _j < _len1; i = ++_j) {
1263 prop = props[i];
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');
1268 }
1269 if (prop instanceof Value && prop["this"]) {
1270 prop = new Assign(prop.properties[0].name, prop, 'object');
1271 }
1272 if (!(prop instanceof Comment)) {
1273 if (!(prop instanceof Assign)) {
1274 prop = new Assign(prop, prop, 'object');
1275 }
1276 (prop.variable.base || prop.variable).asKey = true;
1277 }
1278 if (indent) {
1279 answer.push(this.makeCode(indent));
1280 }
1281 answer.push.apply(answer, prop.compileToFragments(o, LEVEL_TOP));
1282 if (join) {
1283 answer.push(this.makeCode(join));
1284 }
1285 }
1286 answer.unshift(this.makeCode("{" + (props.length && '\n')));
1287 answer.push(this.makeCode("" + (props.length && '\n' + this.tab) + "}"));
1288 if (this.front) {
1289 return this.wrapInBraces(answer);
1290 } else {
1291 return answer;
1292 }
1293 };
1294
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++) {
1299 prop = _ref2[_i];
1300 if (prop.assigns(name)) {
1301 return true;
1302 }
1303 }
1304 return false;
1305 };
1306
1307 return Obj;
1308
1309 })(Base);
1310
1311 exports.Arr = Arr = (function(_super) {
1312 __extends(Arr, _super);
1313
1314 function Arr(objs) {
1315 this.objects = objs || [];
1316 }
1317
1318 Arr.prototype.children = ['objects'];
1319
1320 Arr.prototype.compileNode = function(o) {
1321 var answer, compiledObjs, fragments, index, obj, _i, _len;
1322 if (!this.objects.length) {
1323 return [this.makeCode('[]')];
1324 }
1325 o.indent += TAB;
1326 answer = Splat.compileSplattedArray(o, this.objects);
1327 if (answer.length) {
1328 return answer;
1329 }
1330 answer = [];
1331 compiledObjs = (function() {
1332 var _i, _len, _ref2, _results;
1333 _ref2 = this.objects;
1334 _results = [];
1335 for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
1336 obj = _ref2[_i];
1337 _results.push(obj.compileToFragments(o, LEVEL_LIST));
1338 }
1339 return _results;
1340 }).call(this);
1341 for (index = _i = 0, _len = compiledObjs.length; _i < _len; index = ++_i) {
1342 fragments = compiledObjs[index];
1343 if (index) {
1344 answer.push(this.makeCode(", "));
1345 }
1346 answer.push.apply(answer, fragments);
1347 }
1348 if (fragmentsToText(answer).indexOf('\n') >= 0) {
1349 answer.unshift(this.makeCode("[\n" + o.indent));
1350 answer.push(this.makeCode("\n" + this.tab + "]"));
1351 } else {
1352 answer.unshift(this.makeCode("["));
1353 answer.push(this.makeCode("]"));
1354 }
1355 return answer;
1356 };
1357
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++) {
1362 obj = _ref2[_i];
1363 if (obj.assigns(name)) {
1364 return true;
1365 }
1366 }
1367 return false;
1368 };
1369
1370 return Arr;
1371
1372 })(Base);
1373
1374 exports.Class = Class = (function(_super) {
1375 __extends(Class, _super);
1376
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;
1383 }
1384
1385 Class.prototype.children = ['variable', 'parent', 'body'];
1386
1387 Class.prototype.determineName = function() {
1388 var decl, tail;
1389 if (!this.variable) {
1390 return null;
1391 }
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);
1395 }
1396 return decl && (decl = IDENTIFIER.test(decl) && decl);
1397 };
1398
1399 Class.prototype.setContext = function(name) {
1400 return this.body.traverseChildren(false, function(node) {
1401 if (node.classBody) {
1402 return false;
1403 }
1404 if (node instanceof Literal && node.value === 'this') {
1405 return node.value = name;
1406 } else if (node instanceof Code) {
1407 node.klass = name;
1408 if (node.bound) {
1409 return node.context = name;
1410 }
1411 }
1412 });
1413 };
1414
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++) {
1419 bvar = _ref2[_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)"));
1422 }
1423 };
1424
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() {
1429 var _results;
1430 _results = [];
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') {
1437 if (this.ctor) {
1438 assign.error('cannot define more than one constructor in a class');
1439 }
1440 if (func.bound) {
1441 assign.error('cannot define a constructor as a bound function');
1442 }
1443 if (func instanceof Code) {
1444 assign = this.ctor = func;
1445 } else {
1446 this.externalCtor = o.classScope.freeVariable('class');
1447 assign = new Assign(new Literal(this.externalCtor), func);
1448 }
1449 } else {
1450 if (assign.variable["this"]) {
1451 func["static"] = true;
1452 } else {
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);
1456 func.bound = false;
1457 }
1458 }
1459 }
1460 }
1461 _results.push(assign);
1462 }
1463 return _results;
1464 }).call(this);
1465 return compact(exprs);
1466 };
1467
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;
1472 cont = true;
1473 if (child instanceof Class) {
1474 return false;
1475 }
1476 if (child instanceof Block) {
1477 _ref2 = exps = child.expressions;
1478 for (i = _i = 0, _len = _ref2.length; _i < _len; i = ++_i) {
1479 node = _ref2[i];
1480 if (node instanceof Assign && node.variable.looksStatic(name)) {
1481 node.value["static"] = true;
1482 } else if (node instanceof Value && node.isObject(true)) {
1483 cont = false;
1484 exps[i] = _this.addProperties(node, name, o);
1485 }
1486 }
1487 child.expressions = exps = flatten(exps);
1488 }
1489 return cont && !(child instanceof Class);
1490 };
1491 })(this));
1492 };
1493
1494 Class.prototype.hoistDirectivePrologue = function() {
1495 var expressions, index, node;
1496 index = 0;
1497 expressions = this.body.expressions;
1498 while ((node = expressions[index]) && node instanceof Comment || node instanceof Value && node.isString()) {
1499 ++index;
1500 }
1501 return this.directives = expressions.splice(0, index);
1502 };
1503
1504 Class.prototype.ensureConstructor = function(name) {
1505 if (!this.ctor) {
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)"));
1511 }
1512 this.ctor.body.makeReturn();
1513 this.body.expressions.unshift(this.ctor);
1514 }
1515 this.ctor.ctor = this.ctor.name = name;
1516 this.ctor.klass = null;
1517 return this.ctor.noReturn = true;
1518 };
1519
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');
1524 }
1525 if (argumentsNode = this.body.contains(isLiteralArguments)) {
1526 argumentsNode.error("Class bodies shouldn't reference arguments");
1527 }
1528 name = this.determineName() || '_Class';
1529 if (name.reserved) {
1530 name = "_" + name;
1531 }
1532 lname = new Literal(name);
1533 func = new Code([], Block.wrap([this.body]));
1534 args = [];
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);
1543 if (this.parent) {
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);
1548 }
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);
1553 }
1554 return klass.compileToFragments(o);
1555 };
1556
1557 return Class;
1558
1559 })(Base);
1560
1561 exports.Assign = Assign = (function(_super) {
1562 __extends(Assign, _super);
1563
1564 function Assign(variable, value, context, options) {
1565 var forbidden, name, _ref2;
1566 this.variable = variable;
1567 this.value = value;
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 + "\"");
1574 }
1575 }
1576
1577 Assign.prototype.children = ['variable', 'value'];
1578
1579 Assign.prototype.isStatement = function(o) {
1580 return (o != null ? o.level : void 0) === LEVEL_TOP && (this.context != null) && __indexOf.call(this.context, "?") >= 0;
1581 };
1582
1583 Assign.prototype.assigns = function(name) {
1584 return this[this.context === 'object' ? 'value' : 'variable'].assigns(name);
1585 };
1586
1587 Assign.prototype.unfoldSoak = function(o) {
1588 return unfoldSoak(o, this, 'variable');
1589 };
1590
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);
1596 }
1597 if (this.variable.isSplice()) {
1598 return this.compileSplice(o);
1599 }
1600 if ((_ref2 = this.context) === '||=' || _ref2 === '&&=' || _ref2 === '?=') {
1601 return this.compileConditional(o);
1602 }
1603 if ((_ref3 = this.context) === '**=' || _ref3 === '//=' || _ref3 === '%%=') {
1604 return this.compileSpecialMath(o);
1605 }
1606 }
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");
1613 }
1614 if (!(typeof varBase.hasProperties === "function" ? varBase.hasProperties() : void 0)) {
1615 if (this.param) {
1616 o.scope.add(name, 'var');
1617 } else {
1618 o.scope.find(name);
1619 }
1620 }
1621 }
1622 if (this.value instanceof Code && (match = METHOD_DEF.exec(name))) {
1623 if (match[2]) {
1624 this.value.klass = match[1];
1625 }
1626 this.value.name = (_ref4 = (_ref5 = match[3]) != null ? _ref5 : match[4]) != null ? _ref4 : match[5];
1627 }
1628 val = this.value.compileToFragments(o, LEVEL_LIST);
1629 if (this.context === 'object') {
1630 return compiledName.concat(this.makeCode(": "), val);
1631 }
1632 answer = compiledName.concat(this.makeCode(" " + (this.context || '=') + " "), val);
1633 if (o.level <= LEVEL_LIST) {
1634 return answer;
1635 } else {
1636 return this.wrapInBraces(answer);
1637 }
1638 };
1639
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;
1643 value = this.value;
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);
1649 } else {
1650 return code;
1651 }
1652 }
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;
1657 } else {
1658 idx = isObject ? obj["this"] ? obj.properties[0].name : obj : new Literal(0);
1659 }
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)));
1665 }
1666 return new Assign(obj, value, null, {
1667 param: this.param
1668 }).compileToFragments(o, LEVEL_TOP);
1669 }
1670 vvar = value.compileToFragments(o, LEVEL_LIST);
1671 vvarText = fragmentsToText(vvar);
1672 assigns = [];
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)];
1677 vvarText = ref;
1678 }
1679 for (i = _i = 0, _len = objects.length; _i < _len; i = ++_i) {
1680 obj = objects[i];
1681 idx = i;
1682 if (isObject) {
1683 if (obj instanceof Assign) {
1684 _ref5 = obj, (_ref6 = _ref5.variable, idx = _ref6.base), obj = _ref5.value;
1685 } else {
1686 if (obj.base instanceof Parens) {
1687 _ref7 = new Value(obj.unwrapAll()).cacheReference(o), obj = _ref7[0], idx = _ref7[1];
1688 } else {
1689 idx = obj["this"] ? obj.properties[0].name : obj;
1690 }
1691 }
1692 }
1693 if (!expandedIdx && obj instanceof Splat) {
1694 name = obj.name.unwrap().value;
1695 obj = obj.unwrap();
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 + ", [])";
1700 } else {
1701 val += ") : []";
1702 }
1703 val = new Literal(val);
1704 expandedIdx = "" + ivar + "++";
1705 } else if (!expandedIdx && obj instanceof Expansion) {
1706 if (rest = olen - i - 1) {
1707 if (rest === 1) {
1708 expandedIdx = "" + vvarText + ".length - 1";
1709 } else {
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));
1714 }
1715 }
1716 continue;
1717 } else {
1718 name = obj.unwrap().value;
1719 if (obj instanceof Splat || obj instanceof Expansion) {
1720 obj.error("multiple splats/expansions are disallowed in an assignment");
1721 }
1722 if (typeof idx === 'number') {
1723 idx = new Literal(expandedIdx || idx);
1724 acc = false;
1725 } else {
1726 acc = isObject && IDENTIFIER.test(idx.unwrap().value || 0);
1727 }
1728 val = new Value(new Literal(vvarText), [new (acc ? Access : Index)(idx)]);
1729 }
1730 if ((name != null) && __indexOf.call(RESERVED, name) >= 0) {
1731 obj.error("assignment to a reserved word: " + (obj.compile(o)));
1732 }
1733 assigns.push(new Assign(obj, val, null, {
1734 param: this.param,
1735 subpattern: true
1736 }).compileToFragments(o, LEVEL_LIST));
1737 }
1738 if (!(top || this.subpattern)) {
1739 assigns.push(vvar);
1740 }
1741 fragments = this.joinFragmentArrays(assigns, ', ');
1742 if (o.level < LEVEL_LIST) {
1743 return fragments;
1744 } else {
1745 return this.wrapInBraces(fragments);
1746 }
1747 };
1748
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");
1754 }
1755 if (__indexOf.call(this.context, "?") >= 0) {
1756 o.isExistentialEquals = true;
1757 return new If(new Existence(left), right, {
1758 type: 'if'
1759 }).addElse(new Assign(right, this.value, '=')).compileToFragments(o);
1760 } else {
1761 fragments = new Op(this.context.slice(0, -1), left, new Assign(right, this.value, '=')).compileToFragments(o);
1762 if (o.level <= LEVEL_LIST) {
1763 return fragments;
1764 } else {
1765 return this.wrapInBraces(fragments);
1766 }
1767 }
1768 };
1769
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);
1774 };
1775
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);
1780 if (from) {
1781 _ref3 = this.cacheToCodeFragments(from.cache(o, LEVEL_OP)), fromDecl = _ref3[0], fromRef = _ref3[1];
1782 } else {
1783 fromDecl = fromRef = '0';
1784 }
1785 if (to) {
1786 if (from instanceof Value && from.isSimpleNumber() && to instanceof Value && to.isSimpleNumber()) {
1787 to = to.compile(o) - fromRef;
1788 if (!exclusive) {
1789 to += 1;
1790 }
1791 } else {
1792 to = to.compile(o, LEVEL_ACCESS) + ' - ' + fromRef;
1793 if (!exclusive) {
1794 to += ' + 1';
1795 }
1796 }
1797 } else {
1798 to = "9e9";
1799 }
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);
1804 } else {
1805 return answer;
1806 }
1807 };
1808
1809 return Assign;
1810
1811 })(Base);
1812
1813 exports.Code = Code = (function(_super) {
1814 __extends(Code, _super);
1815
1816 function Code(params, body, tag) {
1817 this.params = params || [];
1818 this.body = body || new Block;
1819 this.bound = tag === 'boundfunc';
1820 }
1821
1822 Code.prototype.children = ['params', 'body'];
1823
1824 Code.prototype.isStatement = function() {
1825 return !!this.ctor;
1826 };
1827
1828 Code.prototype.jumps = NO;
1829
1830 Code.prototype.makeScope = function(parentScope) {
1831 return new Scope(parentScope, this.body, this);
1832 };
1833
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;
1838 }
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);
1845 }
1846 o.scope = del(o, 'classScope') || this.makeScope(o.scope);
1847 o.scope.shared = del(o, 'sharedScope');
1848 o.indent += TAB;
1849 delete o.bare;
1850 delete o.isExistentialEquals;
1851 params = [];
1852 exprs = [];
1853 _ref3 = this.params;
1854 for (_i = 0, _len = _ref3.length; _i < _len; _i++) {
1855 param = _ref3[_i];
1856 if (!(param instanceof Expansion)) {
1857 o.scope.parameter(param.asReference(o));
1858 }
1859 }
1860 _ref4 = this.params;
1861 for (_j = 0, _len1 = _ref4.length; _j < _len1; _j++) {
1862 param = _ref4[_j];
1863 if (!(param.splat || param instanceof Expansion)) {
1864 continue;
1865 }
1866 _ref5 = this.params;
1867 for (_k = 0, _len2 = _ref5.length; _k < _len2; _k++) {
1868 p = _ref5[_k].name;
1869 if (!(!(param instanceof Expansion))) {
1870 continue;
1871 }
1872 if (p["this"]) {
1873 p = p.properties[0].name;
1874 }
1875 if (p.value) {
1876 o.scope.add(p.value, 'var', true);
1877 }
1878 }
1879 splats = new Assign(new Value(new Arr((function() {
1880 var _l, _len3, _ref6, _results;
1881 _ref6 = this.params;
1882 _results = [];
1883 for (_l = 0, _len3 = _ref6.length; _l < _len3; _l++) {
1884 p = _ref6[_l];
1885 _results.push(p.asReference(o));
1886 }
1887 return _results;
1888 }).call(this))), new Value(new Literal('arguments')));
1889 break;
1890 }
1891 _ref6 = this.params;
1892 for (_l = 0, _len3 = _ref6.length; _l < _len3; _l++) {
1893 param = _ref6[_l];
1894 if (param.isComplex()) {
1895 val = ref = param.asReference(o);
1896 if (param.value) {
1897 val = new Op('?', ref, param.value);
1898 }
1899 exprs.push(new Assign(new Value(param.name), val, '=', {
1900 param: true
1901 }));
1902 } else {
1903 ref = param;
1904 if (param.value) {
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));
1908 }
1909 }
1910 if (!splats) {
1911 params.push(ref);
1912 }
1913 }
1914 wasEmpty = this.body.isEmpty();
1915 if (splats) {
1916 exprs.unshift(splats);
1917 }
1918 if (exprs.length) {
1919 (_ref7 = this.body.expressions).unshift.apply(_ref7, exprs);
1920 }
1921 for (i = _m = 0, _len4 = params.length; _m < _len4; i = ++_m) {
1922 p = params[i];
1923 params[i] = p.compileToFragments(o);
1924 o.scope.parameter(fragmentsToText(params[i]));
1925 }
1926 uniqs = [];
1927 this.eachParamName(function(name, node) {
1928 if (__indexOf.call(uniqs, name) >= 0) {
1929 node.error("multiple parameters named '" + name + "'");
1930 }
1931 return uniqs.push(name);
1932 });
1933 if (!(wasEmpty || this.noReturn)) {
1934 this.body.makeReturn();
1935 }
1936 code = 'function';
1937 if (this.ctor) {
1938 code += ' ' + this.name;
1939 }
1940 code += '(';
1941 answer = [this.makeCode(code)];
1942 for (i = _n = 0, _len5 = params.length; _n < _len5; i = ++_n) {
1943 p = params[i];
1944 if (i) {
1945 answer.push(this.makeCode(", "));
1946 }
1947 answer.push.apply(answer, p);
1948 }
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));
1952 }
1953 answer.push(this.makeCode('}'));
1954 if (this.ctor) {
1955 return [this.makeCode(this.tab)].concat(__slice.call(answer));
1956 }
1957 if (this.front || (o.level >= LEVEL_ACCESS)) {
1958 return this.wrapInBraces(answer);
1959 } else {
1960 return answer;
1961 }
1962 };
1963
1964 Code.prototype.eachParamName = function(iterator) {
1965 var param, _i, _len, _ref2, _results;
1966 _ref2 = this.params;
1967 _results = [];
1968 for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
1969 param = _ref2[_i];
1970 _results.push(param.eachName(iterator));
1971 }
1972 return _results;
1973 };
1974
1975 Code.prototype.traverseChildren = function(crossScope, func) {
1976 if (crossScope) {
1977 return Code.__super__.traverseChildren.call(this, crossScope, func);
1978 }
1979 };
1980
1981 return Code;
1982
1983 })(Base);
1984
1985 exports.Param = Param = (function(_super) {
1986 __extends(Param, _super);
1987
1988 function Param(name, value, splat) {
1989 var _ref2;
1990 this.name = name;
1991 this.value = value;
1992 this.splat = 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");
1995 }
1996 }
1997
1998 Param.prototype.children = ['name', 'value'];
1999
2000 Param.prototype.compileToFragments = function(o) {
2001 return this.name.compileToFragments(o, LEVEL_LIST);
2002 };
2003
2004 Param.prototype.asReference = function(o) {
2005 var node;
2006 if (this.reference) {
2007 return this.reference;
2008 }
2009 node = this.name;
2010 if (node["this"]) {
2011 node = node.properties[0].name;
2012 if (node.value.reserved) {
2013 node = new Literal(o.scope.freeVariable(node.value));
2014 }
2015 } else if (node.isComplex()) {
2016 node = new Literal(o.scope.freeVariable('arg'));
2017 }
2018 node = new Value(node);
2019 if (this.splat) {
2020 node = new Splat(node);
2021 }
2022 node.updateLocationDataIfMissing(this.locationData);
2023 return this.reference = node;
2024 };
2025
2026 Param.prototype.isComplex = function() {
2027 return this.name.isComplex();
2028 };
2029
2030 Param.prototype.eachName = function(iterator, name) {
2031 var atParam, node, obj, _i, _len, _ref2;
2032 if (name == null) {
2033 name = this.name;
2034 }
2035 atParam = function(obj) {
2036 var node;
2037 node = obj.properties[0].name;
2038 if (!node.value.reserved) {
2039 return iterator(node.value, node);
2040 }
2041 };
2042 if (name instanceof Literal) {
2043 return iterator(name.value, name);
2044 }
2045 if (name instanceof Value) {
2046 return atParam(name);
2047 }
2048 _ref2 = name.objects;
2049 for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
2050 obj = _ref2[_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"]) {
2060 atParam(obj);
2061 } else {
2062 iterator(obj.base.value, obj.base);
2063 }
2064 } else if (!(obj instanceof Expansion)) {
2065 obj.error("illegal parameter " + (obj.compile()));
2066 }
2067 }
2068 };
2069
2070 return Param;
2071
2072 })(Base);
2073
2074 exports.Splat = Splat = (function(_super) {
2075 __extends(Splat, _super);
2076
2077 Splat.prototype.children = ['name'];
2078
2079 Splat.prototype.isAssignable = YES;
2080
2081 function Splat(name) {
2082 this.name = name.compile ? name : new Literal(name);
2083 }
2084
2085 Splat.prototype.assigns = function(name) {
2086 return this.name.assigns(name);
2087 };
2088
2089 Splat.prototype.compileToFragments = function(o) {
2090 return this.name.compileToFragments(o);
2091 };
2092
2093 Splat.prototype.unwrap = function() {
2094 return this.name;
2095 };
2096
2097 Splat.compileSplattedArray = function(o, list, apply) {
2098 var args, base, compiledNode, concatPart, fragments, i, index, node, _i, _len;
2099 index = -1;
2100 while ((node = list[++index]) && !(node instanceof Splat)) {
2101 continue;
2102 }
2103 if (index >= list.length) {
2104 return [];
2105 }
2106 if (list.length === 1) {
2107 node = list[0];
2108 fragments = node.compileToFragments(o, LEVEL_LIST);
2109 if (apply) {
2110 return fragments;
2111 }
2112 return [].concat(node.makeCode("" + (utility('slice')) + ".call("), fragments, node.makeCode(")"));
2113 }
2114 args = list.slice(index);
2115 for (i = _i = 0, _len = args.length; _i < _len; i = ++_i) {
2116 node = args[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("]"));
2119 }
2120 if (index === 0) {
2121 node = list[0];
2122 concatPart = node.joinFragmentArrays(args.slice(1), ', ');
2123 return args[0].concat(node.makeCode(".concat("), concatPart, node.makeCode(")"));
2124 }
2125 base = (function() {
2126 var _j, _len1, _ref2, _results;
2127 _ref2 = list.slice(0, index);
2128 _results = [];
2129 for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {
2130 node = _ref2[_j];
2131 _results.push(node.compileToFragments(o, LEVEL_LIST));
2132 }
2133 return _results;
2134 })();
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(")"));
2138 };
2139
2140 return Splat;
2141
2142 })(Base);
2143
2144 exports.Expansion = Expansion = (function(_super) {
2145 __extends(Expansion, _super);
2146
2147 function Expansion() {
2148 return Expansion.__super__.constructor.apply(this, arguments);
2149 }
2150
2151 Expansion.prototype.isComplex = NO;
2152
2153 Expansion.prototype.compileNode = function(o) {
2154 return this.error('Expansion must be used inside a destructuring assignment or parameter list');
2155 };
2156
2157 Expansion.prototype.asReference = function(o) {
2158 return this;
2159 };
2160
2161 Expansion.prototype.eachName = function(iterator) {};
2162
2163 return Expansion;
2164
2165 })(Base);
2166
2167 exports.While = While = (function(_super) {
2168 __extends(While, _super);
2169
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;
2173 }
2174
2175 While.prototype.children = ['condition', 'guard', 'body'];
2176
2177 While.prototype.isStatement = YES;
2178
2179 While.prototype.makeReturn = function(res) {
2180 if (res) {
2181 return While.__super__.makeReturn.apply(this, arguments);
2182 } else {
2183 this.returns = !this.jumps({
2184 loop: true
2185 });
2186 return this;
2187 }
2188 };
2189
2190 While.prototype.addBody = function(body) {
2191 this.body = body;
2192 return this;
2193 };
2194
2195 While.prototype.jumps = function() {
2196 var expressions, jumpNode, node, _i, _len;
2197 expressions = this.body.expressions;
2198 if (!expressions.length) {
2199 return false;
2200 }
2201 for (_i = 0, _len = expressions.length; _i < _len; _i++) {
2202 node = expressions[_i];
2203 if (jumpNode = node.jumps({
2204 loop: true
2205 })) {
2206 return jumpNode;
2207 }
2208 }
2209 return false;
2210 };
2211
2212 While.prototype.compileNode = function(o) {
2213 var answer, body, rvar, set;
2214 o.indent += TAB;
2215 set = '';
2216 body = this.body;
2217 if (body.isEmpty()) {
2218 body = this.makeCode('');
2219 } else {
2220 if (this.returns) {
2221 body.makeReturn(rvar = o.scope.freeVariable('results'));
2222 set = "" + this.tab + rvar + " = [];\n";
2223 }
2224 if (this.guard) {
2225 if (body.expressions.length > 1) {
2226 body.expressions.unshift(new If((new Parens(this.guard)).invert(), new Literal("continue")));
2227 } else {
2228 if (this.guard) {
2229 body = Block.wrap([new If(this.guard, body)]);
2230 }
2231 }
2232 }
2233 body = [].concat(this.makeCode("\n"), body.compileToFragments(o, LEVEL_TOP), this.makeCode("\n" + this.tab));
2234 }
2235 answer = [].concat(this.makeCode(set + this.tab + "while ("), this.condition.compileToFragments(o, LEVEL_PAREN), this.makeCode(") {"), body, this.makeCode("}"));
2236 if (this.returns) {
2237 answer.push(this.makeCode("\n" + this.tab + "return " + rvar + ";"));
2238 }
2239 return answer;
2240 };
2241
2242 return While;
2243
2244 })(Base);
2245
2246 exports.Op = Op = (function(_super) {
2247 var CONVERSIONS, INVERSIONS;
2248
2249 __extends(Op, _super);
2250
2251 function Op(op, first, second, flip) {
2252 if (op === 'in') {
2253 return new In(first, second);
2254 }
2255 if (op === 'do') {
2256 return this.generateDo(first);
2257 }
2258 if (op === 'new') {
2259 if (first instanceof Call && !first["do"] && !first.isNew) {
2260 return first.newInstance();
2261 }
2262 if (first instanceof Code && first.bound || first["do"]) {
2263 first = new Parens(first);
2264 }
2265 }
2266 this.operator = CONVERSIONS[op] || op;
2267 this.first = first;
2268 this.second = second;
2269 this.flip = !!flip;
2270 return this;
2271 }
2272
2273 CONVERSIONS = {
2274 '==': '===',
2275 '!=': '!==',
2276 'of': 'in'
2277 };
2278
2279 INVERSIONS = {
2280 '!==': '===',
2281 '===': '!=='
2282 };
2283
2284 Op.prototype.children = ['first', 'second'];
2285
2286 Op.prototype.isSimpleNumber = NO;
2287
2288 Op.prototype.isUnary = function() {
2289 return !this.second;
2290 };
2291
2292 Op.prototype.isComplex = function() {
2293 var _ref2;
2294 return !(this.isUnary() && ((_ref2 = this.operator) === '+' || _ref2 === '-')) || this.first.isComplex();
2295 };
2296
2297 Op.prototype.isChainable = function() {
2298 var _ref2;
2299 return (_ref2 = this.operator) === '<' || _ref2 === '>' || _ref2 === '>=' || _ref2 === '<=' || _ref2 === '===' || _ref2 === '!==';
2300 };
2301
2302 Op.prototype.invert = function() {
2303 var allInvertable, curr, fst, op, _ref2;
2304 if (this.isChainable() && this.first.isChainable()) {
2305 allInvertable = true;
2306 curr = this;
2307 while (curr && curr.operator) {
2308 allInvertable && (allInvertable = curr.operator in INVERSIONS);
2309 curr = curr.first;
2310 }
2311 if (!allInvertable) {
2312 return new Parens(this).invert();
2313 }
2314 curr = this;
2315 while (curr && curr.operator) {
2316 curr.invert = !curr.invert;
2317 curr.operator = INVERSIONS[curr.operator];
2318 curr = curr.first;
2319 }
2320 return this;
2321 } else if (op = INVERSIONS[this.operator]) {
2322 this.operator = op;
2323 if (this.first.unwrap() instanceof Op) {
2324 this.first.invert();
2325 }
2326 return this;
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')) {
2330 return fst;
2331 } else {
2332 return new Op('!', this);
2333 }
2334 };
2335
2336 Op.prototype.unfoldSoak = function(o) {
2337 var _ref2;
2338 return ((_ref2 = this.operator) === '++' || _ref2 === '--' || _ref2 === 'delete') && unfoldSoak(o, this, 'first');
2339 };
2340
2341 Op.prototype.generateDo = function(exp) {
2342 var call, func, param, passedParams, ref, _i, _len, _ref2;
2343 passedParams = [];
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++) {
2347 param = _ref2[_i];
2348 if (param.value) {
2349 passedParams.push(param.value);
2350 delete param.value;
2351 } else {
2352 passedParams.push(param);
2353 }
2354 }
2355 call = new Call(exp, passedParams);
2356 call["do"] = true;
2357 return call;
2358 };
2359
2360 Op.prototype.compileNode = function(o) {
2361 var answer, isChain, lhs, rhs, _ref2, _ref3;
2362 isChain = this.isChainable() && this.first.isChainable();
2363 if (!isChain) {
2364 this.first.front = this.front;
2365 }
2366 if (this.operator === 'delete' && o.scope.check(this.first.unwrapAll().value)) {
2367 this.error('delete operand may not be argument or var');
2368 }
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) + "\"");
2371 }
2372 if (this.isUnary()) {
2373 return this.compileUnary(o);
2374 }
2375 if (isChain) {
2376 return this.compileChain(o);
2377 }
2378 switch (this.operator) {
2379 case '?':
2380 return this.compileExistence(o);
2381 case '**':
2382 return this.compilePower(o);
2383 case '//':
2384 return this.compileFloorDivision(o);
2385 case '%%':
2386 return this.compileModulo(o);
2387 default:
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) {
2392 return answer;
2393 } else {
2394 return this.wrapInBraces(answer);
2395 }
2396 }
2397 };
2398
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);
2405 };
2406
2407 Op.prototype.compileExistence = function(o) {
2408 var fst, ref;
2409 if (this.first.isComplex()) {
2410 ref = new Literal(o.scope.freeVariable('ref'));
2411 fst = new Parens(new Assign(ref, this.first));
2412 } else {
2413 fst = this.first;
2414 ref = fst;
2415 }
2416 return new If(new Existence(fst), ref, {
2417 type: 'if'
2418 }).addElse(this.second).compileToFragments(o);
2419 };
2420
2421 Op.prototype.compileUnary = function(o) {
2422 var op, parts, plusMinus;
2423 parts = [];
2424 op = this.operator;
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);
2429 }
2430 if (o.level >= LEVEL_ACCESS) {
2431 return (new Parens(this)).compileToFragments(o);
2432 }
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(' ')]);
2436 }
2437 if ((plusMinus && this.first instanceof Op) || (op === 'new' && this.first.isStatement(o))) {
2438 this.first = new Parens(this.first);
2439 }
2440 parts.push(this.first.compileToFragments(o, LEVEL_OP));
2441 if (this.flip) {
2442 parts.reverse();
2443 }
2444 return this.joinFragmentArrays(parts, '');
2445 };
2446
2447 Op.prototype.compilePower = function(o) {
2448 var pow;
2449 pow = new Value(new Literal('Math'), [new Access(new Literal('pow'))]);
2450 return new Call(pow, [this.first, this.second]).compileToFragments(o);
2451 };
2452
2453 Op.prototype.compileFloorDivision = function(o) {
2454 var div, floor;
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);
2458 };
2459
2460 Op.prototype.compileModulo = function(o) {
2461 var mod;
2462 mod = new Value(new Literal(utility('modulo')));
2463 return new Call(mod, [this.first, this.second]).compileToFragments(o);
2464 };
2465
2466 Op.prototype.toString = function(idt) {
2467 return Op.__super__.toString.call(this, idt, this.constructor.name + ' ' + this.operator);
2468 };
2469
2470 return Op;
2471
2472 })(Base);
2473
2474 exports.In = In = (function(_super) {
2475 __extends(In, _super);
2476
2477 function In(object, array) {
2478 this.object = object;
2479 this.array = array;
2480 }
2481
2482 In.prototype.children = ['object', 'array'];
2483
2484 In.prototype.invert = NEGATE;
2485
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++) {
2491 obj = _ref2[_i];
2492 if (!(obj instanceof Splat)) {
2493 continue;
2494 }
2495 hasSplat = true;
2496 break;
2497 }
2498 if (!hasSplat) {
2499 return this.compileOrTest(o);
2500 }
2501 }
2502 return this.compileLoopTest(o);
2503 };
2504
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];
2509 tests = [];
2510 _ref4 = this.array.base.objects;
2511 for (i = _i = 0, _len = _ref4.length; _i < _len; i = ++_i) {
2512 item = _ref4[i];
2513 if (i) {
2514 tests.push(this.makeCode(cnj));
2515 }
2516 tests = tests.concat((i ? ref : sub), this.makeCode(cmp), item.compileToFragments(o, LEVEL_ACCESS));
2517 }
2518 if (o.level < LEVEL_OP) {
2519 return tests;
2520 } else {
2521 return this.wrapInBraces(tests);
2522 }
2523 };
2524
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)) {
2530 return fragments;
2531 }
2532 fragments = sub.concat(this.makeCode(', '), fragments);
2533 if (o.level < LEVEL_LIST) {
2534 return fragments;
2535 } else {
2536 return this.wrapInBraces(fragments);
2537 }
2538 };
2539
2540 In.prototype.toString = function(idt) {
2541 return In.__super__.toString.call(this, idt, this.constructor.name + (this.negated ? '!' : ''));
2542 };
2543
2544 return In;
2545
2546 })(Base);
2547
2548 exports.Try = Try = (function(_super) {
2549 __extends(Try, _super);
2550
2551 function Try(attempt, errorVariable, recovery, ensure) {
2552 this.attempt = attempt;
2553 this.errorVariable = errorVariable;
2554 this.recovery = recovery;
2555 this.ensure = ensure;
2556 }
2557
2558 Try.prototype.children = ['attempt', 'recovery', 'ensure'];
2559
2560 Try.prototype.isStatement = YES;
2561
2562 Try.prototype.jumps = function(o) {
2563 var _ref2;
2564 return this.attempt.jumps(o) || ((_ref2 = this.recovery) != null ? _ref2.jumps(o) : void 0);
2565 };
2566
2567 Try.prototype.makeReturn = function(res) {
2568 if (this.attempt) {
2569 this.attempt = this.attempt.makeReturn(res);
2570 }
2571 if (this.recovery) {
2572 this.recovery = this.recovery.makeReturn(res);
2573 }
2574 return this;
2575 };
2576
2577 Try.prototype.compileNode = function(o) {
2578 var catchPart, ensurePart, placeholder, tryPart;
2579 o.indent += TAB;
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);
2584 };
2585
2586 return Try;
2587
2588 })(Base);
2589
2590 exports.Throw = Throw = (function(_super) {
2591 __extends(Throw, _super);
2592
2593 function Throw(expression) {
2594 this.expression = expression;
2595 }
2596
2597 Throw.prototype.children = ['expression'];
2598
2599 Throw.prototype.isStatement = YES;
2600
2601 Throw.prototype.jumps = NO;
2602
2603 Throw.prototype.makeReturn = THIS;
2604
2605 Throw.prototype.compileNode = function(o) {
2606 return [].concat(this.makeCode(this.tab + "throw "), this.expression.compileToFragments(o), this.makeCode(";"));
2607 };
2608
2609 return Throw;
2610
2611 })(Base);
2612
2613 exports.Existence = Existence = (function(_super) {
2614 __extends(Existence, _super);
2615
2616 function Existence(expression) {
2617 this.expression = expression;
2618 }
2619
2620 Existence.prototype.children = ['expression'];
2621
2622 Existence.prototype.invert = NEGATE;
2623
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";
2631 } else {
2632 code = "" + code + " " + (this.negated ? '==' : '!=') + " null";
2633 }
2634 return [this.makeCode(o.level <= LEVEL_COND ? code : "(" + code + ")")];
2635 };
2636
2637 return Existence;
2638
2639 })(Base);
2640
2641 exports.Parens = Parens = (function(_super) {
2642 __extends(Parens, _super);
2643
2644 function Parens(body) {
2645 this.body = body;
2646 }
2647
2648 Parens.prototype.children = ['body'];
2649
2650 Parens.prototype.unwrap = function() {
2651 return this.body;
2652 };
2653
2654 Parens.prototype.isComplex = function() {
2655 return this.body.isComplex();
2656 };
2657
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);
2664 }
2665 fragments = expr.compileToFragments(o, LEVEL_PAREN);
2666 bare = o.level < LEVEL_OP && (expr instanceof Op || expr instanceof Call || (expr instanceof For && expr.returns));
2667 if (bare) {
2668 return fragments;
2669 } else {
2670 return this.wrapInBraces(fragments);
2671 }
2672 };
2673
2674 return Parens;
2675
2676 })(Base);
2677
2678 exports.For = For = (function(_super) {
2679 __extends(For, _super);
2680
2681 function For(body, source) {
2682 var _ref2;
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;
2687 if (this.object) {
2688 _ref2 = [this.index, this.name], this.name = _ref2[0], this.index = _ref2[1];
2689 }
2690 if (this.index instanceof Value) {
2691 this.index.error('index cannot be a pattern matching expression');
2692 }
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');
2697 }
2698 if (this.range && this.pattern) {
2699 this.name.error('cannot pattern match over range loops');
2700 }
2701 if (this.own && !this.object) {
2702 this.name.error('cannot use own with for-in');
2703 }
2704 this.returns = false;
2705 }
2706
2707 For.prototype.children = ['body', 'source', 'guard', 'step'];
2708
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;
2715 }
2716 source = this.range ? this.source.base : this.source;
2717 scope = o.scope;
2718 if (!this.pattern) {
2719 name = this.name && (this.name.compile(o, LEVEL_LIST));
2720 }
2721 index = this.index && (this.index.compile(o, LEVEL_LIST));
2722 if (name && !this.pattern) {
2723 scope.find(name);
2724 }
2725 if (index) {
2726 scope.find(index);
2727 }
2728 if (this.returns) {
2729 rvar = scope.freeVariable('results');
2730 }
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);
2737 }
2738 if (this.pattern) {
2739 name = ivar;
2740 }
2741 varPart = '';
2742 guardPart = '';
2743 defPart = '';
2744 idt1 = this.tab + TAB;
2745 if (this.range) {
2746 forPartFragments = source.compileToFragments(merge(o, {
2747 index: ivar,
2748 name: name,
2749 step: this.step
2750 }));
2751 } else {
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";
2755 svar = ref;
2756 }
2757 if (name && !this.pattern) {
2758 namePart = "" + name + " = " + svar + "[" + kvar + "]";
2759 }
2760 if (!this.object) {
2761 if (step !== stepVar) {
2762 defPart += "" + this.tab + step + ";\n";
2763 }
2764 if (!(this.step && stepNum && (down = parseNum(stepNum[0]) < 0))) {
2765 lvar = scope.freeVariable('len');
2766 }
2767 declare = "" + kvarAssign + ivar + " = 0, " + lvar + " = " + svar + ".length";
2768 declareDown = "" + kvarAssign + ivar + " = " + svar + ".length - 1";
2769 compare = "" + ivar + " < " + lvar;
2770 compareDown = "" + ivar + " >= 0";
2771 if (this.step) {
2772 if (stepNum) {
2773 if (down) {
2774 compare = compareDown;
2775 declare = declareDown;
2776 }
2777 } else {
2778 compare = "" + stepVar + " > 0 ? " + compare + " : " + compareDown;
2779 declare = "(" + stepVar + " > 0 ? (" + declare + ") : " + declareDown + ")";
2780 }
2781 increment = "" + ivar + " += " + stepVar;
2782 } else {
2783 increment = "" + (kvar !== ivar ? "++" + ivar : "" + ivar + "++");
2784 }
2785 forPartFragments = [this.makeCode("" + declare + "; " + compare + "; " + kvarAssign + increment)];
2786 }
2787 }
2788 if (this.returns) {
2789 resultPart = "" + this.tab + rvar + " = [];\n";
2790 returnResult = "\n" + this.tab + "return " + rvar + ";";
2791 body.makeReturn(rvar);
2792 }
2793 if (this.guard) {
2794 if (body.expressions.length > 1) {
2795 body.expressions.unshift(new If((new Parens(this.guard)).invert(), new Literal("continue")));
2796 } else {
2797 if (this.guard) {
2798 body = Block.wrap([new If(this.guard, body)]);
2799 }
2800 }
2801 }
2802 if (this.pattern) {
2803 body.expressions.unshift(new Assign(this.name, new Literal("" + svar + "[" + kvar + "]")));
2804 }
2805 defPartFragments = [].concat(this.makeCode(defPart), this.pluckDirectCall(o, body));
2806 if (namePart) {
2807 varPart = "\n" + idt1 + namePart + ";";
2808 }
2809 if (this.object) {
2810 forPartFragments = [this.makeCode("" + kvar + " in " + svar)];
2811 if (this.own) {
2812 guardPart = "\n" + idt1 + "if (!" + (utility('hasProp')) + ".call(" + svar + ", " + kvar + ")) continue;";
2813 }
2814 }
2815 bodyFragments = body.compileToFragments(merge(o, {
2816 indent: idt1
2817 }), LEVEL_TOP);
2818 if (bodyFragments && (bodyFragments.length > 0)) {
2819 bodyFragments = [].concat(this.makeCode("\n"), bodyFragments, this.makeCode("\n"));
2820 }
2821 return [].concat(defPartFragments, this.makeCode("" + (resultPart || '') + this.tab + "for ("), forPartFragments, this.makeCode(") {" + guardPart + varPart), bodyFragments, this.makeCode("" + this.tab + "}" + (returnResult || '')));
2822 };
2823
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;
2826 defs = [];
2827 _ref2 = body.expressions;
2828 for (idx = _i = 0, _len = _ref2.length; _i < _len; idx = ++_i) {
2829 expr = _ref2[idx];
2830 expr = expr.unwrapAll();
2831 if (!(expr instanceof Call)) {
2832 continue;
2833 }
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')))) {
2836 continue;
2837 }
2838 fn = ((_ref7 = val.base) != null ? _ref7.unwrapAll() : void 0) || val;
2839 ref = new Literal(o.scope.freeVariable('fn'));
2840 base = new Value(ref);
2841 if (val.base) {
2842 _ref8 = [base, val], val.base = _ref8[0], base = _ref8[1];
2843 }
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'));
2846 }
2847 return defs;
2848 };
2849
2850 return For;
2851
2852 })(While);
2853
2854 exports.Switch = Switch = (function(_super) {
2855 __extends(Switch, _super);
2856
2857 function Switch(subject, cases, otherwise) {
2858 this.subject = subject;
2859 this.cases = cases;
2860 this.otherwise = otherwise;
2861 }
2862
2863 Switch.prototype.children = ['subject', 'cases', 'otherwise'];
2864
2865 Switch.prototype.isStatement = YES;
2866
2867 Switch.prototype.jumps = function(o) {
2868 var block, conds, jumpNode, _i, _len, _ref2, _ref3, _ref4;
2869 if (o == null) {
2870 o = {
2871 block: true
2872 };
2873 }
2874 _ref2 = this.cases;
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)) {
2878 return jumpNode;
2879 }
2880 }
2881 return (_ref4 = this.otherwise) != null ? _ref4.jumps(o) : void 0;
2882 };
2883
2884 Switch.prototype.makeReturn = function(res) {
2885 var pair, _i, _len, _ref2, _ref3;
2886 _ref2 = this.cases;
2887 for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
2888 pair = _ref2[_i];
2889 pair[1].makeReturn(res);
2890 }
2891 if (res) {
2892 this.otherwise || (this.otherwise = new Block([new Literal('void 0')]));
2893 }
2894 if ((_ref3 = this.otherwise) != null) {
2895 _ref3.makeReturn(res);
2896 }
2897 return this;
2898 };
2899
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"));
2905 _ref2 = this.cases;
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++) {
2910 cond = _ref4[_j];
2911 if (!this.subject) {
2912 cond = cond.invert();
2913 }
2914 fragments = fragments.concat(this.makeCode(idt1 + "case "), cond.compileToFragments(o, LEVEL_PAREN), this.makeCode(":\n"));
2915 }
2916 if ((body = block.compileToFragments(o, LEVEL_TOP)).length > 0) {
2917 fragments = fragments.concat(body, this.makeCode('\n'));
2918 }
2919 if (i === this.cases.length - 1 && !this.otherwise) {
2920 break;
2921 }
2922 expr = this.lastNonComment(block.expressions);
2923 if (expr instanceof Return || (expr instanceof Literal && expr.jumps() && expr.value !== 'debugger')) {
2924 continue;
2925 }
2926 fragments.push(cond.makeCode(idt2 + 'break;\n'));
2927 }
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")]));
2930 }
2931 fragments.push(this.makeCode(this.tab + '}'));
2932 return fragments;
2933 };
2934
2935 return Switch;
2936
2937 })(Base);
2938
2939 exports.If = If = (function(_super) {
2940 __extends(If, _super);
2941
2942 function If(condition, body, options) {
2943 this.body = body;
2944 if (options == null) {
2945 options = {};
2946 }
2947 this.condition = options.type === 'unless' ? condition.invert() : condition;
2948 this.elseBody = null;
2949 this.isChain = false;
2950 this.soak = options.soak;
2951 }
2952
2953 If.prototype.children = ['condition', 'body', 'elseBody'];
2954
2955 If.prototype.bodyNode = function() {
2956 var _ref2;
2957 return (_ref2 = this.body) != null ? _ref2.unwrap() : void 0;
2958 };
2959
2960 If.prototype.elseBodyNode = function() {
2961 var _ref2;
2962 return (_ref2 = this.elseBody) != null ? _ref2.unwrap() : void 0;
2963 };
2964
2965 If.prototype.addElse = function(elseBody) {
2966 if (this.isChain) {
2967 this.elseBodyNode().addElse(elseBody);
2968 } else {
2969 this.isChain = elseBody instanceof If;
2970 this.elseBody = this.ensureBlock(elseBody);
2971 this.elseBody.updateLocationDataIfMissing(elseBody.locationData);
2972 }
2973 return this;
2974 };
2975
2976 If.prototype.isStatement = function(o) {
2977 var _ref2;
2978 return (o != null ? o.level : void 0) === LEVEL_TOP || this.bodyNode().isStatement(o) || ((_ref2 = this.elseBodyNode()) != null ? _ref2.isStatement(o) : void 0);
2979 };
2980
2981 If.prototype.jumps = function(o) {
2982 var _ref2;
2983 return this.body.jumps(o) || ((_ref2 = this.elseBody) != null ? _ref2.jumps(o) : void 0);
2984 };
2985
2986 If.prototype.compileNode = function(o) {
2987 if (this.isStatement(o)) {
2988 return this.compileStatement(o);
2989 } else {
2990 return this.compileExpression(o);
2991 }
2992 };
2993
2994 If.prototype.makeReturn = function(res) {
2995 if (res) {
2996 this.elseBody || (this.elseBody = new Block([new Literal('void 0')]));
2997 }
2998 this.body && (this.body = new Block([this.body.makeReturn(res)]));
2999 this.elseBody && (this.elseBody = new Block([this.elseBody.makeReturn(res)]));
3000 return this;
3001 };
3002
3003 If.prototype.ensureBlock = function(node) {
3004 if (node instanceof Block) {
3005 return node;
3006 } else {
3007 return new Block([node]);
3008 }
3009 };
3010
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');
3015 if (exeq) {
3016 return new If(this.condition.invert(), this.elseBodyNode(), {
3017 type: 'if'
3018 }).compileToFragments(o);
3019 }
3020 indent = o.indent + TAB;
3021 cond = this.condition.compileToFragments(o, LEVEL_PAREN);
3022 body = this.ensureBlock(this.body).compileToFragments(merge(o, {
3023 indent: indent
3024 }));
3025 ifPart = [].concat(this.makeCode("if ("), cond, this.makeCode(") {\n"), body, this.makeCode("\n" + this.tab + "}"));
3026 if (!child) {
3027 ifPart.unshift(this.makeCode(this.tab));
3028 }
3029 if (!this.elseBody) {
3030 return ifPart;
3031 }
3032 answer = ifPart.concat(this.makeCode(' else '));
3033 if (this.isChain) {
3034 o.chainChild = true;
3035 answer = answer.concat(this.elseBody.unwrap().compileToFragments(o, LEVEL_TOP));
3036 } else {
3037 answer = answer.concat(this.makeCode("{\n"), this.elseBody.compileToFragments(merge(o, {
3038 indent: indent
3039 }), LEVEL_TOP), this.makeCode("\n" + this.tab + "}"));
3040 }
3041 return answer;
3042 };
3043
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);
3052 } else {
3053 return fragments;
3054 }
3055 };
3056
3057 If.prototype.unfoldSoak = function() {
3058 return this.soak && this;
3059 };
3060
3061 return If;
3062
3063 })(Base);
3064
3065 UTILITIES = {
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; }";
3068 },
3069 bind: function() {
3070 return 'function(fn, me){ return function(){ return fn.apply(me, arguments); }; }';
3071 },
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; }";
3074 },
3075 modulo: function() {
3076 return "function(a, b) { return (+a % (b = +b) + b) % b; }";
3077 },
3078 hasProp: function() {
3079 return '{}.hasOwnProperty';
3080 },
3081 slice: function() {
3082 return '[].slice';
3083 }
3084 };
3085
3086 LEVEL_TOP = 1;
3087
3088 LEVEL_PAREN = 2;
3089
3090 LEVEL_LIST = 3;
3091
3092 LEVEL_COND = 4;
3093
3094 LEVEL_OP = 5;
3095
3096 LEVEL_ACCESS = 6;
3097
3098 TAB = ' ';
3099
3100 IDENTIFIER_STR = "[$A-Za-z_\\x7f-\\uffff][$\\w\\x7f-\\uffff]*";
3101
3102 IDENTIFIER = RegExp("^" + IDENTIFIER_STR + "$");
3103
3104 SIMPLENUM = /^[+-]?\d+$/;
3105
3106 HEXNUM = /^[+-]?0x[\da-f]+/i;
3107
3108 NUMBER = /^[+-]?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)$/i;
3109
3110 METHOD_DEF = RegExp("^(" + IDENTIFIER_STR + ")(\\.prototype)?(?:\\.(" + IDENTIFIER_STR + ")|\\[(\"(?:[^\\\\\"\\r\\n]|\\\\.)*\"|'(?:[^\\\\'\\r\\n]|\\\\.)*')\\]|\\[(0x[\\da-fA-F]+|\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\])$");
3111
3112 IS_STRING = /^['"]/;
3113
3114 IS_REGEX = /^\//;
3115
3116 utility = function(name) {
3117 var ref;
3118 ref = "__" + name;
3119 Scope.root.assign(ref, UTILITIES[name]());
3120 return ref;
3121 };
3122
3123 multident = function(code, tab) {
3124 code = code.replace(/\n/g, '$&' + tab);
3125 return code.replace(/\s+$/, '');
3126 };
3127
3128 parseNum = function(x) {
3129 if (x == null) {
3130 return 0;
3131 } else if (x.match(HEXNUM)) {
3132 return parseInt(x, 16);
3133 } else {
3134 return parseFloat(x);
3135 }
3136 };
3137
3138 isLiteralArguments = function(node) {
3139 return node instanceof Literal && node.value === 'arguments' && !node.asKey;
3140 };
3141
3142 isLiteralThis = function(node) {
3143 return (node instanceof Literal && node.value === 'this' && !node.asKey) || (node instanceof Code && node.bound) || (node instanceof Call && node.isSuper);
3144 };
3145
3146 unfoldSoak = function(o, parent, name) {
3147 var ifn;
3148 if (!(ifn = parent[name].unfoldSoak(o))) {
3149 return;
3150 }
3151 parent[name] = ifn.body;
3152 ifn.body = new Value(parent);
3153 return ifn;
3154 };
3155
3156 }).call(this);