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