"Fossies" - the Fresh Open Source Software Archive

Member "Atom/resources/app/apm/node_modules/coffee-script/lib/coffee-script/nodes.js" (8 Mar 2017, 106017 Bytes) of archive /windows/misc/atom-windows.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Javascript source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 // Generated by CoffeeScript 1.9.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     __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; },
    5     __hasProp = {}.hasOwnProperty,
    6     __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },
    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, parts;
   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       parts = (new Call(func, args)).compileNode(o);
  108       if (func.isGenerator) {
  109         parts.unshift(this.makeCode("(yield* "));
  110         parts.push(this.makeCode(")"));
  111       }
  112       return parts;
  113     };
  114 
  115     Base.prototype.cache = function(o, level, reused) {
  116       var ref, sub;
  117       if (!this.isComplex()) {
  118         ref = level ? this.compileToFragments(o, level) : this;
  119         return [ref, ref];
  120       } else {
  121         ref = new Literal(reused || o.scope.freeVariable('ref'));
  122         sub = new Assign(ref, this);
  123         if (level) {
  124           return [sub.compileToFragments(o, level), [this.makeCode(ref.value)]];
  125         } else {
  126           return [sub, ref];
  127         }
  128       }
  129     };
  130 
  131     Base.prototype.cacheToCodeFragments = function(cacheValues) {
  132       return [fragmentsToText(cacheValues[0]), fragmentsToText(cacheValues[1])];
  133     };
  134 
  135     Base.prototype.makeReturn = function(res) {
  136       var me;
  137       me = this.unwrapAll();
  138       if (res) {
  139         return new Call(new Literal(res + ".push"), [me]);
  140       } else {
  141         return new Return(me);
  142       }
  143     };
  144 
  145     Base.prototype.contains = function(pred) {
  146       var node;
  147       node = void 0;
  148       this.traverseChildren(false, function(n) {
  149         if (pred(n)) {
  150           node = n;
  151           return false;
  152         }
  153       });
  154       return node;
  155     };
  156 
  157     Base.prototype.lastNonComment = function(list) {
  158       var i;
  159       i = list.length;
  160       while (i--) {
  161         if (!(list[i] instanceof Comment)) {
  162           return list[i];
  163         }
  164       }
  165       return null;
  166     };
  167 
  168     Base.prototype.toString = function(idt, name) {
  169       var tree;
  170       if (idt == null) {
  171         idt = '';
  172       }
  173       if (name == null) {
  174         name = this.constructor.name;
  175       }
  176       tree = '\n' + idt + name;
  177       if (this.soak) {
  178         tree += '?';
  179       }
  180       this.eachChild(function(node) {
  181         return tree += node.toString(idt + TAB);
  182       });
  183       return tree;
  184     };
  185 
  186     Base.prototype.eachChild = function(func) {
  187       var attr, child, _i, _j, _len, _len1, _ref2, _ref3;
  188       if (!this.children) {
  189         return this;
  190       }
  191       _ref2 = this.children;
  192       for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
  193         attr = _ref2[_i];
  194         if (this[attr]) {
  195           _ref3 = flatten([this[attr]]);
  196           for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) {
  197             child = _ref3[_j];
  198             if (func(child) === false) {
  199               return this;
  200             }
  201           }
  202         }
  203       }
  204       return this;
  205     };
  206 
  207     Base.prototype.traverseChildren = function(crossScope, func) {
  208       return this.eachChild(function(child) {
  209         var recur;
  210         recur = func(child);
  211         if (recur !== false) {
  212           return child.traverseChildren(crossScope, func);
  213         }
  214       });
  215     };
  216 
  217     Base.prototype.invert = function() {
  218       return new Op('!', this);
  219     };
  220 
  221     Base.prototype.unwrapAll = function() {
  222       var node;
  223       node = this;
  224       while (node !== (node = node.unwrap())) {
  225         continue;
  226       }
  227       return node;
  228     };
  229 
  230     Base.prototype.children = [];
  231 
  232     Base.prototype.isStatement = NO;
  233 
  234     Base.prototype.jumps = NO;
  235 
  236     Base.prototype.isComplex = YES;
  237 
  238     Base.prototype.isChainable = NO;
  239 
  240     Base.prototype.isAssignable = NO;
  241 
  242     Base.prototype.unwrap = THIS;
  243 
  244     Base.prototype.unfoldSoak = NO;
  245 
  246     Base.prototype.assigns = NO;
  247 
  248     Base.prototype.updateLocationDataIfMissing = function(locationData) {
  249       if (this.locationData) {
  250         return this;
  251       }
  252       this.locationData = locationData;
  253       return this.eachChild(function(child) {
  254         return child.updateLocationDataIfMissing(locationData);
  255       });
  256     };
  257 
  258     Base.prototype.error = function(message) {
  259       return throwSyntaxError(message, this.locationData);
  260     };
  261 
  262     Base.prototype.makeCode = function(code) {
  263       return new CodeFragment(this, code);
  264     };
  265 
  266     Base.prototype.wrapInBraces = function(fragments) {
  267       return [].concat(this.makeCode('('), fragments, this.makeCode(')'));
  268     };
  269 
  270     Base.prototype.joinFragmentArrays = function(fragmentsList, joinStr) {
  271       var answer, fragments, i, _i, _len;
  272       answer = [];
  273       for (i = _i = 0, _len = fragmentsList.length; _i < _len; i = ++_i) {
  274         fragments = fragmentsList[i];
  275         if (i) {
  276           answer.push(this.makeCode(joinStr));
  277         }
  278         answer = answer.concat(fragments);
  279       }
  280       return answer;
  281     };
  282 
  283     return Base;
  284 
  285   })();
  286 
  287   exports.Block = Block = (function(_super) {
  288     __extends(Block, _super);
  289 
  290     function Block(nodes) {
  291       this.expressions = compact(flatten(nodes || []));
  292     }
  293 
  294     Block.prototype.children = ['expressions'];
  295 
  296     Block.prototype.push = function(node) {
  297       this.expressions.push(node);
  298       return this;
  299     };
  300 
  301     Block.prototype.pop = function() {
  302       return this.expressions.pop();
  303     };
  304 
  305     Block.prototype.unshift = function(node) {
  306       this.expressions.unshift(node);
  307       return this;
  308     };
  309 
  310     Block.prototype.unwrap = function() {
  311       if (this.expressions.length === 1) {
  312         return this.expressions[0];
  313       } else {
  314         return this;
  315       }
  316     };
  317 
  318     Block.prototype.isEmpty = function() {
  319       return !this.expressions.length;
  320     };
  321 
  322     Block.prototype.isStatement = function(o) {
  323       var exp, _i, _len, _ref2;
  324       _ref2 = this.expressions;
  325       for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
  326         exp = _ref2[_i];
  327         if (exp.isStatement(o)) {
  328           return true;
  329         }
  330       }
  331       return false;
  332     };
  333 
  334     Block.prototype.jumps = function(o) {
  335       var exp, jumpNode, _i, _len, _ref2;
  336       _ref2 = this.expressions;
  337       for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
  338         exp = _ref2[_i];
  339         if (jumpNode = exp.jumps(o)) {
  340           return jumpNode;
  341         }
  342       }
  343     };
  344 
  345     Block.prototype.makeReturn = function(res) {
  346       var expr, len;
  347       len = this.expressions.length;
  348       while (len--) {
  349         expr = this.expressions[len];
  350         if (!(expr instanceof Comment)) {
  351           this.expressions[len] = expr.makeReturn(res);
  352           if (expr instanceof Return && !expr.expression) {
  353             this.expressions.splice(len, 1);
  354           }
  355           break;
  356         }
  357       }
  358       return this;
  359     };
  360 
  361     Block.prototype.compileToFragments = function(o, level) {
  362       if (o == null) {
  363         o = {};
  364       }
  365       if (o.scope) {
  366         return Block.__super__.compileToFragments.call(this, o, level);
  367       } else {
  368         return this.compileRoot(o);
  369       }
  370     };
  371 
  372     Block.prototype.compileNode = function(o) {
  373       var answer, compiledNodes, fragments, index, node, top, _i, _len, _ref2;
  374       this.tab = o.indent;
  375       top = o.level === LEVEL_TOP;
  376       compiledNodes = [];
  377       _ref2 = this.expressions;
  378       for (index = _i = 0, _len = _ref2.length; _i < _len; index = ++_i) {
  379         node = _ref2[index];
  380         node = node.unwrapAll();
  381         node = node.unfoldSoak(o) || node;
  382         if (node instanceof Block) {
  383           compiledNodes.push(node.compileNode(o));
  384         } else if (top) {
  385           node.front = true;
  386           fragments = node.compileToFragments(o);
  387           if (!node.isStatement(o)) {
  388             fragments.unshift(this.makeCode("" + this.tab));
  389             fragments.push(this.makeCode(";"));
  390           }
  391           compiledNodes.push(fragments);
  392         } else {
  393           compiledNodes.push(node.compileToFragments(o, LEVEL_LIST));
  394         }
  395       }
  396       if (top) {
  397         if (this.spaced) {
  398           return [].concat(this.joinFragmentArrays(compiledNodes, '\n\n'), this.makeCode("\n"));
  399         } else {
  400           return this.joinFragmentArrays(compiledNodes, '\n');
  401         }
  402       }
  403       if (compiledNodes.length) {
  404         answer = this.joinFragmentArrays(compiledNodes, ', ');
  405       } else {
  406         answer = [this.makeCode("void 0")];
  407       }
  408       if (compiledNodes.length > 1 && o.level >= LEVEL_LIST) {
  409         return this.wrapInBraces(answer);
  410       } else {
  411         return answer;
  412       }
  413     };
  414 
  415     Block.prototype.compileRoot = function(o) {
  416       var exp, fragments, i, name, prelude, preludeExps, rest, _i, _len, _ref2, _ref3;
  417       o.indent = o.bare ? '' : TAB;
  418       o.level = LEVEL_TOP;
  419       this.spaced = true;
  420       o.scope = new Scope(null, this, null, (_ref2 = o.referencedVars) != null ? _ref2 : []);
  421       _ref3 = o.locals || [];
  422       for (_i = 0, _len = _ref3.length; _i < _len; _i++) {
  423         name = _ref3[_i];
  424         o.scope.parameter(name);
  425       }
  426       prelude = [];
  427       if (!o.bare) {
  428         preludeExps = (function() {
  429           var _j, _len1, _ref4, _results;
  430           _ref4 = this.expressions;
  431           _results = [];
  432           for (i = _j = 0, _len1 = _ref4.length; _j < _len1; i = ++_j) {
  433             exp = _ref4[i];
  434             if (!(exp.unwrap() instanceof Comment)) {
  435               break;
  436             }
  437             _results.push(exp);
  438           }
  439           return _results;
  440         }).call(this);
  441         rest = this.expressions.slice(preludeExps.length);
  442         this.expressions = preludeExps;
  443         if (preludeExps.length) {
  444           prelude = this.compileNode(merge(o, {
  445             indent: ''
  446           }));
  447           prelude.push(this.makeCode("\n"));
  448         }
  449         this.expressions = rest;
  450       }
  451       fragments = this.compileWithDeclarations(o);
  452       if (o.bare) {
  453         return fragments;
  454       }
  455       return [].concat(prelude, this.makeCode("(function() {\n"), fragments, this.makeCode("\n}).call(this);\n"));
  456     };
  457 
  458     Block.prototype.compileWithDeclarations = function(o) {
  459       var assigns, declars, exp, fragments, i, post, rest, scope, spaced, _i, _len, _ref2, _ref3, _ref4;
  460       fragments = [];
  461       post = [];
  462       _ref2 = this.expressions;
  463       for (i = _i = 0, _len = _ref2.length; _i < _len; i = ++_i) {
  464         exp = _ref2[i];
  465         exp = exp.unwrap();
  466         if (!(exp instanceof Comment || exp instanceof Literal)) {
  467           break;
  468         }
  469       }
  470       o = merge(o, {
  471         level: LEVEL_TOP
  472       });
  473       if (i) {
  474         rest = this.expressions.splice(i, 9e9);
  475         _ref3 = [this.spaced, false], spaced = _ref3[0], this.spaced = _ref3[1];
  476         _ref4 = [this.compileNode(o), spaced], fragments = _ref4[0], this.spaced = _ref4[1];
  477         this.expressions = rest;
  478       }
  479       post = this.compileNode(o);
  480       scope = o.scope;
  481       if (scope.expressions === this) {
  482         declars = o.scope.hasDeclarations();
  483         assigns = scope.hasAssignments;
  484         if (declars || assigns) {
  485           if (i) {
  486             fragments.push(this.makeCode('\n'));
  487           }
  488           fragments.push(this.makeCode(this.tab + "var "));
  489           if (declars) {
  490             fragments.push(this.makeCode(scope.declaredVariables().join(', ')));
  491           }
  492           if (assigns) {
  493             if (declars) {
  494               fragments.push(this.makeCode(",\n" + (this.tab + TAB)));
  495             }
  496             fragments.push(this.makeCode(scope.assignedVariables().join(",\n" + (this.tab + TAB))));
  497           }
  498           fragments.push(this.makeCode(";\n" + (this.spaced ? '\n' : '')));
  499         } else if (fragments.length && post.length) {
  500           fragments.push(this.makeCode("\n"));
  501         }
  502       }
  503       return fragments.concat(post);
  504     };
  505 
  506     Block.wrap = function(nodes) {
  507       if (nodes.length === 1 && nodes[0] instanceof Block) {
  508         return nodes[0];
  509       }
  510       return new Block(nodes);
  511     };
  512 
  513     return Block;
  514 
  515   })(Base);
  516 
  517   exports.Literal = Literal = (function(_super) {
  518     __extends(Literal, _super);
  519 
  520     function Literal(_at_value) {
  521       this.value = _at_value;
  522     }
  523 
  524     Literal.prototype.makeReturn = function() {
  525       if (this.isStatement()) {
  526         return this;
  527       } else {
  528         return Literal.__super__.makeReturn.apply(this, arguments);
  529       }
  530     };
  531 
  532     Literal.prototype.isAssignable = function() {
  533       return IDENTIFIER.test(this.value);
  534     };
  535 
  536     Literal.prototype.isStatement = function() {
  537       var _ref2;
  538       return (_ref2 = this.value) === 'break' || _ref2 === 'continue' || _ref2 === 'debugger';
  539     };
  540 
  541     Literal.prototype.isComplex = NO;
  542 
  543     Literal.prototype.assigns = function(name) {
  544       return name === this.value;
  545     };
  546 
  547     Literal.prototype.jumps = function(o) {
  548       if (this.value === 'break' && !((o != null ? o.loop : void 0) || (o != null ? o.block : void 0))) {
  549         return this;
  550       }
  551       if (this.value === 'continue' && !(o != null ? o.loop : void 0)) {
  552         return this;
  553       }
  554     };
  555 
  556     Literal.prototype.compileNode = function(o) {
  557       var answer, code, _ref2;
  558       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;
  559       answer = this.isStatement() ? "" + this.tab + code + ";" : code;
  560       return [this.makeCode(answer)];
  561     };
  562 
  563     Literal.prototype.toString = function() {
  564       return ' "' + this.value + '"';
  565     };
  566 
  567     return Literal;
  568 
  569   })(Base);
  570 
  571   exports.Undefined = (function(_super) {
  572     __extends(Undefined, _super);
  573 
  574     function Undefined() {
  575       return Undefined.__super__.constructor.apply(this, arguments);
  576     }
  577 
  578     Undefined.prototype.isAssignable = NO;
  579 
  580     Undefined.prototype.isComplex = NO;
  581 
  582     Undefined.prototype.compileNode = function(o) {
  583       return [this.makeCode(o.level >= LEVEL_ACCESS ? '(void 0)' : 'void 0')];
  584     };
  585 
  586     return Undefined;
  587 
  588   })(Base);
  589 
  590   exports.Null = (function(_super) {
  591     __extends(Null, _super);
  592 
  593     function Null() {
  594       return Null.__super__.constructor.apply(this, arguments);
  595     }
  596 
  597     Null.prototype.isAssignable = NO;
  598 
  599     Null.prototype.isComplex = NO;
  600 
  601     Null.prototype.compileNode = function() {
  602       return [this.makeCode("null")];
  603     };
  604 
  605     return Null;
  606 
  607   })(Base);
  608 
  609   exports.Bool = (function(_super) {
  610     __extends(Bool, _super);
  611 
  612     Bool.prototype.isAssignable = NO;
  613 
  614     Bool.prototype.isComplex = NO;
  615 
  616     Bool.prototype.compileNode = function() {
  617       return [this.makeCode(this.val)];
  618     };
  619 
  620     function Bool(_at_val) {
  621       this.val = _at_val;
  622     }
  623 
  624     return Bool;
  625 
  626   })(Base);
  627 
  628   exports.Return = Return = (function(_super) {
  629     __extends(Return, _super);
  630 
  631     function Return(_at_expression) {
  632       this.expression = _at_expression;
  633     }
  634 
  635     Return.prototype.children = ['expression'];
  636 
  637     Return.prototype.isStatement = YES;
  638 
  639     Return.prototype.makeReturn = THIS;
  640 
  641     Return.prototype.jumps = THIS;
  642 
  643     Return.prototype.compileToFragments = function(o, level) {
  644       var expr, _ref2;
  645       expr = (_ref2 = this.expression) != null ? _ref2.makeReturn() : void 0;
  646       if (expr && !(expr instanceof Return)) {
  647         return expr.compileToFragments(o, level);
  648       } else {
  649         return Return.__super__.compileToFragments.call(this, o, level);
  650       }
  651     };
  652 
  653     Return.prototype.compileNode = function(o) {
  654       var answer;
  655       answer = [];
  656       answer.push(this.makeCode(this.tab + ("return" + (this.expression ? " " : ""))));
  657       if (this.expression) {
  658         answer = answer.concat(this.expression.compileToFragments(o, LEVEL_PAREN));
  659       }
  660       answer.push(this.makeCode(";"));
  661       return answer;
  662     };
  663 
  664     return Return;
  665 
  666   })(Base);
  667 
  668   exports.Value = Value = (function(_super) {
  669     __extends(Value, _super);
  670 
  671     function Value(base, props, tag) {
  672       if (!props && base instanceof Value) {
  673         return base;
  674       }
  675       this.base = base;
  676       this.properties = props || [];
  677       if (tag) {
  678         this[tag] = true;
  679       }
  680       return this;
  681     }
  682 
  683     Value.prototype.children = ['base', 'properties'];
  684 
  685     Value.prototype.add = function(props) {
  686       this.properties = this.properties.concat(props);
  687       return this;
  688     };
  689 
  690     Value.prototype.hasProperties = function() {
  691       return !!this.properties.length;
  692     };
  693 
  694     Value.prototype.bareLiteral = function(type) {
  695       return !this.properties.length && this.base instanceof type;
  696     };
  697 
  698     Value.prototype.isArray = function() {
  699       return this.bareLiteral(Arr);
  700     };
  701 
  702     Value.prototype.isRange = function() {
  703       return this.bareLiteral(Range);
  704     };
  705 
  706     Value.prototype.isComplex = function() {
  707       return this.hasProperties() || this.base.isComplex();
  708     };
  709 
  710     Value.prototype.isAssignable = function() {
  711       return this.hasProperties() || this.base.isAssignable();
  712     };
  713 
  714     Value.prototype.isSimpleNumber = function() {
  715       return this.bareLiteral(Literal) && SIMPLENUM.test(this.base.value);
  716     };
  717 
  718     Value.prototype.isString = function() {
  719       return this.bareLiteral(Literal) && IS_STRING.test(this.base.value);
  720     };
  721 
  722     Value.prototype.isRegex = function() {
  723       return this.bareLiteral(Literal) && IS_REGEX.test(this.base.value);
  724     };
  725 
  726     Value.prototype.isAtomic = function() {
  727       var node, _i, _len, _ref2;
  728       _ref2 = this.properties.concat(this.base);
  729       for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
  730         node = _ref2[_i];
  731         if (node.soak || node instanceof Call) {
  732           return false;
  733         }
  734       }
  735       return true;
  736     };
  737 
  738     Value.prototype.isNotCallable = function() {
  739       return this.isSimpleNumber() || this.isString() || this.isRegex() || this.isArray() || this.isRange() || this.isSplice() || this.isObject();
  740     };
  741 
  742     Value.prototype.isStatement = function(o) {
  743       return !this.properties.length && this.base.isStatement(o);
  744     };
  745 
  746     Value.prototype.assigns = function(name) {
  747       return !this.properties.length && this.base.assigns(name);
  748     };
  749 
  750     Value.prototype.jumps = function(o) {
  751       return !this.properties.length && this.base.jumps(o);
  752     };
  753 
  754     Value.prototype.isObject = function(onlyGenerated) {
  755       if (this.properties.length) {
  756         return false;
  757       }
  758       return (this.base instanceof Obj) && (!onlyGenerated || this.base.generated);
  759     };
  760 
  761     Value.prototype.isSplice = function() {
  762       return last(this.properties) instanceof Slice;
  763     };
  764 
  765     Value.prototype.looksStatic = function(className) {
  766       var _ref2;
  767       return this.base.value === className && this.properties.length && ((_ref2 = this.properties[0].name) != null ? _ref2.value : void 0) !== 'prototype';
  768     };
  769 
  770     Value.prototype.unwrap = function() {
  771       if (this.properties.length) {
  772         return this;
  773       } else {
  774         return this.base;
  775       }
  776     };
  777 
  778     Value.prototype.cacheReference = function(o) {
  779       var base, bref, name, nref;
  780       name = last(this.properties);
  781       if (this.properties.length < 2 && !this.base.isComplex() && !(name != null ? name.isComplex() : void 0)) {
  782         return [this, this];
  783       }
  784       base = new Value(this.base, this.properties.slice(0, -1));
  785       if (base.isComplex()) {
  786         bref = new Literal(o.scope.freeVariable('base'));
  787         base = new Value(new Parens(new Assign(bref, base)));
  788       }
  789       if (!name) {
  790         return [base, bref];
  791       }
  792       if (name.isComplex()) {
  793         nref = new Literal(o.scope.freeVariable('name'));
  794         name = new Index(new Assign(nref, name.index));
  795         nref = new Index(nref);
  796       }
  797       return [base.add(name), new Value(bref || base.base, [nref || name])];
  798     };
  799 
  800     Value.prototype.compileNode = function(o) {
  801       var fragments, prop, props, _i, _len;
  802       this.base.front = this.front;
  803       props = this.properties;
  804       fragments = this.base.compileToFragments(o, (props.length ? LEVEL_ACCESS : null));
  805       if ((this.base instanceof Parens || props.length) && SIMPLENUM.test(fragmentsToText(fragments))) {
  806         fragments.push(this.makeCode('.'));
  807       }
  808       for (_i = 0, _len = props.length; _i < _len; _i++) {
  809         prop = props[_i];
  810         fragments.push.apply(fragments, prop.compileToFragments(o));
  811       }
  812       return fragments;
  813     };
  814 
  815     Value.prototype.unfoldSoak = function(o) {
  816       return this.unfoldedSoak != null ? this.unfoldedSoak : this.unfoldedSoak = (function(_this) {
  817         return function() {
  818           var fst, i, ifn, prop, ref, snd, _i, _len, _ref2, _ref3;
  819           if (ifn = _this.base.unfoldSoak(o)) {
  820             (_ref2 = ifn.body.properties).push.apply(_ref2, _this.properties);
  821             return ifn;
  822           }
  823           _ref3 = _this.properties;
  824           for (i = _i = 0, _len = _ref3.length; _i < _len; i = ++_i) {
  825             prop = _ref3[i];
  826             if (!prop.soak) {
  827               continue;
  828             }
  829             prop.soak = false;
  830             fst = new Value(_this.base, _this.properties.slice(0, i));
  831             snd = new Value(_this.base, _this.properties.slice(i));
  832             if (fst.isComplex()) {
  833               ref = new Literal(o.scope.freeVariable('ref'));
  834               fst = new Parens(new Assign(ref, fst));
  835               snd.base = ref;
  836             }
  837             return new If(new Existence(fst), snd, {
  838               soak: true
  839             });
  840           }
  841           return false;
  842         };
  843       })(this)();
  844     };
  845 
  846     return Value;
  847 
  848   })(Base);
  849 
  850   exports.Comment = Comment = (function(_super) {
  851     __extends(Comment, _super);
  852 
  853     function Comment(_at_comment) {
  854       this.comment = _at_comment;
  855     }
  856 
  857     Comment.prototype.isStatement = YES;
  858 
  859     Comment.prototype.makeReturn = THIS;
  860 
  861     Comment.prototype.compileNode = function(o, level) {
  862       var code, comment;
  863       comment = this.comment.replace(/^(\s*)# /gm, "$1 * ");
  864       code = "/*" + (multident(comment, this.tab)) + (__indexOf.call(comment, '\n') >= 0 ? "\n" + this.tab : '') + " */";
  865       if ((level || o.level) === LEVEL_TOP) {
  866         code = o.indent + code;
  867       }
  868       return [this.makeCode("\n"), this.makeCode(code)];
  869     };
  870 
  871     return Comment;
  872 
  873   })(Base);
  874 
  875   exports.Call = Call = (function(_super) {
  876     __extends(Call, _super);
  877 
  878     function Call(variable, _at_args, _at_soak) {
  879       this.args = _at_args != null ? _at_args : [];
  880       this.soak = _at_soak;
  881       this.isNew = false;
  882       this.isSuper = variable === 'super';
  883       this.variable = this.isSuper ? null : variable;
  884       if (variable instanceof Value && variable.isNotCallable()) {
  885         variable.error("literal is not a function");
  886       }
  887     }
  888 
  889     Call.prototype.children = ['variable', 'args'];
  890 
  891     Call.prototype.newInstance = function() {
  892       var base, _ref2;
  893       base = ((_ref2 = this.variable) != null ? _ref2.base : void 0) || this.variable;
  894       if (base instanceof Call && !base.isNew) {
  895         base.newInstance();
  896       } else {
  897         this.isNew = true;
  898       }
  899       return this;
  900     };
  901 
  902     Call.prototype.superReference = function(o) {
  903       var accesses, method;
  904       method = o.scope.namedMethod();
  905       if (method != null ? method.klass : void 0) {
  906         accesses = [new Access(new Literal('__super__'))];
  907         if (method["static"]) {
  908           accesses.push(new Access(new Literal('constructor')));
  909         }
  910         accesses.push(new Access(new Literal(method.name)));
  911         return (new Value(new Literal(method.klass), accesses)).compile(o);
  912       } else if (method != null ? method.ctor : void 0) {
  913         return method.name + ".__super__.constructor";
  914       } else {
  915         return this.error('cannot call super outside of an instance method.');
  916       }
  917     };
  918 
  919     Call.prototype.superThis = function(o) {
  920       var method;
  921       method = o.scope.method;
  922       return (method && !method.klass && method.context) || "this";
  923     };
  924 
  925     Call.prototype.unfoldSoak = function(o) {
  926       var call, ifn, left, list, rite, _i, _len, _ref2, _ref3;
  927       if (this.soak) {
  928         if (this.variable) {
  929           if (ifn = unfoldSoak(o, this, 'variable')) {
  930             return ifn;
  931           }
  932           _ref2 = new Value(this.variable).cacheReference(o), left = _ref2[0], rite = _ref2[1];
  933         } else {
  934           left = new Literal(this.superReference(o));
  935           rite = new Value(left);
  936         }
  937         rite = new Call(rite, this.args);
  938         rite.isNew = this.isNew;
  939         left = new Literal("typeof " + (left.compile(o)) + " === \"function\"");
  940         return new If(left, new Value(rite), {
  941           soak: true
  942         });
  943       }
  944       call = this;
  945       list = [];
  946       while (true) {
  947         if (call.variable instanceof Call) {
  948           list.push(call);
  949           call = call.variable;
  950           continue;
  951         }
  952         if (!(call.variable instanceof Value)) {
  953           break;
  954         }
  955         list.push(call);
  956         if (!((call = call.variable.base) instanceof Call)) {
  957           break;
  958         }
  959       }
  960       _ref3 = list.reverse();
  961       for (_i = 0, _len = _ref3.length; _i < _len; _i++) {
  962         call = _ref3[_i];
  963         if (ifn) {
  964           if (call.variable instanceof Call) {
  965             call.variable = ifn;
  966           } else {
  967             call.variable.base = ifn;
  968           }
  969         }
  970         ifn = unfoldSoak(o, call, 'variable');
  971       }
  972       return ifn;
  973     };
  974 
  975     Call.prototype.compileNode = function(o) {
  976       var arg, argIndex, compiledArgs, compiledArray, fragments, preface, _i, _len, _ref2, _ref3;
  977       if ((_ref2 = this.variable) != null) {
  978         _ref2.front = this.front;
  979       }
  980       compiledArray = Splat.compileSplattedArray(o, this.args, true);
  981       if (compiledArray.length) {
  982         return this.compileSplat(o, compiledArray);
  983       }
  984       compiledArgs = [];
  985       _ref3 = this.args;
  986       for (argIndex = _i = 0, _len = _ref3.length; _i < _len; argIndex = ++_i) {
  987         arg = _ref3[argIndex];
  988         if (argIndex) {
  989           compiledArgs.push(this.makeCode(", "));
  990         }
  991         compiledArgs.push.apply(compiledArgs, arg.compileToFragments(o, LEVEL_LIST));
  992       }
  993       fragments = [];
  994       if (this.isSuper) {
  995         preface = this.superReference(o) + (".call(" + (this.superThis(o)));
  996         if (compiledArgs.length) {
  997           preface += ", ";
  998         }
  999         fragments.push(this.makeCode(preface));
 1000       } else {
 1001         if (this.isNew) {
 1002           fragments.push(this.makeCode('new '));
 1003         }
 1004         fragments.push.apply(fragments, this.variable.compileToFragments(o, LEVEL_ACCESS));
 1005         fragments.push(this.makeCode("("));
 1006       }
 1007       fragments.push.apply(fragments, compiledArgs);
 1008       fragments.push(this.makeCode(")"));
 1009       return fragments;
 1010     };
 1011 
 1012     Call.prototype.compileSplat = function(o, splatArgs) {
 1013       var answer, base, fun, idt, name, ref;
 1014       if (this.isSuper) {
 1015         return [].concat(this.makeCode((this.superReference(o)) + ".apply(" + (this.superThis(o)) + ", "), splatArgs, this.makeCode(")"));
 1016       }
 1017       if (this.isNew) {
 1018         idt = this.tab + TAB;
 1019         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(){})"));
 1020       }
 1021       answer = [];
 1022       base = new Value(this.variable);
 1023       if ((name = base.properties.pop()) && base.isComplex()) {
 1024         ref = o.scope.freeVariable('ref');
 1025         answer = answer.concat(this.makeCode("(" + ref + " = "), base.compileToFragments(o, LEVEL_LIST), this.makeCode(")"), name.compileToFragments(o));
 1026       } else {
 1027         fun = base.compileToFragments(o, LEVEL_ACCESS);
 1028         if (SIMPLENUM.test(fragmentsToText(fun))) {
 1029           fun = this.wrapInBraces(fun);
 1030         }
 1031         if (name) {
 1032           ref = fragmentsToText(fun);
 1033           fun.push.apply(fun, name.compileToFragments(o));
 1034         } else {
 1035           ref = 'null';
 1036         }
 1037         answer = answer.concat(fun);
 1038       }
 1039       return answer = answer.concat(this.makeCode(".apply(" + ref + ", "), splatArgs, this.makeCode(")"));
 1040     };
 1041 
 1042     return Call;
 1043 
 1044   })(Base);
 1045 
 1046   exports.Extends = Extends = (function(_super) {
 1047     __extends(Extends, _super);
 1048 
 1049     function Extends(_at_child, _at_parent) {
 1050       this.child = _at_child;
 1051       this.parent = _at_parent;
 1052     }
 1053 
 1054     Extends.prototype.children = ['child', 'parent'];
 1055 
 1056     Extends.prototype.compileToFragments = function(o) {
 1057       return new Call(new Value(new Literal(utility('extends', o))), [this.child, this.parent]).compileToFragments(o);
 1058     };
 1059 
 1060     return Extends;
 1061 
 1062   })(Base);
 1063 
 1064   exports.Access = Access = (function(_super) {
 1065     __extends(Access, _super);
 1066 
 1067     function Access(_at_name, tag) {
 1068       this.name = _at_name;
 1069       this.name.asKey = true;
 1070       this.soak = tag === 'soak';
 1071     }
 1072 
 1073     Access.prototype.children = ['name'];
 1074 
 1075     Access.prototype.compileToFragments = function(o) {
 1076       var name;
 1077       name = this.name.compileToFragments(o);
 1078       if (IDENTIFIER.test(fragmentsToText(name))) {
 1079         name.unshift(this.makeCode("."));
 1080       } else {
 1081         name.unshift(this.makeCode("["));
 1082         name.push(this.makeCode("]"));
 1083       }
 1084       return name;
 1085     };
 1086 
 1087     Access.prototype.isComplex = NO;
 1088 
 1089     return Access;
 1090 
 1091   })(Base);
 1092 
 1093   exports.Index = Index = (function(_super) {
 1094     __extends(Index, _super);
 1095 
 1096     function Index(_at_index) {
 1097       this.index = _at_index;
 1098     }
 1099 
 1100     Index.prototype.children = ['index'];
 1101 
 1102     Index.prototype.compileToFragments = function(o) {
 1103       return [].concat(this.makeCode("["), this.index.compileToFragments(o, LEVEL_PAREN), this.makeCode("]"));
 1104     };
 1105 
 1106     Index.prototype.isComplex = function() {
 1107       return this.index.isComplex();
 1108     };
 1109 
 1110     return Index;
 1111 
 1112   })(Base);
 1113 
 1114   exports.Range = Range = (function(_super) {
 1115     __extends(Range, _super);
 1116 
 1117     Range.prototype.children = ['from', 'to'];
 1118 
 1119     function Range(_at_from, _at_to, tag) {
 1120       this.from = _at_from;
 1121       this.to = _at_to;
 1122       this.exclusive = tag === 'exclusive';
 1123       this.equals = this.exclusive ? '' : '=';
 1124     }
 1125 
 1126     Range.prototype.compileVariables = function(o) {
 1127       var step, _ref2, _ref3, _ref4, _ref5;
 1128       o = merge(o, {
 1129         top: true
 1130       });
 1131       _ref2 = this.cacheToCodeFragments(this.from.cache(o, LEVEL_LIST)), this.fromC = _ref2[0], this.fromVar = _ref2[1];
 1132       _ref3 = this.cacheToCodeFragments(this.to.cache(o, LEVEL_LIST)), this.toC = _ref3[0], this.toVar = _ref3[1];
 1133       if (step = del(o, 'step')) {
 1134         _ref4 = this.cacheToCodeFragments(step.cache(o, LEVEL_LIST)), this.step = _ref4[0], this.stepVar = _ref4[1];
 1135       }
 1136       _ref5 = [this.fromVar.match(NUMBER), this.toVar.match(NUMBER)], this.fromNum = _ref5[0], this.toNum = _ref5[1];
 1137       if (this.stepVar) {
 1138         return this.stepNum = this.stepVar.match(NUMBER);
 1139       }
 1140     };
 1141 
 1142     Range.prototype.compileNode = function(o) {
 1143       var cond, condPart, from, gt, idx, idxName, known, lt, namedIndex, stepPart, to, varPart, _ref2, _ref3;
 1144       if (!this.fromVar) {
 1145         this.compileVariables(o);
 1146       }
 1147       if (!o.index) {
 1148         return this.compileArray(o);
 1149       }
 1150       known = this.fromNum && this.toNum;
 1151       idx = del(o, 'index');
 1152       idxName = del(o, 'name');
 1153       namedIndex = idxName && idxName !== idx;
 1154       varPart = idx + " = " + this.fromC;
 1155       if (this.toC !== this.toVar) {
 1156         varPart += ", " + this.toC;
 1157       }
 1158       if (this.step !== this.stepVar) {
 1159         varPart += ", " + this.step;
 1160       }
 1161       _ref2 = [idx + " <" + this.equals, idx + " >" + this.equals], lt = _ref2[0], gt = _ref2[1];
 1162       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);
 1163       stepPart = this.stepVar ? idx + " += " + this.stepVar : known ? namedIndex ? from <= to ? "++" + idx : "--" + idx : from <= to ? idx + "++" : idx + "--" : namedIndex ? cond + " ? ++" + idx + " : --" + idx : cond + " ? " + idx + "++ : " + idx + "--";
 1164       if (namedIndex) {
 1165         varPart = idxName + " = " + varPart;
 1166       }
 1167       if (namedIndex) {
 1168         stepPart = idxName + " = " + stepPart;
 1169       }
 1170       return [this.makeCode(varPart + "; " + condPart + "; " + stepPart)];
 1171     };
 1172 
 1173     Range.prototype.compileArray = function(o) {
 1174       var args, body, cond, hasArgs, i, idt, post, pre, range, result, vars, _i, _ref2, _ref3, _results;
 1175       if (this.fromNum && this.toNum && Math.abs(this.fromNum - this.toNum) <= 20) {
 1176         range = (function() {
 1177           _results = [];
 1178           for (var _i = _ref2 = +this.fromNum, _ref3 = +this.toNum; _ref2 <= _ref3 ? _i <= _ref3 : _i >= _ref3; _ref2 <= _ref3 ? _i++ : _i--){ _results.push(_i); }
 1179           return _results;
 1180         }).apply(this);
 1181         if (this.exclusive) {
 1182           range.pop();
 1183         }
 1184         return [this.makeCode("[" + (range.join(', ')) + "]")];
 1185       }
 1186       idt = this.tab + TAB;
 1187       i = o.scope.freeVariable('i');
 1188       result = o.scope.freeVariable('results');
 1189       pre = "\n" + idt + result + " = [];";
 1190       if (this.fromNum && this.toNum) {
 1191         o.index = i;
 1192         body = fragmentsToText(this.compileNode(o));
 1193       } else {
 1194         vars = (i + " = " + this.fromC) + (this.toC !== this.toVar ? ", " + this.toC : '');
 1195         cond = this.fromVar + " <= " + this.toVar;
 1196         body = "var " + vars + "; " + cond + " ? " + i + " <" + this.equals + " " + this.toVar + " : " + i + " >" + this.equals + " " + this.toVar + "; " + cond + " ? " + i + "++ : " + i + "--";
 1197       }
 1198       post = "{ " + result + ".push(" + i + "); }\n" + idt + "return " + result + ";\n" + o.indent;
 1199       hasArgs = function(node) {
 1200         return node != null ? node.contains(isLiteralArguments) : void 0;
 1201       };
 1202       if (hasArgs(this.from) || hasArgs(this.to)) {
 1203         args = ', arguments';
 1204       }
 1205       return [this.makeCode("(function() {" + pre + "\n" + idt + "for (" + body + ")" + post + "}).apply(this" + (args != null ? args : '') + ")")];
 1206     };
 1207 
 1208     return Range;
 1209 
 1210   })(Base);
 1211 
 1212   exports.Slice = Slice = (function(_super) {
 1213     __extends(Slice, _super);
 1214 
 1215     Slice.prototype.children = ['range'];
 1216 
 1217     function Slice(_at_range) {
 1218       this.range = _at_range;
 1219       Slice.__super__.constructor.call(this);
 1220     }
 1221 
 1222     Slice.prototype.compileNode = function(o) {
 1223       var compiled, compiledText, from, fromCompiled, to, toStr, _ref2;
 1224       _ref2 = this.range, to = _ref2.to, from = _ref2.from;
 1225       fromCompiled = from && from.compileToFragments(o, LEVEL_PAREN) || [this.makeCode('0')];
 1226       if (to) {
 1227         compiled = to.compileToFragments(o, LEVEL_PAREN);
 1228         compiledText = fragmentsToText(compiled);
 1229         if (!(!this.range.exclusive && +compiledText === -1)) {
 1230           toStr = ', ' + (this.range.exclusive ? compiledText : SIMPLENUM.test(compiledText) ? "" + (+compiledText + 1) : (compiled = to.compileToFragments(o, LEVEL_ACCESS), "+" + (fragmentsToText(compiled)) + " + 1 || 9e9"));
 1231         }
 1232       }
 1233       return [this.makeCode(".slice(" + (fragmentsToText(fromCompiled)) + (toStr || '') + ")")];
 1234     };
 1235 
 1236     return Slice;
 1237 
 1238   })(Base);
 1239 
 1240   exports.Obj = Obj = (function(_super) {
 1241     __extends(Obj, _super);
 1242 
 1243     function Obj(props, _at_generated) {
 1244       this.generated = _at_generated != null ? _at_generated : false;
 1245       this.objects = this.properties = props || [];
 1246     }
 1247 
 1248     Obj.prototype.children = ['properties'];
 1249 
 1250     Obj.prototype.compileNode = function(o) {
 1251       var answer, i, idt, indent, join, lastNoncom, node, prop, props, _i, _j, _len, _len1;
 1252       props = this.properties;
 1253       if (!props.length) {
 1254         return [this.makeCode(this.front ? '({})' : '{}')];
 1255       }
 1256       if (this.generated) {
 1257         for (_i = 0, _len = props.length; _i < _len; _i++) {
 1258           node = props[_i];
 1259           if (node instanceof Value) {
 1260             node.error('cannot have an implicit value in an implicit object');
 1261           }
 1262         }
 1263       }
 1264       idt = o.indent += TAB;
 1265       lastNoncom = this.lastNonComment(this.properties);
 1266       answer = [];
 1267       for (i = _j = 0, _len1 = props.length; _j < _len1; i = ++_j) {
 1268         prop = props[i];
 1269         join = i === props.length - 1 ? '' : prop === lastNoncom || prop instanceof Comment ? '\n' : ',\n';
 1270         indent = prop instanceof Comment ? '' : idt;
 1271         if (prop instanceof Assign && prop.variable instanceof Value && prop.variable.hasProperties()) {
 1272           prop.variable.error('Invalid object key');
 1273         }
 1274         if (prop instanceof Value && prop["this"]) {
 1275           prop = new Assign(prop.properties[0].name, prop, 'object');
 1276         }
 1277         if (!(prop instanceof Comment)) {
 1278           if (!(prop instanceof Assign)) {
 1279             prop = new Assign(prop, prop, 'object');
 1280           }
 1281           (prop.variable.base || prop.variable).asKey = true;
 1282         }
 1283         if (indent) {
 1284           answer.push(this.makeCode(indent));
 1285         }
 1286         answer.push.apply(answer, prop.compileToFragments(o, LEVEL_TOP));
 1287         if (join) {
 1288           answer.push(this.makeCode(join));
 1289         }
 1290       }
 1291       answer.unshift(this.makeCode("{" + (props.length && '\n')));
 1292       answer.push(this.makeCode((props.length && '\n' + this.tab) + "}"));
 1293       if (this.front) {
 1294         return this.wrapInBraces(answer);
 1295       } else {
 1296         return answer;
 1297       }
 1298     };
 1299 
 1300     Obj.prototype.assigns = function(name) {
 1301       var prop, _i, _len, _ref2;
 1302       _ref2 = this.properties;
 1303       for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
 1304         prop = _ref2[_i];
 1305         if (prop.assigns(name)) {
 1306           return true;
 1307         }
 1308       }
 1309       return false;
 1310     };
 1311 
 1312     return Obj;
 1313 
 1314   })(Base);
 1315 
 1316   exports.Arr = Arr = (function(_super) {
 1317     __extends(Arr, _super);
 1318 
 1319     function Arr(objs) {
 1320       this.objects = objs || [];
 1321     }
 1322 
 1323     Arr.prototype.children = ['objects'];
 1324 
 1325     Arr.prototype.compileNode = function(o) {
 1326       var answer, compiledObjs, fragments, index, obj, _i, _len;
 1327       if (!this.objects.length) {
 1328         return [this.makeCode('[]')];
 1329       }
 1330       o.indent += TAB;
 1331       answer = Splat.compileSplattedArray(o, this.objects);
 1332       if (answer.length) {
 1333         return answer;
 1334       }
 1335       answer = [];
 1336       compiledObjs = (function() {
 1337         var _i, _len, _ref2, _results;
 1338         _ref2 = this.objects;
 1339         _results = [];
 1340         for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
 1341           obj = _ref2[_i];
 1342           _results.push(obj.compileToFragments(o, LEVEL_LIST));
 1343         }
 1344         return _results;
 1345       }).call(this);
 1346       for (index = _i = 0, _len = compiledObjs.length; _i < _len; index = ++_i) {
 1347         fragments = compiledObjs[index];
 1348         if (index) {
 1349           answer.push(this.makeCode(", "));
 1350         }
 1351         answer.push.apply(answer, fragments);
 1352       }
 1353       if (fragmentsToText(answer).indexOf('\n') >= 0) {
 1354         answer.unshift(this.makeCode("[\n" + o.indent));
 1355         answer.push(this.makeCode("\n" + this.tab + "]"));
 1356       } else {
 1357         answer.unshift(this.makeCode("["));
 1358         answer.push(this.makeCode("]"));
 1359       }
 1360       return answer;
 1361     };
 1362 
 1363     Arr.prototype.assigns = function(name) {
 1364       var obj, _i, _len, _ref2;
 1365       _ref2 = this.objects;
 1366       for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
 1367         obj = _ref2[_i];
 1368         if (obj.assigns(name)) {
 1369           return true;
 1370         }
 1371       }
 1372       return false;
 1373     };
 1374 
 1375     return Arr;
 1376 
 1377   })(Base);
 1378 
 1379   exports.Class = Class = (function(_super) {
 1380     __extends(Class, _super);
 1381 
 1382     function Class(_at_variable, _at_parent, _at_body) {
 1383       this.variable = _at_variable;
 1384       this.parent = _at_parent;
 1385       this.body = _at_body != null ? _at_body : new Block;
 1386       this.boundFuncs = [];
 1387       this.body.classBody = true;
 1388     }
 1389 
 1390     Class.prototype.children = ['variable', 'parent', 'body'];
 1391 
 1392     Class.prototype.determineName = function() {
 1393       var decl, tail;
 1394       if (!this.variable) {
 1395         return null;
 1396       }
 1397       decl = (tail = last(this.variable.properties)) ? tail instanceof Access && tail.name.value : this.variable.base.value;
 1398       if (__indexOf.call(STRICT_PROSCRIBED, decl) >= 0) {
 1399         this.variable.error("class variable name may not be " + decl);
 1400       }
 1401       return decl && (decl = IDENTIFIER.test(decl) && decl);
 1402     };
 1403 
 1404     Class.prototype.setContext = function(name) {
 1405       return this.body.traverseChildren(false, function(node) {
 1406         if (node.classBody) {
 1407           return false;
 1408         }
 1409         if (node instanceof Literal && node.value === 'this') {
 1410           return node.value = name;
 1411         } else if (node instanceof Code) {
 1412           node.klass = name;
 1413           if (node.bound) {
 1414             return node.context = name;
 1415           }
 1416         }
 1417       });
 1418     };
 1419 
 1420     Class.prototype.addBoundFunctions = function(o) {
 1421       var bvar, lhs, _i, _len, _ref2;
 1422       _ref2 = this.boundFuncs;
 1423       for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
 1424         bvar = _ref2[_i];
 1425         lhs = (new Value(new Literal("this"), [new Access(bvar)])).compile(o);
 1426         this.ctor.body.unshift(new Literal(lhs + " = " + (utility('bind', o)) + "(" + lhs + ", this)"));
 1427       }
 1428     };
 1429 
 1430     Class.prototype.addProperties = function(node, name, o) {
 1431       var assign, base, exprs, func, props;
 1432       props = node.base.properties.slice(0);
 1433       exprs = (function() {
 1434         var _results;
 1435         _results = [];
 1436         while (assign = props.shift()) {
 1437           if (assign instanceof Assign) {
 1438             base = assign.variable.base;
 1439             delete assign.context;
 1440             func = assign.value;
 1441             if (base.value === 'constructor') {
 1442               if (this.ctor) {
 1443                 assign.error('cannot define more than one constructor in a class');
 1444               }
 1445               if (func.bound) {
 1446                 assign.error('cannot define a constructor as a bound function');
 1447               }
 1448               if (func instanceof Code) {
 1449                 assign = this.ctor = func;
 1450               } else {
 1451                 this.externalCtor = o.classScope.freeVariable('class');
 1452                 assign = new Assign(new Literal(this.externalCtor), func);
 1453               }
 1454             } else {
 1455               if (assign.variable["this"]) {
 1456                 func["static"] = true;
 1457               } else {
 1458                 assign.variable = new Value(new Literal(name), [new Access(new Literal('prototype')), new Access(base)]);
 1459                 if (func instanceof Code && func.bound) {
 1460                   this.boundFuncs.push(base);
 1461                   func.bound = false;
 1462                 }
 1463               }
 1464             }
 1465           }
 1466           _results.push(assign);
 1467         }
 1468         return _results;
 1469       }).call(this);
 1470       return compact(exprs);
 1471     };
 1472 
 1473     Class.prototype.walkBody = function(name, o) {
 1474       return this.traverseChildren(false, (function(_this) {
 1475         return function(child) {
 1476           var cont, exps, i, node, _i, _len, _ref2;
 1477           cont = true;
 1478           if (child instanceof Class) {
 1479             return false;
 1480           }
 1481           if (child instanceof Block) {
 1482             _ref2 = exps = child.expressions;
 1483             for (i = _i = 0, _len = _ref2.length; _i < _len; i = ++_i) {
 1484               node = _ref2[i];
 1485               if (node instanceof Assign && node.variable.looksStatic(name)) {
 1486                 node.value["static"] = true;
 1487               } else if (node instanceof Value && node.isObject(true)) {
 1488                 cont = false;
 1489                 exps[i] = _this.addProperties(node, name, o);
 1490               }
 1491             }
 1492             child.expressions = exps = flatten(exps);
 1493           }
 1494           return cont && !(child instanceof Class);
 1495         };
 1496       })(this));
 1497     };
 1498 
 1499     Class.prototype.hoistDirectivePrologue = function() {
 1500       var expressions, index, node;
 1501       index = 0;
 1502       expressions = this.body.expressions;
 1503       while ((node = expressions[index]) && node instanceof Comment || node instanceof Value && node.isString()) {
 1504         ++index;
 1505       }
 1506       return this.directives = expressions.splice(0, index);
 1507     };
 1508 
 1509     Class.prototype.ensureConstructor = function(name) {
 1510       if (!this.ctor) {
 1511         this.ctor = new Code;
 1512         if (this.externalCtor) {
 1513           this.ctor.body.push(new Literal(this.externalCtor + ".apply(this, arguments)"));
 1514         } else if (this.parent) {
 1515           this.ctor.body.push(new Literal(name + ".__super__.constructor.apply(this, arguments)"));
 1516         }
 1517         this.ctor.body.makeReturn();
 1518         this.body.expressions.unshift(this.ctor);
 1519       }
 1520       this.ctor.ctor = this.ctor.name = name;
 1521       this.ctor.klass = null;
 1522       return this.ctor.noReturn = true;
 1523     };
 1524 
 1525     Class.prototype.compileNode = function(o) {
 1526       var args, argumentsNode, func, jumpNode, klass, lname, name, superClass, _ref2;
 1527       if (jumpNode = this.body.jumps()) {
 1528         jumpNode.error('Class bodies cannot contain pure statements');
 1529       }
 1530       if (argumentsNode = this.body.contains(isLiteralArguments)) {
 1531         argumentsNode.error("Class bodies shouldn't reference arguments");
 1532       }
 1533       name = this.determineName() || '_Class';
 1534       if (name.reserved) {
 1535         name = "_" + name;
 1536       }
 1537       lname = new Literal(name);
 1538       func = new Code([], Block.wrap([this.body]));
 1539       args = [];
 1540       o.classScope = func.makeScope(o.scope);
 1541       this.hoistDirectivePrologue();
 1542       this.setContext(name);
 1543       this.walkBody(name, o);
 1544       this.ensureConstructor(name);
 1545       this.addBoundFunctions(o);
 1546       this.body.spaced = true;
 1547       this.body.expressions.push(lname);
 1548       if (this.parent) {
 1549         superClass = new Literal(o.classScope.freeVariable('super', false));
 1550         this.body.expressions.unshift(new Extends(lname, superClass));
 1551         func.params.push(new Param(superClass));
 1552         args.push(this.parent);
 1553       }
 1554       (_ref2 = this.body.expressions).unshift.apply(_ref2, this.directives);
 1555       klass = new Parens(new Call(func, args));
 1556       if (this.variable) {
 1557         klass = new Assign(this.variable, klass);
 1558       }
 1559       return klass.compileToFragments(o);
 1560     };
 1561 
 1562     return Class;
 1563 
 1564   })(Base);
 1565 
 1566   exports.Assign = Assign = (function(_super) {
 1567     __extends(Assign, _super);
 1568 
 1569     function Assign(_at_variable, _at_value, _at_context, options) {
 1570       var forbidden, name, _ref2;
 1571       this.variable = _at_variable;
 1572       this.value = _at_value;
 1573       this.context = _at_context;
 1574       this.param = options && options.param;
 1575       this.subpattern = options && options.subpattern;
 1576       forbidden = (_ref2 = (name = this.variable.unwrapAll().value), __indexOf.call(STRICT_PROSCRIBED, _ref2) >= 0);
 1577       if (forbidden && this.context !== 'object') {
 1578         this.variable.error("variable name may not be \"" + name + "\"");
 1579       }
 1580     }
 1581 
 1582     Assign.prototype.children = ['variable', 'value'];
 1583 
 1584     Assign.prototype.isStatement = function(o) {
 1585       return (o != null ? o.level : void 0) === LEVEL_TOP && (this.context != null) && __indexOf.call(this.context, "?") >= 0;
 1586     };
 1587 
 1588     Assign.prototype.assigns = function(name) {
 1589       return this[this.context === 'object' ? 'value' : 'variable'].assigns(name);
 1590     };
 1591 
 1592     Assign.prototype.unfoldSoak = function(o) {
 1593       return unfoldSoak(o, this, 'variable');
 1594     };
 1595 
 1596     Assign.prototype.compileNode = function(o) {
 1597       var answer, compiledName, isValue, match, name, val, varBase, _ref2, _ref3, _ref4, _ref5;
 1598       if (isValue = this.variable instanceof Value) {
 1599         if (this.variable.isArray() || this.variable.isObject()) {
 1600           return this.compilePatternMatch(o);
 1601         }
 1602         if (this.variable.isSplice()) {
 1603           return this.compileSplice(o);
 1604         }
 1605         if ((_ref2 = this.context) === '||=' || _ref2 === '&&=' || _ref2 === '?=') {
 1606           return this.compileConditional(o);
 1607         }
 1608         if ((_ref3 = this.context) === '**=' || _ref3 === '//=' || _ref3 === '%%=') {
 1609           return this.compileSpecialMath(o);
 1610         }
 1611       }
 1612       compiledName = this.variable.compileToFragments(o, LEVEL_LIST);
 1613       name = fragmentsToText(compiledName);
 1614       if (!this.context) {
 1615         varBase = this.variable.unwrapAll();
 1616         if (!varBase.isAssignable()) {
 1617           this.variable.error("\"" + (this.variable.compile(o)) + "\" cannot be assigned");
 1618         }
 1619         if (!(typeof varBase.hasProperties === "function" ? varBase.hasProperties() : void 0)) {
 1620           if (this.param) {
 1621             o.scope.add(name, 'var');
 1622           } else {
 1623             o.scope.find(name);
 1624           }
 1625         }
 1626       }
 1627       if (this.value instanceof Code && (match = METHOD_DEF.exec(name))) {
 1628         if (match[2]) {
 1629           this.value.klass = match[1];
 1630         }
 1631         this.value.name = (_ref4 = (_ref5 = match[3]) != null ? _ref5 : match[4]) != null ? _ref4 : match[5];
 1632       }
 1633       val = this.value.compileToFragments(o, LEVEL_LIST);
 1634       if (this.context === 'object') {
 1635         return compiledName.concat(this.makeCode(": "), val);
 1636       }
 1637       answer = compiledName.concat(this.makeCode(" " + (this.context || '=') + " "), val);
 1638       if (o.level <= LEVEL_LIST) {
 1639         return answer;
 1640       } else {
 1641         return this.wrapInBraces(answer);
 1642       }
 1643     };
 1644 
 1645     Assign.prototype.compilePatternMatch = function(o) {
 1646       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;
 1647       top = o.level === LEVEL_TOP;
 1648       value = this.value;
 1649       objects = this.variable.base.objects;
 1650       if (!(olen = objects.length)) {
 1651         code = value.compileToFragments(o);
 1652         if (o.level >= LEVEL_OP) {
 1653           return this.wrapInBraces(code);
 1654         } else {
 1655           return code;
 1656         }
 1657       }
 1658       isObject = this.variable.isObject();
 1659       if (top && olen === 1 && !((obj = objects[0]) instanceof Splat)) {
 1660         if (obj instanceof Assign) {
 1661           _ref2 = obj, (_ref3 = _ref2.variable, idx = _ref3.base), obj = _ref2.value;
 1662         } else {
 1663           idx = isObject ? obj["this"] ? obj.properties[0].name : obj : new Literal(0);
 1664         }
 1665         acc = IDENTIFIER.test(idx.unwrap().value || 0);
 1666         value = new Value(value);
 1667         value.properties.push(new (acc ? Access : Index)(idx));
 1668         if (_ref4 = obj.unwrap().value, __indexOf.call(RESERVED, _ref4) >= 0) {
 1669           obj.error("assignment to a reserved word: " + (obj.compile(o)));
 1670         }
 1671         return new Assign(obj, value, null, {
 1672           param: this.param
 1673         }).compileToFragments(o, LEVEL_TOP);
 1674       }
 1675       vvar = value.compileToFragments(o, LEVEL_LIST);
 1676       vvarText = fragmentsToText(vvar);
 1677       assigns = [];
 1678       expandedIdx = false;
 1679       if (!IDENTIFIER.test(vvarText) || this.variable.assigns(vvarText)) {
 1680         assigns.push([this.makeCode((ref = o.scope.freeVariable('ref')) + " = ")].concat(__slice.call(vvar)));
 1681         vvar = [this.makeCode(ref)];
 1682         vvarText = ref;
 1683       }
 1684       for (i = _i = 0, _len = objects.length; _i < _len; i = ++_i) {
 1685         obj = objects[i];
 1686         idx = i;
 1687         if (isObject) {
 1688           if (obj instanceof Assign) {
 1689             _ref5 = obj, (_ref6 = _ref5.variable, idx = _ref6.base), obj = _ref5.value;
 1690           } else {
 1691             if (obj.base instanceof Parens) {
 1692               _ref7 = new Value(obj.unwrapAll()).cacheReference(o), obj = _ref7[0], idx = _ref7[1];
 1693             } else {
 1694               idx = obj["this"] ? obj.properties[0].name : obj;
 1695             }
 1696           }
 1697         }
 1698         if (!expandedIdx && obj instanceof Splat) {
 1699           name = obj.name.unwrap().value;
 1700           obj = obj.unwrap();
 1701           val = olen + " <= " + vvarText + ".length ? " + (utility('slice', o)) + ".call(" + vvarText + ", " + i;
 1702           if (rest = olen - i - 1) {
 1703             ivar = o.scope.freeVariable('i');
 1704             val += ", " + ivar + " = " + vvarText + ".length - " + rest + ") : (" + ivar + " = " + i + ", [])";
 1705           } else {
 1706             val += ") : []";
 1707           }
 1708           val = new Literal(val);
 1709           expandedIdx = ivar + "++";
 1710         } else if (!expandedIdx && obj instanceof Expansion) {
 1711           if (rest = olen - i - 1) {
 1712             if (rest === 1) {
 1713               expandedIdx = vvarText + ".length - 1";
 1714             } else {
 1715               ivar = o.scope.freeVariable('i');
 1716               val = new Literal(ivar + " = " + vvarText + ".length - " + rest);
 1717               expandedIdx = ivar + "++";
 1718               assigns.push(val.compileToFragments(o, LEVEL_LIST));
 1719             }
 1720           }
 1721           continue;
 1722         } else {
 1723           name = obj.unwrap().value;
 1724           if (obj instanceof Splat || obj instanceof Expansion) {
 1725             obj.error("multiple splats/expansions are disallowed in an assignment");
 1726           }
 1727           if (typeof idx === 'number') {
 1728             idx = new Literal(expandedIdx || idx);
 1729             acc = false;
 1730           } else {
 1731             acc = isObject && IDENTIFIER.test(idx.unwrap().value || 0);
 1732           }
 1733           val = new Value(new Literal(vvarText), [new (acc ? Access : Index)(idx)]);
 1734         }
 1735         if ((name != null) && __indexOf.call(RESERVED, name) >= 0) {
 1736           obj.error("assignment to a reserved word: " + (obj.compile(o)));
 1737         }
 1738         assigns.push(new Assign(obj, val, null, {
 1739           param: this.param,
 1740           subpattern: true
 1741         }).compileToFragments(o, LEVEL_LIST));
 1742       }
 1743       if (!(top || this.subpattern)) {
 1744         assigns.push(vvar);
 1745       }
 1746       fragments = this.joinFragmentArrays(assigns, ', ');
 1747       if (o.level < LEVEL_LIST) {
 1748         return fragments;
 1749       } else {
 1750         return this.wrapInBraces(fragments);
 1751       }
 1752     };
 1753 
 1754     Assign.prototype.compileConditional = function(o) {
 1755       var fragments, left, right, _ref2;
 1756       _ref2 = this.variable.cacheReference(o), left = _ref2[0], right = _ref2[1];
 1757       if (!left.properties.length && left.base instanceof Literal && left.base.value !== "this" && !o.scope.check(left.base.value)) {
 1758         this.variable.error("the variable \"" + left.base.value + "\" can't be assigned with " + this.context + " because it has not been declared before");
 1759       }
 1760       if (__indexOf.call(this.context, "?") >= 0) {
 1761         o.isExistentialEquals = true;
 1762         return new If(new Existence(left), right, {
 1763           type: 'if'
 1764         }).addElse(new Assign(right, this.value, '=')).compileToFragments(o);
 1765       } else {
 1766         fragments = new Op(this.context.slice(0, -1), left, new Assign(right, this.value, '=')).compileToFragments(o);
 1767         if (o.level <= LEVEL_LIST) {
 1768           return fragments;
 1769         } else {
 1770           return this.wrapInBraces(fragments);
 1771         }
 1772       }
 1773     };
 1774 
 1775     Assign.prototype.compileSpecialMath = function(o) {
 1776       var left, right, _ref2;
 1777       _ref2 = this.variable.cacheReference(o), left = _ref2[0], right = _ref2[1];
 1778       return new Assign(left, new Op(this.context.slice(0, -1), right, this.value)).compileToFragments(o);
 1779     };
 1780 
 1781     Assign.prototype.compileSplice = function(o) {
 1782       var answer, exclusive, from, fromDecl, fromRef, name, to, valDef, valRef, _ref2, _ref3, _ref4;
 1783       _ref2 = this.variable.properties.pop().range, from = _ref2.from, to = _ref2.to, exclusive = _ref2.exclusive;
 1784       name = this.variable.compile(o);
 1785       if (from) {
 1786         _ref3 = this.cacheToCodeFragments(from.cache(o, LEVEL_OP)), fromDecl = _ref3[0], fromRef = _ref3[1];
 1787       } else {
 1788         fromDecl = fromRef = '0';
 1789       }
 1790       if (to) {
 1791         if (from instanceof Value && from.isSimpleNumber() && to instanceof Value && to.isSimpleNumber()) {
 1792           to = to.compile(o) - fromRef;
 1793           if (!exclusive) {
 1794             to += 1;
 1795           }
 1796         } else {
 1797           to = to.compile(o, LEVEL_ACCESS) + ' - ' + fromRef;
 1798           if (!exclusive) {
 1799             to += ' + 1';
 1800           }
 1801         }
 1802       } else {
 1803         to = "9e9";
 1804       }
 1805       _ref4 = this.value.cache(o, LEVEL_LIST), valDef = _ref4[0], valRef = _ref4[1];
 1806       answer = [].concat(this.makeCode("[].splice.apply(" + name + ", [" + fromDecl + ", " + to + "].concat("), valDef, this.makeCode(")), "), valRef);
 1807       if (o.level > LEVEL_TOP) {
 1808         return this.wrapInBraces(answer);
 1809       } else {
 1810         return answer;
 1811       }
 1812     };
 1813 
 1814     return Assign;
 1815 
 1816   })(Base);
 1817 
 1818   exports.Code = Code = (function(_super) {
 1819     __extends(Code, _super);
 1820 
 1821     function Code(params, body, tag) {
 1822       this.params = params || [];
 1823       this.body = body || new Block;
 1824       this.bound = tag === 'boundfunc';
 1825       this.isGenerator = !!this.body.contains(function(node) {
 1826         var _ref2;
 1827         return node instanceof Op && ((_ref2 = node.operator) === 'yield' || _ref2 === 'yield*');
 1828       });
 1829     }
 1830 
 1831     Code.prototype.children = ['params', 'body'];
 1832 
 1833     Code.prototype.isStatement = function() {
 1834       return !!this.ctor;
 1835     };
 1836 
 1837     Code.prototype.jumps = NO;
 1838 
 1839     Code.prototype.makeScope = function(parentScope) {
 1840       return new Scope(parentScope, this.body, this);
 1841     };
 1842 
 1843     Code.prototype.compileNode = function(o) {
 1844       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;
 1845       if (this.bound && ((_ref2 = o.scope.method) != null ? _ref2.bound : void 0)) {
 1846         this.context = o.scope.method.context;
 1847       }
 1848       if (this.bound && !this.context) {
 1849         this.context = '_this';
 1850         wrapper = new Code([new Param(new Literal(this.context))], new Block([this]));
 1851         boundfunc = new Call(wrapper, [new Literal('this')]);
 1852         boundfunc.updateLocationDataIfMissing(this.locationData);
 1853         return boundfunc.compileNode(o);
 1854       }
 1855       o.scope = del(o, 'classScope') || this.makeScope(o.scope);
 1856       o.scope.shared = del(o, 'sharedScope');
 1857       o.indent += TAB;
 1858       delete o.bare;
 1859       delete o.isExistentialEquals;
 1860       params = [];
 1861       exprs = [];
 1862       _ref3 = this.params;
 1863       for (_i = 0, _len = _ref3.length; _i < _len; _i++) {
 1864         param = _ref3[_i];
 1865         if (!(param instanceof Expansion)) {
 1866           o.scope.parameter(param.asReference(o));
 1867         }
 1868       }
 1869       _ref4 = this.params;
 1870       for (_j = 0, _len1 = _ref4.length; _j < _len1; _j++) {
 1871         param = _ref4[_j];
 1872         if (!(param.splat || param instanceof Expansion)) {
 1873           continue;
 1874         }
 1875         _ref5 = this.params;
 1876         for (_k = 0, _len2 = _ref5.length; _k < _len2; _k++) {
 1877           p = _ref5[_k];
 1878           if (!(p instanceof Expansion) && p.name.value) {
 1879             o.scope.add(p.name.value, 'var', true);
 1880           }
 1881         }
 1882         splats = new Assign(new Value(new Arr((function() {
 1883           var _l, _len3, _ref6, _results;
 1884           _ref6 = this.params;
 1885           _results = [];
 1886           for (_l = 0, _len3 = _ref6.length; _l < _len3; _l++) {
 1887             p = _ref6[_l];
 1888             _results.push(p.asReference(o));
 1889           }
 1890           return _results;
 1891         }).call(this))), new Value(new Literal('arguments')));
 1892         break;
 1893       }
 1894       _ref6 = this.params;
 1895       for (_l = 0, _len3 = _ref6.length; _l < _len3; _l++) {
 1896         param = _ref6[_l];
 1897         if (param.isComplex()) {
 1898           val = ref = param.asReference(o);
 1899           if (param.value) {
 1900             val = new Op('?', ref, param.value);
 1901           }
 1902           exprs.push(new Assign(new Value(param.name), val, '=', {
 1903             param: true
 1904           }));
 1905         } else {
 1906           ref = param;
 1907           if (param.value) {
 1908             lit = new Literal(ref.name.value + ' == null');
 1909             val = new Assign(new Value(param.name), param.value, '=');
 1910             exprs.push(new If(lit, val));
 1911           }
 1912         }
 1913         if (!splats) {
 1914           params.push(ref);
 1915         }
 1916       }
 1917       wasEmpty = this.body.isEmpty();
 1918       if (splats) {
 1919         exprs.unshift(splats);
 1920       }
 1921       if (exprs.length) {
 1922         (_ref7 = this.body.expressions).unshift.apply(_ref7, exprs);
 1923       }
 1924       for (i = _m = 0, _len4 = params.length; _m < _len4; i = ++_m) {
 1925         p = params[i];
 1926         params[i] = p.compileToFragments(o);
 1927         o.scope.parameter(fragmentsToText(params[i]));
 1928       }
 1929       uniqs = [];
 1930       this.eachParamName(function(name, node) {
 1931         if (__indexOf.call(uniqs, name) >= 0) {
 1932           node.error("multiple parameters named " + name);
 1933         }
 1934         return uniqs.push(name);
 1935       });
 1936       if (!(wasEmpty || this.noReturn)) {
 1937         this.body.makeReturn();
 1938       }
 1939       code = 'function';
 1940       if (this.isGenerator) {
 1941         code += '*';
 1942       }
 1943       if (this.ctor) {
 1944         code += ' ' + this.name;
 1945       }
 1946       code += '(';
 1947       answer = [this.makeCode(code)];
 1948       for (i = _n = 0, _len5 = params.length; _n < _len5; i = ++_n) {
 1949         p = params[i];
 1950         if (i) {
 1951           answer.push(this.makeCode(", "));
 1952         }
 1953         answer.push.apply(answer, p);
 1954       }
 1955       answer.push(this.makeCode(') {'));
 1956       if (!this.body.isEmpty()) {
 1957         answer = answer.concat(this.makeCode("\n"), this.body.compileWithDeclarations(o), this.makeCode("\n" + this.tab));
 1958       }
 1959       answer.push(this.makeCode('}'));
 1960       if (this.ctor) {
 1961         return [this.makeCode(this.tab)].concat(__slice.call(answer));
 1962       }
 1963       if (this.front || (o.level >= LEVEL_ACCESS)) {
 1964         return this.wrapInBraces(answer);
 1965       } else {
 1966         return answer;
 1967       }
 1968     };
 1969 
 1970     Code.prototype.eachParamName = function(iterator) {
 1971       var param, _i, _len, _ref2, _results;
 1972       _ref2 = this.params;
 1973       _results = [];
 1974       for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
 1975         param = _ref2[_i];
 1976         _results.push(param.eachName(iterator));
 1977       }
 1978       return _results;
 1979     };
 1980 
 1981     Code.prototype.traverseChildren = function(crossScope, func) {
 1982       if (crossScope) {
 1983         return Code.__super__.traverseChildren.call(this, crossScope, func);
 1984       }
 1985     };
 1986 
 1987     return Code;
 1988 
 1989   })(Base);
 1990 
 1991   exports.Param = Param = (function(_super) {
 1992     __extends(Param, _super);
 1993 
 1994     function Param(_at_name, _at_value, _at_splat) {
 1995       var name, _ref2;
 1996       this.name = _at_name;
 1997       this.value = _at_value;
 1998       this.splat = _at_splat;
 1999       if (_ref2 = (name = this.name.unwrapAll().value), __indexOf.call(STRICT_PROSCRIBED, _ref2) >= 0) {
 2000         this.name.error("parameter name \"" + name + "\" is not allowed");
 2001       }
 2002     }
 2003 
 2004     Param.prototype.children = ['name', 'value'];
 2005 
 2006     Param.prototype.compileToFragments = function(o) {
 2007       return this.name.compileToFragments(o, LEVEL_LIST);
 2008     };
 2009 
 2010     Param.prototype.asReference = function(o) {
 2011       var name, node;
 2012       if (this.reference) {
 2013         return this.reference;
 2014       }
 2015       node = this.name;
 2016       if (node["this"]) {
 2017         name = "at_" + node.properties[0].name.value;
 2018         node = new Literal(o.scope.freeVariable(name));
 2019       } else if (node.isComplex()) {
 2020         node = new Literal(o.scope.freeVariable('arg'));
 2021       }
 2022       node = new Value(node);
 2023       if (this.splat) {
 2024         node = new Splat(node);
 2025       }
 2026       node.updateLocationDataIfMissing(this.locationData);
 2027       return this.reference = node;
 2028     };
 2029 
 2030     Param.prototype.isComplex = function() {
 2031       return this.name.isComplex();
 2032     };
 2033 
 2034     Param.prototype.eachName = function(iterator, name) {
 2035       var atParam, node, obj, _i, _len, _ref2;
 2036       if (name == null) {
 2037         name = this.name;
 2038       }
 2039       atParam = function(obj) {
 2040         return iterator("@" + obj.properties[0].name.value, obj);
 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', o)) + ".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', o)) + ".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(_at_body) {
 2191       this.body = _at_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       'yieldfrom': 'yield*'
 2278     };
 2279 
 2280     INVERSIONS = {
 2281       '!==': '===',
 2282       '===': '!=='
 2283     };
 2284 
 2285     Op.prototype.children = ['first', 'second'];
 2286 
 2287     Op.prototype.isSimpleNumber = NO;
 2288 
 2289     Op.prototype.isYield = function() {
 2290       var _ref2;
 2291       return (_ref2 = this.operator) === 'yield' || _ref2 === 'yield*';
 2292     };
 2293 
 2294     Op.prototype.isUnary = function() {
 2295       return !this.second;
 2296     };
 2297 
 2298     Op.prototype.isComplex = function() {
 2299       var _ref2;
 2300       return !(this.isUnary() && ((_ref2 = this.operator) === '+' || _ref2 === '-') && this.first instanceof Value && this.first.isSimpleNumber());
 2301     };
 2302 
 2303     Op.prototype.isChainable = function() {
 2304       var _ref2;
 2305       return (_ref2 = this.operator) === '<' || _ref2 === '>' || _ref2 === '>=' || _ref2 === '<=' || _ref2 === '===' || _ref2 === '!==';
 2306     };
 2307 
 2308     Op.prototype.invert = function() {
 2309       var allInvertable, curr, fst, op, _ref2;
 2310       if (this.isChainable() && this.first.isChainable()) {
 2311         allInvertable = true;
 2312         curr = this;
 2313         while (curr && curr.operator) {
 2314           allInvertable && (allInvertable = curr.operator in INVERSIONS);
 2315           curr = curr.first;
 2316         }
 2317         if (!allInvertable) {
 2318           return new Parens(this).invert();
 2319         }
 2320         curr = this;
 2321         while (curr && curr.operator) {
 2322           curr.invert = !curr.invert;
 2323           curr.operator = INVERSIONS[curr.operator];
 2324           curr = curr.first;
 2325         }
 2326         return this;
 2327       } else if (op = INVERSIONS[this.operator]) {
 2328         this.operator = op;
 2329         if (this.first.unwrap() instanceof Op) {
 2330           this.first.invert();
 2331         }
 2332         return this;
 2333       } else if (this.second) {
 2334         return new Parens(this).invert();
 2335       } else if (this.operator === '!' && (fst = this.first.unwrap()) instanceof Op && ((_ref2 = fst.operator) === '!' || _ref2 === 'in' || _ref2 === 'instanceof')) {
 2336         return fst;
 2337       } else {
 2338         return new Op('!', this);
 2339       }
 2340     };
 2341 
 2342     Op.prototype.unfoldSoak = function(o) {
 2343       var _ref2;
 2344       return ((_ref2 = this.operator) === '++' || _ref2 === '--' || _ref2 === 'delete') && unfoldSoak(o, this, 'first');
 2345     };
 2346 
 2347     Op.prototype.generateDo = function(exp) {
 2348       var call, func, param, passedParams, ref, _i, _len, _ref2;
 2349       passedParams = [];
 2350       func = exp instanceof Assign && (ref = exp.value.unwrap()) instanceof Code ? ref : exp;
 2351       _ref2 = func.params || [];
 2352       for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
 2353         param = _ref2[_i];
 2354         if (param.value) {
 2355           passedParams.push(param.value);
 2356           delete param.value;
 2357         } else {
 2358           passedParams.push(param);
 2359         }
 2360       }
 2361       call = new Call(exp, passedParams);
 2362       call["do"] = true;
 2363       return call;
 2364     };
 2365 
 2366     Op.prototype.compileNode = function(o) {
 2367       var answer, isChain, lhs, rhs, _ref2, _ref3;
 2368       isChain = this.isChainable() && this.first.isChainable();
 2369       if (!isChain) {
 2370         this.first.front = this.front;
 2371       }
 2372       if (this.operator === 'delete' && o.scope.check(this.first.unwrapAll().value)) {
 2373         this.error('delete operand may not be argument or var');
 2374       }
 2375       if (((_ref2 = this.operator) === '--' || _ref2 === '++') && (_ref3 = this.first.unwrapAll().value, __indexOf.call(STRICT_PROSCRIBED, _ref3) >= 0)) {
 2376         this.error("cannot increment/decrement \"" + (this.first.unwrapAll().value) + "\"");
 2377       }
 2378       if (this.isYield()) {
 2379         return this.compileYield(o);
 2380       }
 2381       if (this.isUnary()) {
 2382         return this.compileUnary(o);
 2383       }
 2384       if (isChain) {
 2385         return this.compileChain(o);
 2386       }
 2387       switch (this.operator) {
 2388         case '?':
 2389           return this.compileExistence(o);
 2390         case '**':
 2391           return this.compilePower(o);
 2392         case '//':
 2393           return this.compileFloorDivision(o);
 2394         case '%%':
 2395           return this.compileModulo(o);
 2396         default:
 2397           lhs = this.first.compileToFragments(o, LEVEL_OP);
 2398           rhs = this.second.compileToFragments(o, LEVEL_OP);
 2399           answer = [].concat(lhs, this.makeCode(" " + this.operator + " "), rhs);
 2400           if (o.level <= LEVEL_OP) {
 2401             return answer;
 2402           } else {
 2403             return this.wrapInBraces(answer);
 2404           }
 2405       }
 2406     };
 2407 
 2408     Op.prototype.compileChain = function(o) {
 2409       var fragments, fst, shared, _ref2;
 2410       _ref2 = this.first.second.cache(o), this.first.second = _ref2[0], shared = _ref2[1];
 2411       fst = this.first.compileToFragments(o, LEVEL_OP);
 2412       fragments = fst.concat(this.makeCode(" " + (this.invert ? '&&' : '||') + " "), shared.compileToFragments(o), this.makeCode(" " + this.operator + " "), this.second.compileToFragments(o, LEVEL_OP));
 2413       return this.wrapInBraces(fragments);
 2414     };
 2415 
 2416     Op.prototype.compileExistence = function(o) {
 2417       var fst, ref;
 2418       if (this.first.isComplex()) {
 2419         ref = new Literal(o.scope.freeVariable('ref'));
 2420         fst = new Parens(new Assign(ref, this.first));
 2421       } else {
 2422         fst = this.first;
 2423         ref = fst;
 2424       }
 2425       return new If(new Existence(fst), ref, {
 2426         type: 'if'
 2427       }).addElse(this.second).compileToFragments(o);
 2428     };
 2429 
 2430     Op.prototype.compileUnary = function(o) {
 2431       var op, parts, plusMinus;
 2432       parts = [];
 2433       op = this.operator;
 2434       parts.push([this.makeCode(op)]);
 2435       if (op === '!' && this.first instanceof Existence) {
 2436         this.first.negated = !this.first.negated;
 2437         return this.first.compileToFragments(o);
 2438       }
 2439       if (o.level >= LEVEL_ACCESS) {
 2440         return (new Parens(this)).compileToFragments(o);
 2441       }
 2442       plusMinus = op === '+' || op === '-';
 2443       if ((op === 'new' || op === 'typeof' || op === 'delete') || plusMinus && this.first instanceof Op && this.first.operator === op) {
 2444         parts.push([this.makeCode(' ')]);
 2445       }
 2446       if ((plusMinus && this.first instanceof Op) || (op === 'new' && this.first.isStatement(o))) {
 2447         this.first = new Parens(this.first);
 2448       }
 2449       parts.push(this.first.compileToFragments(o, LEVEL_OP));
 2450       if (this.flip) {
 2451         parts.reverse();
 2452       }
 2453       return this.joinFragmentArrays(parts, '');
 2454     };
 2455 
 2456     Op.prototype.compileYield = function(o) {
 2457       var op, parts;
 2458       parts = [];
 2459       op = this.operator;
 2460       if (o.scope.parent == null) {
 2461         this.error('yield statements must occur within a function generator.');
 2462       }
 2463       if (__indexOf.call(Object.keys(this.first), 'expression') >= 0) {
 2464         if (this.first.expression != null) {
 2465           parts.push(this.first.expression.compileToFragments(o, LEVEL_OP));
 2466         }
 2467       } else {
 2468         parts.push([this.makeCode("(" + op + " ")]);
 2469         parts.push(this.first.compileToFragments(o, LEVEL_OP));
 2470         parts.push([this.makeCode(")")]);
 2471       }
 2472       return this.joinFragmentArrays(parts, '');
 2473     };
 2474 
 2475     Op.prototype.compilePower = function(o) {
 2476       var pow;
 2477       pow = new Value(new Literal('Math'), [new Access(new Literal('pow'))]);
 2478       return new Call(pow, [this.first, this.second]).compileToFragments(o);
 2479     };
 2480 
 2481     Op.prototype.compileFloorDivision = function(o) {
 2482       var div, floor;
 2483       floor = new Value(new Literal('Math'), [new Access(new Literal('floor'))]);
 2484       div = new Op('/', this.first, this.second);
 2485       return new Call(floor, [div]).compileToFragments(o);
 2486     };
 2487 
 2488     Op.prototype.compileModulo = function(o) {
 2489       var mod;
 2490       mod = new Value(new Literal(utility('modulo', o)));
 2491       return new Call(mod, [this.first, this.second]).compileToFragments(o);
 2492     };
 2493 
 2494     Op.prototype.toString = function(idt) {
 2495       return Op.__super__.toString.call(this, idt, this.constructor.name + ' ' + this.operator);
 2496     };
 2497 
 2498     return Op;
 2499 
 2500   })(Base);
 2501 
 2502   exports.In = In = (function(_super) {
 2503     __extends(In, _super);
 2504 
 2505     function In(_at_object, _at_array) {
 2506       this.object = _at_object;
 2507       this.array = _at_array;
 2508     }
 2509 
 2510     In.prototype.children = ['object', 'array'];
 2511 
 2512     In.prototype.invert = NEGATE;
 2513 
 2514     In.prototype.compileNode = function(o) {
 2515       var hasSplat, obj, _i, _len, _ref2;
 2516       if (this.array instanceof Value && this.array.isArray() && this.array.base.objects.length) {
 2517         _ref2 = this.array.base.objects;
 2518         for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
 2519           obj = _ref2[_i];
 2520           if (!(obj instanceof Splat)) {
 2521             continue;
 2522           }
 2523           hasSplat = true;
 2524           break;
 2525         }
 2526         if (!hasSplat) {
 2527           return this.compileOrTest(o);
 2528         }
 2529       }
 2530       return this.compileLoopTest(o);
 2531     };
 2532 
 2533     In.prototype.compileOrTest = function(o) {
 2534       var cmp, cnj, i, item, ref, sub, tests, _i, _len, _ref2, _ref3, _ref4;
 2535       _ref2 = this.object.cache(o, LEVEL_OP), sub = _ref2[0], ref = _ref2[1];
 2536       _ref3 = this.negated ? [' !== ', ' && '] : [' === ', ' || '], cmp = _ref3[0], cnj = _ref3[1];
 2537       tests = [];
 2538       _ref4 = this.array.base.objects;
 2539       for (i = _i = 0, _len = _ref4.length; _i < _len; i = ++_i) {
 2540         item = _ref4[i];
 2541         if (i) {
 2542           tests.push(this.makeCode(cnj));
 2543         }
 2544         tests = tests.concat((i ? ref : sub), this.makeCode(cmp), item.compileToFragments(o, LEVEL_ACCESS));
 2545       }
 2546       if (o.level < LEVEL_OP) {
 2547         return tests;
 2548       } else {
 2549         return this.wrapInBraces(tests);
 2550       }
 2551     };
 2552 
 2553     In.prototype.compileLoopTest = function(o) {
 2554       var fragments, ref, sub, _ref2;
 2555       _ref2 = this.object.cache(o, LEVEL_LIST), sub = _ref2[0], ref = _ref2[1];
 2556       fragments = [].concat(this.makeCode(utility('indexOf', o) + ".call("), this.array.compileToFragments(o, LEVEL_LIST), this.makeCode(", "), ref, this.makeCode(") " + (this.negated ? '< 0' : '>= 0')));
 2557       if (fragmentsToText(sub) === fragmentsToText(ref)) {
 2558         return fragments;
 2559       }
 2560       fragments = sub.concat(this.makeCode(', '), fragments);
 2561       if (o.level < LEVEL_LIST) {
 2562         return fragments;
 2563       } else {
 2564         return this.wrapInBraces(fragments);
 2565       }
 2566     };
 2567 
 2568     In.prototype.toString = function(idt) {
 2569       return In.__super__.toString.call(this, idt, this.constructor.name + (this.negated ? '!' : ''));
 2570     };
 2571 
 2572     return In;
 2573 
 2574   })(Base);
 2575 
 2576   exports.Try = Try = (function(_super) {
 2577     __extends(Try, _super);
 2578 
 2579     function Try(_at_attempt, _at_errorVariable, _at_recovery, _at_ensure) {
 2580       this.attempt = _at_attempt;
 2581       this.errorVariable = _at_errorVariable;
 2582       this.recovery = _at_recovery;
 2583       this.ensure = _at_ensure;
 2584     }
 2585 
 2586     Try.prototype.children = ['attempt', 'recovery', 'ensure'];
 2587 
 2588     Try.prototype.isStatement = YES;
 2589 
 2590     Try.prototype.jumps = function(o) {
 2591       var _ref2;
 2592       return this.attempt.jumps(o) || ((_ref2 = this.recovery) != null ? _ref2.jumps(o) : void 0);
 2593     };
 2594 
 2595     Try.prototype.makeReturn = function(res) {
 2596       if (this.attempt) {
 2597         this.attempt = this.attempt.makeReturn(res);
 2598       }
 2599       if (this.recovery) {
 2600         this.recovery = this.recovery.makeReturn(res);
 2601       }
 2602       return this;
 2603     };
 2604 
 2605     Try.prototype.compileNode = function(o) {
 2606       var catchPart, ensurePart, placeholder, tryPart;
 2607       o.indent += TAB;
 2608       tryPart = this.attempt.compileToFragments(o, LEVEL_TOP);
 2609       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) {}')] : [];
 2610       ensurePart = this.ensure ? [].concat(this.makeCode(" finally {\n"), this.ensure.compileToFragments(o, LEVEL_TOP), this.makeCode("\n" + this.tab + "}")) : [];
 2611       return [].concat(this.makeCode(this.tab + "try {\n"), tryPart, this.makeCode("\n" + this.tab + "}"), catchPart, ensurePart);
 2612     };
 2613 
 2614     return Try;
 2615 
 2616   })(Base);
 2617 
 2618   exports.Throw = Throw = (function(_super) {
 2619     __extends(Throw, _super);
 2620 
 2621     function Throw(_at_expression) {
 2622       this.expression = _at_expression;
 2623     }
 2624 
 2625     Throw.prototype.children = ['expression'];
 2626 
 2627     Throw.prototype.isStatement = YES;
 2628 
 2629     Throw.prototype.jumps = NO;
 2630 
 2631     Throw.prototype.makeReturn = THIS;
 2632 
 2633     Throw.prototype.compileNode = function(o) {
 2634       return [].concat(this.makeCode(this.tab + "throw "), this.expression.compileToFragments(o), this.makeCode(";"));
 2635     };
 2636 
 2637     return Throw;
 2638 
 2639   })(Base);
 2640 
 2641   exports.Existence = Existence = (function(_super) {
 2642     __extends(Existence, _super);
 2643 
 2644     function Existence(_at_expression) {
 2645       this.expression = _at_expression;
 2646     }
 2647 
 2648     Existence.prototype.children = ['expression'];
 2649 
 2650     Existence.prototype.invert = NEGATE;
 2651 
 2652     Existence.prototype.compileNode = function(o) {
 2653       var cmp, cnj, code, _ref2;
 2654       this.expression.front = this.front;
 2655       code = this.expression.compile(o, LEVEL_OP);
 2656       if (IDENTIFIER.test(code) && !o.scope.check(code)) {
 2657         _ref2 = this.negated ? ['===', '||'] : ['!==', '&&'], cmp = _ref2[0], cnj = _ref2[1];
 2658         code = "typeof " + code + " " + cmp + " \"undefined\" " + cnj + " " + code + " " + cmp + " null";
 2659       } else {
 2660         code = code + " " + (this.negated ? '==' : '!=') + " null";
 2661       }
 2662       return [this.makeCode(o.level <= LEVEL_COND ? code : "(" + code + ")")];
 2663     };
 2664 
 2665     return Existence;
 2666 
 2667   })(Base);
 2668 
 2669   exports.Parens = Parens = (function(_super) {
 2670     __extends(Parens, _super);
 2671 
 2672     function Parens(_at_body) {
 2673       this.body = _at_body;
 2674     }
 2675 
 2676     Parens.prototype.children = ['body'];
 2677 
 2678     Parens.prototype.unwrap = function() {
 2679       return this.body;
 2680     };
 2681 
 2682     Parens.prototype.isComplex = function() {
 2683       return this.body.isComplex();
 2684     };
 2685 
 2686     Parens.prototype.compileNode = function(o) {
 2687       var bare, expr, fragments;
 2688       expr = this.body.unwrap();
 2689       if (expr instanceof Value && expr.isAtomic()) {
 2690         expr.front = this.front;
 2691         return expr.compileToFragments(o);
 2692       }
 2693       fragments = expr.compileToFragments(o, LEVEL_PAREN);
 2694       bare = o.level < LEVEL_OP && (expr instanceof Op || expr instanceof Call || (expr instanceof For && expr.returns));
 2695       if (bare) {
 2696         return fragments;
 2697       } else {
 2698         return this.wrapInBraces(fragments);
 2699       }
 2700     };
 2701 
 2702     return Parens;
 2703 
 2704   })(Base);
 2705 
 2706   exports.For = For = (function(_super) {
 2707     __extends(For, _super);
 2708 
 2709     function For(body, source) {
 2710       var _ref2;
 2711       this.source = source.source, this.guard = source.guard, this.step = source.step, this.name = source.name, this.index = source.index;
 2712       this.body = Block.wrap([body]);
 2713       this.own = !!source.own;
 2714       this.object = !!source.object;
 2715       if (this.object) {
 2716         _ref2 = [this.index, this.name], this.name = _ref2[0], this.index = _ref2[1];
 2717       }
 2718       if (this.index instanceof Value) {
 2719         this.index.error('index cannot be a pattern matching expression');
 2720       }
 2721       this.range = this.source instanceof Value && this.source.base instanceof Range && !this.source.properties.length;
 2722       this.pattern = this.name instanceof Value;
 2723       if (this.range && this.index) {
 2724         this.index.error('indexes do not apply to range loops');
 2725       }
 2726       if (this.range && this.pattern) {
 2727         this.name.error('cannot pattern match over range loops');
 2728       }
 2729       if (this.own && !this.object) {
 2730         this.name.error('cannot use own with for-in');
 2731       }
 2732       this.returns = false;
 2733     }
 2734 
 2735     For.prototype.children = ['body', 'source', 'guard', 'step'];
 2736 
 2737     For.prototype.compileNode = function(o) {
 2738       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;
 2739       body = Block.wrap([this.body]);
 2740       lastJumps = (_ref2 = last(body.expressions)) != null ? _ref2.jumps() : void 0;
 2741       if (lastJumps && lastJumps instanceof Return) {
 2742         this.returns = false;
 2743       }
 2744       source = this.range ? this.source.base : this.source;
 2745       scope = o.scope;
 2746       if (!this.pattern) {
 2747         name = this.name && (this.name.compile(o, LEVEL_LIST));
 2748       }
 2749       index = this.index && (this.index.compile(o, LEVEL_LIST));
 2750       if (name && !this.pattern) {
 2751         scope.find(name);
 2752       }
 2753       if (index) {
 2754         scope.find(index);
 2755       }
 2756       if (this.returns) {
 2757         rvar = scope.freeVariable('results');
 2758       }
 2759       ivar = (this.object && index) || scope.freeVariable('i');
 2760       kvar = (this.range && name) || index || ivar;
 2761       kvarAssign = kvar !== ivar ? kvar + " = " : "";
 2762       if (this.step && !this.range) {
 2763         _ref3 = this.cacheToCodeFragments(this.step.cache(o, LEVEL_LIST)), step = _ref3[0], stepVar = _ref3[1];
 2764         stepNum = stepVar.match(NUMBER);
 2765       }
 2766       if (this.pattern) {
 2767         name = ivar;
 2768       }
 2769       varPart = '';
 2770       guardPart = '';
 2771       defPart = '';
 2772       idt1 = this.tab + TAB;
 2773       if (this.range) {
 2774         forPartFragments = source.compileToFragments(merge(o, {
 2775           index: ivar,
 2776           name: name,
 2777           step: this.step
 2778         }));
 2779       } else {
 2780         svar = this.source.compile(o, LEVEL_LIST);
 2781         if ((name || this.own) && !IDENTIFIER.test(svar)) {
 2782           defPart += "" + this.tab + (ref = scope.freeVariable('ref')) + " = " + svar + ";\n";
 2783           svar = ref;
 2784         }
 2785         if (name && !this.pattern) {
 2786           namePart = name + " = " + svar + "[" + kvar + "]";
 2787         }
 2788         if (!this.object) {
 2789           if (step !== stepVar) {
 2790             defPart += "" + this.tab + step + ";\n";
 2791           }
 2792           if (!(this.step && stepNum && (down = parseNum(stepNum[0]) < 0))) {
 2793             lvar = scope.freeVariable('len');
 2794           }
 2795           declare = "" + kvarAssign + ivar + " = 0, " + lvar + " = " + svar + ".length";
 2796           declareDown = "" + kvarAssign + ivar + " = " + svar + ".length - 1";
 2797           compare = ivar + " < " + lvar;
 2798           compareDown = ivar + " >= 0";
 2799           if (this.step) {
 2800             if (stepNum) {
 2801               if (down) {
 2802                 compare = compareDown;
 2803                 declare = declareDown;
 2804               }
 2805             } else {
 2806               compare = stepVar + " > 0 ? " + compare + " : " + compareDown;
 2807               declare = "(" + stepVar + " > 0 ? (" + declare + ") : " + declareDown + ")";
 2808             }
 2809             increment = ivar + " += " + stepVar;
 2810           } else {
 2811             increment = "" + (kvar !== ivar ? "++" + ivar : ivar + "++");
 2812           }
 2813           forPartFragments = [this.makeCode(declare + "; " + compare + "; " + kvarAssign + increment)];
 2814         }
 2815       }
 2816       if (this.returns) {
 2817         resultPart = "" + this.tab + rvar + " = [];\n";
 2818         returnResult = "\n" + this.tab + "return " + rvar + ";";
 2819         body.makeReturn(rvar);
 2820       }
 2821       if (this.guard) {
 2822         if (body.expressions.length > 1) {
 2823           body.expressions.unshift(new If((new Parens(this.guard)).invert(), new Literal("continue")));
 2824         } else {
 2825           if (this.guard) {
 2826             body = Block.wrap([new If(this.guard, body)]);
 2827           }
 2828         }
 2829       }
 2830       if (this.pattern) {
 2831         body.expressions.unshift(new Assign(this.name, new Literal(svar + "[" + kvar + "]")));
 2832       }
 2833       defPartFragments = [].concat(this.makeCode(defPart), this.pluckDirectCall(o, body));
 2834       if (namePart) {
 2835         varPart = "\n" + idt1 + namePart + ";";
 2836       }
 2837       if (this.object) {
 2838         forPartFragments = [this.makeCode(kvar + " in " + svar)];
 2839         if (this.own) {
 2840           guardPart = "\n" + idt1 + "if (!" + (utility('hasProp', o)) + ".call(" + svar + ", " + kvar + ")) continue;";
 2841         }
 2842       }
 2843       bodyFragments = body.compileToFragments(merge(o, {
 2844         indent: idt1
 2845       }), LEVEL_TOP);
 2846       if (bodyFragments && (bodyFragments.length > 0)) {
 2847         bodyFragments = [].concat(this.makeCode("\n"), bodyFragments, this.makeCode("\n"));
 2848       }
 2849       return [].concat(defPartFragments, this.makeCode("" + (resultPart || '') + this.tab + "for ("), forPartFragments, this.makeCode(") {" + guardPart + varPart), bodyFragments, this.makeCode(this.tab + "}" + (returnResult || '')));
 2850     };
 2851 
 2852     For.prototype.pluckDirectCall = function(o, body) {
 2853       var base, defs, expr, fn, idx, ref, val, _i, _len, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8;
 2854       defs = [];
 2855       _ref2 = body.expressions;
 2856       for (idx = _i = 0, _len = _ref2.length; _i < _len; idx = ++_i) {
 2857         expr = _ref2[idx];
 2858         expr = expr.unwrapAll();
 2859         if (!(expr instanceof Call)) {
 2860           continue;
 2861         }
 2862         val = (_ref3 = expr.variable) != null ? _ref3.unwrapAll() : void 0;
 2863         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')))) {
 2864           continue;
 2865         }
 2866         fn = ((_ref7 = val.base) != null ? _ref7.unwrapAll() : void 0) || val;
 2867         ref = new Literal(o.scope.freeVariable('fn'));
 2868         base = new Value(ref);
 2869         if (val.base) {
 2870           _ref8 = [base, val], val.base = _ref8[0], base = _ref8[1];
 2871         }
 2872         body.expressions[idx] = new Call(base, expr.args);
 2873         defs = defs.concat(this.makeCode(this.tab), new Assign(ref, fn).compileToFragments(o, LEVEL_TOP), this.makeCode(';\n'));
 2874       }
 2875       return defs;
 2876     };
 2877 
 2878     return For;
 2879 
 2880   })(While);
 2881 
 2882   exports.Switch = Switch = (function(_super) {
 2883     __extends(Switch, _super);
 2884 
 2885     function Switch(_at_subject, _at_cases, _at_otherwise) {
 2886       this.subject = _at_subject;
 2887       this.cases = _at_cases;
 2888       this.otherwise = _at_otherwise;
 2889     }
 2890 
 2891     Switch.prototype.children = ['subject', 'cases', 'otherwise'];
 2892 
 2893     Switch.prototype.isStatement = YES;
 2894 
 2895     Switch.prototype.jumps = function(o) {
 2896       var block, conds, jumpNode, _i, _len, _ref2, _ref3, _ref4;
 2897       if (o == null) {
 2898         o = {
 2899           block: true
 2900         };
 2901       }
 2902       _ref2 = this.cases;
 2903       for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
 2904         _ref3 = _ref2[_i], conds = _ref3[0], block = _ref3[1];
 2905         if (jumpNode = block.jumps(o)) {
 2906           return jumpNode;
 2907         }
 2908       }
 2909       return (_ref4 = this.otherwise) != null ? _ref4.jumps(o) : void 0;
 2910     };
 2911 
 2912     Switch.prototype.makeReturn = function(res) {
 2913       var pair, _i, _len, _ref2, _ref3;
 2914       _ref2 = this.cases;
 2915       for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
 2916         pair = _ref2[_i];
 2917         pair[1].makeReturn(res);
 2918       }
 2919       if (res) {
 2920         this.otherwise || (this.otherwise = new Block([new Literal('void 0')]));
 2921       }
 2922       if ((_ref3 = this.otherwise) != null) {
 2923         _ref3.makeReturn(res);
 2924       }
 2925       return this;
 2926     };
 2927 
 2928     Switch.prototype.compileNode = function(o) {
 2929       var block, body, cond, conditions, expr, fragments, i, idt1, idt2, _i, _j, _len, _len1, _ref2, _ref3, _ref4;
 2930       idt1 = o.indent + TAB;
 2931       idt2 = o.indent = idt1 + TAB;
 2932       fragments = [].concat(this.makeCode(this.tab + "switch ("), (this.subject ? this.subject.compileToFragments(o, LEVEL_PAREN) : this.makeCode("false")), this.makeCode(") {\n"));
 2933       _ref2 = this.cases;
 2934       for (i = _i = 0, _len = _ref2.length; _i < _len; i = ++_i) {
 2935         _ref3 = _ref2[i], conditions = _ref3[0], block = _ref3[1];
 2936         _ref4 = flatten([conditions]);
 2937         for (_j = 0, _len1 = _ref4.length; _j < _len1; _j++) {
 2938           cond = _ref4[_j];
 2939           if (!this.subject) {
 2940             cond = cond.invert();
 2941           }
 2942           fragments = fragments.concat(this.makeCode(idt1 + "case "), cond.compileToFragments(o, LEVEL_PAREN), this.makeCode(":\n"));
 2943         }
 2944         if ((body = block.compileToFragments(o, LEVEL_TOP)).length > 0) {
 2945           fragments = fragments.concat(body, this.makeCode('\n'));
 2946         }
 2947         if (i === this.cases.length - 1 && !this.otherwise) {
 2948           break;
 2949         }
 2950         expr = this.lastNonComment(block.expressions);
 2951         if (expr instanceof Return || (expr instanceof Literal && expr.jumps() && expr.value !== 'debugger')) {
 2952           continue;
 2953         }
 2954         fragments.push(cond.makeCode(idt2 + 'break;\n'));
 2955       }
 2956       if (this.otherwise && this.otherwise.expressions.length) {
 2957         fragments.push.apply(fragments, [this.makeCode(idt1 + "default:\n")].concat(__slice.call(this.otherwise.compileToFragments(o, LEVEL_TOP)), [this.makeCode("\n")]));
 2958       }
 2959       fragments.push(this.makeCode(this.tab + '}'));
 2960       return fragments;
 2961     };
 2962 
 2963     return Switch;
 2964 
 2965   })(Base);
 2966 
 2967   exports.If = If = (function(_super) {
 2968     __extends(If, _super);
 2969 
 2970     function If(condition, _at_body, options) {
 2971       this.body = _at_body;
 2972       if (options == null) {
 2973         options = {};
 2974       }
 2975       this.condition = options.type === 'unless' ? condition.invert() : condition;
 2976       this.elseBody = null;
 2977       this.isChain = false;
 2978       this.soak = options.soak;
 2979     }
 2980 
 2981     If.prototype.children = ['condition', 'body', 'elseBody'];
 2982 
 2983     If.prototype.bodyNode = function() {
 2984       var _ref2;
 2985       return (_ref2 = this.body) != null ? _ref2.unwrap() : void 0;
 2986     };
 2987 
 2988     If.prototype.elseBodyNode = function() {
 2989       var _ref2;
 2990       return (_ref2 = this.elseBody) != null ? _ref2.unwrap() : void 0;
 2991     };
 2992 
 2993     If.prototype.addElse = function(elseBody) {
 2994       if (this.isChain) {
 2995         this.elseBodyNode().addElse(elseBody);
 2996       } else {
 2997         this.isChain = elseBody instanceof If;
 2998         this.elseBody = this.ensureBlock(elseBody);
 2999         this.elseBody.updateLocationDataIfMissing(elseBody.locationData);
 3000       }
 3001       return this;
 3002     };
 3003 
 3004     If.prototype.isStatement = function(o) {
 3005       var _ref2;
 3006       return (o != null ? o.level : void 0) === LEVEL_TOP || this.bodyNode().isStatement(o) || ((_ref2 = this.elseBodyNode()) != null ? _ref2.isStatement(o) : void 0);
 3007     };
 3008 
 3009     If.prototype.jumps = function(o) {
 3010       var _ref2;
 3011       return this.body.jumps(o) || ((_ref2 = this.elseBody) != null ? _ref2.jumps(o) : void 0);
 3012     };
 3013 
 3014     If.prototype.compileNode = function(o) {
 3015       if (this.isStatement(o)) {
 3016         return this.compileStatement(o);
 3017       } else {
 3018         return this.compileExpression(o);
 3019       }
 3020     };
 3021 
 3022     If.prototype.makeReturn = function(res) {
 3023       if (res) {
 3024         this.elseBody || (this.elseBody = new Block([new Literal('void 0')]));
 3025       }
 3026       this.body && (this.body = new Block([this.body.makeReturn(res)]));
 3027       this.elseBody && (this.elseBody = new Block([this.elseBody.makeReturn(res)]));
 3028       return this;
 3029     };
 3030 
 3031     If.prototype.ensureBlock = function(node) {
 3032       if (node instanceof Block) {
 3033         return node;
 3034       } else {
 3035         return new Block([node]);
 3036       }
 3037     };
 3038 
 3039     If.prototype.compileStatement = function(o) {
 3040       var answer, body, child, cond, exeq, ifPart, indent;
 3041       child = del(o, 'chainChild');
 3042       exeq = del(o, 'isExistentialEquals');
 3043       if (exeq) {
 3044         return new If(this.condition.invert(), this.elseBodyNode(), {
 3045           type: 'if'
 3046         }).compileToFragments(o);
 3047       }
 3048       indent = o.indent + TAB;
 3049       cond = this.condition.compileToFragments(o, LEVEL_PAREN);
 3050       body = this.ensureBlock(this.body).compileToFragments(merge(o, {
 3051         indent: indent
 3052       }));
 3053       ifPart = [].concat(this.makeCode("if ("), cond, this.makeCode(") {\n"), body, this.makeCode("\n" + this.tab + "}"));
 3054       if (!child) {
 3055         ifPart.unshift(this.makeCode(this.tab));
 3056       }
 3057       if (!this.elseBody) {
 3058         return ifPart;
 3059       }
 3060       answer = ifPart.concat(this.makeCode(' else '));
 3061       if (this.isChain) {
 3062         o.chainChild = true;
 3063         answer = answer.concat(this.elseBody.unwrap().compileToFragments(o, LEVEL_TOP));
 3064       } else {
 3065         answer = answer.concat(this.makeCode("{\n"), this.elseBody.compileToFragments(merge(o, {
 3066           indent: indent
 3067         }), LEVEL_TOP), this.makeCode("\n" + this.tab + "}"));
 3068       }
 3069       return answer;
 3070     };
 3071 
 3072     If.prototype.compileExpression = function(o) {
 3073       var alt, body, cond, fragments;
 3074       cond = this.condition.compileToFragments(o, LEVEL_COND);
 3075       body = this.bodyNode().compileToFragments(o, LEVEL_LIST);
 3076       alt = this.elseBodyNode() ? this.elseBodyNode().compileToFragments(o, LEVEL_LIST) : [this.makeCode('void 0')];
 3077       fragments = cond.concat(this.makeCode(" ? "), body, this.makeCode(" : "), alt);
 3078       if (o.level >= LEVEL_COND) {
 3079         return this.wrapInBraces(fragments);
 3080       } else {
 3081         return fragments;
 3082       }
 3083     };
 3084 
 3085     If.prototype.unfoldSoak = function() {
 3086       return this.soak && this;
 3087     };
 3088 
 3089     return If;
 3090 
 3091   })(Base);
 3092 
 3093   UTILITIES = {
 3094     "extends": function(o) {
 3095       return "function(child, parent) { for (var key in parent) { if (" + (utility('hasProp', o)) + ".call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }";
 3096     },
 3097     bind: function() {
 3098       return 'function(fn, me){ return function(){ return fn.apply(me, arguments); }; }';
 3099     },
 3100     indexOf: function() {
 3101       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; }";
 3102     },
 3103     modulo: function() {
 3104       return "function(a, b) { return (+a % (b = +b) + b) % b; }";
 3105     },
 3106     hasProp: function() {
 3107       return '{}.hasOwnProperty';
 3108     },
 3109     slice: function() {
 3110       return '[].slice';
 3111     }
 3112   };
 3113 
 3114   LEVEL_TOP = 1;
 3115 
 3116   LEVEL_PAREN = 2;
 3117 
 3118   LEVEL_LIST = 3;
 3119 
 3120   LEVEL_COND = 4;
 3121 
 3122   LEVEL_OP = 5;
 3123 
 3124   LEVEL_ACCESS = 6;
 3125 
 3126   TAB = '  ';
 3127 
 3128   IDENTIFIER_STR = "[$A-Za-z_\\x7f-\\uffff][$\\w\\x7f-\\uffff]*";
 3129 
 3130   IDENTIFIER = RegExp("^" + IDENTIFIER_STR + "$");
 3131 
 3132   SIMPLENUM = /^[+-]?\d+$/;
 3133 
 3134   HEXNUM = /^[+-]?0x[\da-f]+/i;
 3135 
 3136   NUMBER = /^[+-]?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)$/i;
 3137 
 3138   METHOD_DEF = RegExp("^(" + IDENTIFIER_STR + ")(\\.prototype)?(?:\\.(" + IDENTIFIER_STR + ")|\\[(\"(?:[^\\\\\"\\r\\n]|\\\\.)*\"|'(?:[^\\\\'\\r\\n]|\\\\.)*')\\]|\\[(0x[\\da-fA-F]+|\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\])$");
 3139 
 3140   IS_STRING = /^['"]/;
 3141 
 3142   IS_REGEX = /^\//;
 3143 
 3144   utility = function(name, o) {
 3145     var ref, root;
 3146     root = o.scope.root;
 3147     if (name in root.utilities) {
 3148       return root.utilities[name];
 3149     } else {
 3150       ref = root.freeVariable("_" + name);
 3151       root.assign(ref, UTILITIES[name](o));
 3152       return root.utilities[name] = ref;
 3153     }
 3154   };
 3155 
 3156   multident = function(code, tab) {
 3157     code = code.replace(/\n/g, '$&' + tab);
 3158     return code.replace(/\s+$/, '');
 3159   };
 3160 
 3161   parseNum = function(x) {
 3162     if (x == null) {
 3163       return 0;
 3164     } else if (x.match(HEXNUM)) {
 3165       return parseInt(x, 16);
 3166     } else {
 3167       return parseFloat(x);
 3168     }
 3169   };
 3170 
 3171   isLiteralArguments = function(node) {
 3172     return node instanceof Literal && node.value === 'arguments' && !node.asKey;
 3173   };
 3174 
 3175   isLiteralThis = function(node) {
 3176     return (node instanceof Literal && node.value === 'this' && !node.asKey) || (node instanceof Code && node.bound) || (node instanceof Call && node.isSuper);
 3177   };
 3178 
 3179   unfoldSoak = function(o, parent, name) {
 3180     var ifn;
 3181     if (!(ifn = parent[name].unfoldSoak(o))) {
 3182       return;
 3183     }
 3184     parent[name] = ifn.body;
 3185     ifn.body = new Value(parent);
 3186     return ifn;
 3187   };
 3188 
 3189 }).call(this);