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