coffee-script 0.3.1 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- data/coffee-script.gemspec +2 -2
- data/examples/blocks.coffee +57 -0
- data/extras/CoffeeScript.tmbundle/Syntaxes/CoffeeScript.tmLanguage +6 -0
- data/lib/coffee-script.rb +1 -1
- data/lib/coffee_script/coffee-script.js +50 -0
- data/lib/coffee_script/command_line.rb +17 -11
- data/lib/coffee_script/grammar.y +11 -9
- data/lib/coffee_script/lexer.js +363 -0
- data/lib/coffee_script/lexer.rb +2 -4
- data/lib/coffee_script/narwhal/{lib/coffee-script.js → coffee-script.js} +21 -5
- data/lib/coffee_script/nodes.js +443 -0
- data/lib/coffee_script/nodes.rb +24 -9
- data/lib/coffee_script/parser.js +477 -0
- data/lib/coffee_script/parser.rb +1222 -1140
- data/lib/coffee_script/repl.js +33 -0
- data/lib/coffee_script/rewriter.js +377 -0
- data/lib/coffee_script/rewriter.rb +26 -26
- data/lib/coffee_script/runner.js +11 -0
- data/lib/coffee_script/scope.js +73 -0
- data/package.json +2 -3
- metadata +12 -6
- data/lib/coffee_script/narwhal/coffee-script.coffee +0 -62
- data/lib/coffee_script/narwhal/lib/coffee-script/loader.js +0 -21
- data/lib/coffee_script/narwhal/loader.coffee +0 -19
data/lib/coffee_script/lexer.rb
CHANGED
@@ -15,8 +15,7 @@ module CoffeeScript
|
|
15
15
|
"for", "in", "of", "by", "where", "while",
|
16
16
|
"delete", "instanceof", "typeof",
|
17
17
|
"switch", "when",
|
18
|
-
"super", "extends"
|
19
|
-
"arguments"]
|
18
|
+
"super", "extends"]
|
20
19
|
|
21
20
|
# Token matching regexes.
|
22
21
|
IDENTIFIER = /\A([a-zA-Z$_](\w|\$)*)/
|
@@ -229,8 +228,7 @@ module CoffeeScript
|
|
229
228
|
|
230
229
|
# Helpers ==========================================================
|
231
230
|
|
232
|
-
# Add a token to the results, taking note of the line number
|
233
|
-
# immediately-preceding comment.
|
231
|
+
# Add a token to the results, taking note of the line number.
|
234
232
|
def token(tag, value)
|
235
233
|
@tokens << [tag, Value.new(value, @line)]
|
236
234
|
end
|
@@ -1,14 +1,12 @@
|
|
1
1
|
(function(){
|
2
|
-
var File, OS, Readline, checkForErrors, coffeePath;
|
3
|
-
//
|
4
|
-
// Executes the `coffee` Ruby program to convert from CoffeeScript
|
5
|
-
// to Javascript. Eventually this will hopefully happen entirely within JS.
|
2
|
+
var File, OS, Readline, checkForErrors, coffeePath, factories, loader, puts;
|
3
|
+
// The Narwhal-compatibility wrapper for CoffeeScript.
|
6
4
|
// Require external dependencies.
|
7
5
|
OS = require('os');
|
8
6
|
File = require('file');
|
9
7
|
Readline = require('readline');
|
10
8
|
// The path to the CoffeeScript Compiler.
|
11
|
-
coffeePath = File.path(module.path).dirname().dirname().dirname().dirname().
|
9
|
+
coffeePath = File.path(module.path).dirname().dirname().dirname().dirname().join('bin', 'coffee');
|
12
10
|
// Our general-purpose error handler.
|
13
11
|
checkForErrors = function checkForErrors(coffeeProcess) {
|
14
12
|
if (coffeeProcess.wait() === 0) {
|
@@ -17,6 +15,8 @@
|
|
17
15
|
system.stderr.print(coffeeProcess.stderr.read());
|
18
16
|
throw new Error("CoffeeScript compile error");
|
19
17
|
};
|
18
|
+
// Alias print to "puts", for Node.js compatibility:
|
19
|
+
puts = print;
|
20
20
|
// Run a simple REPL, round-tripping to the CoffeeScript compiler for every
|
21
21
|
// command.
|
22
22
|
exports.run = function run(args) {
|
@@ -77,4 +77,20 @@
|
|
77
77
|
return eval("(" + factoryText + ")");
|
78
78
|
}
|
79
79
|
};
|
80
|
+
// The Narwhal loader for '.coffee' files.
|
81
|
+
factories = {
|
82
|
+
};
|
83
|
+
loader = {
|
84
|
+
};
|
85
|
+
// Reload the coffee-script environment from source.
|
86
|
+
loader.reload = function reload(topId, path) {
|
87
|
+
return factories[topId] = function() {
|
88
|
+
return exports.makeNarwhalFactory(path);
|
89
|
+
};
|
90
|
+
};
|
91
|
+
// Ensure that the coffee-script environment is loaded.
|
92
|
+
loader.load = function load(topId, path) {
|
93
|
+
return factories[topId] = factories[topId] || this.reload(topId, path);
|
94
|
+
};
|
95
|
+
require.loader.loaders.unshift([".coffee", loader]);
|
80
96
|
})();
|
@@ -0,0 +1,443 @@
|
|
1
|
+
(function(){
|
2
|
+
var compact, dup, flatten;
|
3
|
+
var __hasProp = Object.prototype.hasOwnProperty;
|
4
|
+
// The abstract base class for all CoffeeScript nodes.
|
5
|
+
// All nodes are implement a "compile_node" method, which performs the
|
6
|
+
// code generation for that node. To compile a node, call the "compile"
|
7
|
+
// method, which wraps "compile_node" in some extra smarts, to know when the
|
8
|
+
// generated code should be wrapped up in a closure. An options hash is passed
|
9
|
+
// and cloned throughout, containing messages from higher in the AST,
|
10
|
+
// information about the current scope, and indentation level.
|
11
|
+
exports.Node = function Node() {
|
12
|
+
var __a;
|
13
|
+
var arguments = Array.prototype.slice.call(arguments, 0);
|
14
|
+
this.values = arguments;
|
15
|
+
__a = this.name = this.constructor.name;
|
16
|
+
return Node === this.constructor ? this : __a;
|
17
|
+
};
|
18
|
+
exports.Expressions = function Expressions() {
|
19
|
+
var __a;
|
20
|
+
var arguments = Array.prototype.slice.call(arguments, 0);
|
21
|
+
this.name = this.constructor.name;
|
22
|
+
__a = this.values = arguments;
|
23
|
+
return Expressions === this.constructor ? this : __a;
|
24
|
+
};
|
25
|
+
exports.LiteralNode = function LiteralNode() {
|
26
|
+
var __a;
|
27
|
+
var arguments = Array.prototype.slice.call(arguments, 0);
|
28
|
+
this.name = this.constructor.name;
|
29
|
+
__a = this.values = arguments;
|
30
|
+
return LiteralNode === this.constructor ? this : __a;
|
31
|
+
};
|
32
|
+
exports.ReturnNode = function ReturnNode() {
|
33
|
+
var __a;
|
34
|
+
var arguments = Array.prototype.slice.call(arguments, 0);
|
35
|
+
this.name = this.constructor.name;
|
36
|
+
__a = this.values = arguments;
|
37
|
+
return ReturnNode === this.constructor ? this : __a;
|
38
|
+
};
|
39
|
+
exports.CommentNode = function CommentNode() {
|
40
|
+
var __a;
|
41
|
+
var arguments = Array.prototype.slice.call(arguments, 0);
|
42
|
+
this.name = this.constructor.name;
|
43
|
+
__a = this.values = arguments;
|
44
|
+
return CommentNode === this.constructor ? this : __a;
|
45
|
+
};
|
46
|
+
exports.CallNode = function CallNode() {
|
47
|
+
var __a;
|
48
|
+
var arguments = Array.prototype.slice.call(arguments, 0);
|
49
|
+
this.name = this.constructor.name;
|
50
|
+
__a = this.values = arguments;
|
51
|
+
return CallNode === this.constructor ? this : __a;
|
52
|
+
};
|
53
|
+
exports.ExtendsNode = function ExtendsNode() {
|
54
|
+
var __a;
|
55
|
+
var arguments = Array.prototype.slice.call(arguments, 0);
|
56
|
+
this.name = this.constructor.name;
|
57
|
+
__a = this.values = arguments;
|
58
|
+
return ExtendsNode === this.constructor ? this : __a;
|
59
|
+
};
|
60
|
+
exports.ValueNode = function ValueNode() {
|
61
|
+
var __a;
|
62
|
+
var arguments = Array.prototype.slice.call(arguments, 0);
|
63
|
+
this.name = this.constructor.name;
|
64
|
+
__a = this.values = arguments;
|
65
|
+
return ValueNode === this.constructor ? this : __a;
|
66
|
+
};
|
67
|
+
exports.AccessorNode = function AccessorNode() {
|
68
|
+
var __a;
|
69
|
+
var arguments = Array.prototype.slice.call(arguments, 0);
|
70
|
+
this.name = this.constructor.name;
|
71
|
+
__a = this.values = arguments;
|
72
|
+
return AccessorNode === this.constructor ? this : __a;
|
73
|
+
};
|
74
|
+
exports.IndexNode = function IndexNode() {
|
75
|
+
var __a;
|
76
|
+
var arguments = Array.prototype.slice.call(arguments, 0);
|
77
|
+
this.name = this.constructor.name;
|
78
|
+
__a = this.values = arguments;
|
79
|
+
return IndexNode === this.constructor ? this : __a;
|
80
|
+
};
|
81
|
+
exports.RangeNode = function RangeNode() {
|
82
|
+
var __a;
|
83
|
+
var arguments = Array.prototype.slice.call(arguments, 0);
|
84
|
+
this.name = this.constructor.name;
|
85
|
+
__a = this.values = arguments;
|
86
|
+
return RangeNode === this.constructor ? this : __a;
|
87
|
+
};
|
88
|
+
exports.SliceNode = function SliceNode() {
|
89
|
+
var __a;
|
90
|
+
var arguments = Array.prototype.slice.call(arguments, 0);
|
91
|
+
this.name = this.constructor.name;
|
92
|
+
__a = this.values = arguments;
|
93
|
+
return SliceNode === this.constructor ? this : __a;
|
94
|
+
};
|
95
|
+
exports.AssignNode = function AssignNode() {
|
96
|
+
var __a;
|
97
|
+
var arguments = Array.prototype.slice.call(arguments, 0);
|
98
|
+
this.name = this.constructor.name;
|
99
|
+
__a = this.values = arguments;
|
100
|
+
return AssignNode === this.constructor ? this : __a;
|
101
|
+
};
|
102
|
+
exports.OpNode = function OpNode() {
|
103
|
+
var __a;
|
104
|
+
var arguments = Array.prototype.slice.call(arguments, 0);
|
105
|
+
this.name = this.constructor.name;
|
106
|
+
__a = this.values = arguments;
|
107
|
+
return OpNode === this.constructor ? this : __a;
|
108
|
+
};
|
109
|
+
exports.CodeNode = function CodeNode() {
|
110
|
+
var __a;
|
111
|
+
var arguments = Array.prototype.slice.call(arguments, 0);
|
112
|
+
this.name = this.constructor.name;
|
113
|
+
__a = this.values = arguments;
|
114
|
+
return CodeNode === this.constructor ? this : __a;
|
115
|
+
};
|
116
|
+
exports.SplatNode = function SplatNode() {
|
117
|
+
var __a;
|
118
|
+
var arguments = Array.prototype.slice.call(arguments, 0);
|
119
|
+
this.name = this.constructor.name;
|
120
|
+
__a = this.values = arguments;
|
121
|
+
return SplatNode === this.constructor ? this : __a;
|
122
|
+
};
|
123
|
+
exports.ObjectNode = function ObjectNode() {
|
124
|
+
var __a;
|
125
|
+
var arguments = Array.prototype.slice.call(arguments, 0);
|
126
|
+
this.name = this.constructor.name;
|
127
|
+
__a = this.values = arguments;
|
128
|
+
return ObjectNode === this.constructor ? this : __a;
|
129
|
+
};
|
130
|
+
exports.ArrayNode = function ArrayNode() {
|
131
|
+
var __a;
|
132
|
+
var arguments = Array.prototype.slice.call(arguments, 0);
|
133
|
+
this.name = this.constructor.name;
|
134
|
+
__a = this.values = arguments;
|
135
|
+
return ArrayNode === this.constructor ? this : __a;
|
136
|
+
};
|
137
|
+
exports.PushNode = function PushNode() {
|
138
|
+
var __a;
|
139
|
+
var arguments = Array.prototype.slice.call(arguments, 0);
|
140
|
+
this.name = this.constructor.name;
|
141
|
+
__a = this.values = arguments;
|
142
|
+
return PushNode === this.constructor ? this : __a;
|
143
|
+
};
|
144
|
+
exports.ClosureNode = function ClosureNode() {
|
145
|
+
var __a;
|
146
|
+
var arguments = Array.prototype.slice.call(arguments, 0);
|
147
|
+
this.name = this.constructor.name;
|
148
|
+
__a = this.values = arguments;
|
149
|
+
return ClosureNode === this.constructor ? this : __a;
|
150
|
+
};
|
151
|
+
exports.WhileNode = function WhileNode() {
|
152
|
+
var __a;
|
153
|
+
var arguments = Array.prototype.slice.call(arguments, 0);
|
154
|
+
this.name = this.constructor.name;
|
155
|
+
__a = this.values = arguments;
|
156
|
+
return WhileNode === this.constructor ? this : __a;
|
157
|
+
};
|
158
|
+
exports.ForNode = function ForNode() {
|
159
|
+
var __a;
|
160
|
+
var arguments = Array.prototype.slice.call(arguments, 0);
|
161
|
+
this.name = this.constructor.name;
|
162
|
+
__a = this.values = arguments;
|
163
|
+
return ForNode === this.constructor ? this : __a;
|
164
|
+
};
|
165
|
+
exports.TryNode = function TryNode() {
|
166
|
+
var __a;
|
167
|
+
var arguments = Array.prototype.slice.call(arguments, 0);
|
168
|
+
this.name = this.constructor.name;
|
169
|
+
__a = this.values = arguments;
|
170
|
+
return TryNode === this.constructor ? this : __a;
|
171
|
+
};
|
172
|
+
exports.ThrowNode = function ThrowNode() {
|
173
|
+
var __a;
|
174
|
+
var arguments = Array.prototype.slice.call(arguments, 0);
|
175
|
+
this.name = this.constructor.name;
|
176
|
+
__a = this.values = arguments;
|
177
|
+
return ThrowNode === this.constructor ? this : __a;
|
178
|
+
};
|
179
|
+
exports.ExistenceNode = function ExistenceNode() {
|
180
|
+
var __a;
|
181
|
+
var arguments = Array.prototype.slice.call(arguments, 0);
|
182
|
+
this.name = this.constructor.name;
|
183
|
+
__a = this.values = arguments;
|
184
|
+
return ExistenceNode === this.constructor ? this : __a;
|
185
|
+
};
|
186
|
+
exports.ParentheticalNode = function ParentheticalNode() {
|
187
|
+
var __a;
|
188
|
+
var arguments = Array.prototype.slice.call(arguments, 0);
|
189
|
+
this.name = this.constructor.name;
|
190
|
+
__a = this.values = arguments;
|
191
|
+
return ParentheticalNode === this.constructor ? this : __a;
|
192
|
+
};
|
193
|
+
exports.IfNode = function IfNode() {
|
194
|
+
var __a;
|
195
|
+
var arguments = Array.prototype.slice.call(arguments, 0);
|
196
|
+
this.name = this.constructor.name;
|
197
|
+
__a = this.values = arguments;
|
198
|
+
return IfNode === this.constructor ? this : __a;
|
199
|
+
};
|
200
|
+
exports.Expressions.wrap = function wrap(values) {
|
201
|
+
return this.values = values;
|
202
|
+
};
|
203
|
+
// Some helper functions
|
204
|
+
// TODO -- shallow (1 deep) flatten..
|
205
|
+
// need recursive version..
|
206
|
+
flatten = function flatten(aggList, newList) {
|
207
|
+
var __a, __b, item;
|
208
|
+
__a = newList;
|
209
|
+
for (__b = 0; __b < __a.length; __b++) {
|
210
|
+
item = __a[__b];
|
211
|
+
aggList.push(item);
|
212
|
+
}
|
213
|
+
return aggList;
|
214
|
+
};
|
215
|
+
compact = function compact(input) {
|
216
|
+
var __a, __b, __c, compected, item;
|
217
|
+
compected = [];
|
218
|
+
__a = []; __b = input;
|
219
|
+
for (__c = 0; __c < __b.length; __c++) {
|
220
|
+
item = __b[__c];
|
221
|
+
__a.push((typeof item !== "undefined" && item !== null) ? compacted.push(item) : null);
|
222
|
+
}
|
223
|
+
return __a;
|
224
|
+
};
|
225
|
+
dup = function dup(input) {
|
226
|
+
var __a, __b, __c, key, output, val;
|
227
|
+
output = null;
|
228
|
+
if (input instanceof Array) {
|
229
|
+
output = [];
|
230
|
+
__a = input;
|
231
|
+
for (__b = 0; __b < __a.length; __b++) {
|
232
|
+
val = __a[__b];
|
233
|
+
output.push(val);
|
234
|
+
}
|
235
|
+
} else {
|
236
|
+
output = {
|
237
|
+
};
|
238
|
+
__c = input;
|
239
|
+
for (key in __c) {
|
240
|
+
val = __c[key];
|
241
|
+
if (__hasProp.call(__c, key)) {
|
242
|
+
output.key = val;
|
243
|
+
}
|
244
|
+
}
|
245
|
+
output;
|
246
|
+
}
|
247
|
+
return output;
|
248
|
+
};
|
249
|
+
exports.Node.prototype.TAB = ' ';
|
250
|
+
// Tag this node as a statement, meaning that it can't be used directly as
|
251
|
+
// the result of an expression.
|
252
|
+
exports.Node.prototype.mark_as_statement = function mark_as_statement() {
|
253
|
+
return this.is_statement = function is_statement() {
|
254
|
+
return true;
|
255
|
+
};
|
256
|
+
};
|
257
|
+
// Tag this node as a statement that cannot be transformed into an expression.
|
258
|
+
// (break, continue, etc.) It doesn't make sense to try to transform it.
|
259
|
+
exports.Node.prototype.mark_as_statement_only = function mark_as_statement_only() {
|
260
|
+
this.mark_as_statement();
|
261
|
+
return this.is_statement_only = function is_statement_only() {
|
262
|
+
return true;
|
263
|
+
};
|
264
|
+
};
|
265
|
+
// This node needs to know if it's being compiled as a top-level statement,
|
266
|
+
// in order to compile without special expression conversion.
|
267
|
+
exports.Node.prototype.mark_as_top_sensitive = function mark_as_top_sensitive() {
|
268
|
+
return this.is_top_sensitive = function is_top_sensitive() {
|
269
|
+
return true;
|
270
|
+
};
|
271
|
+
};
|
272
|
+
// Provide a quick implementation of a children method.
|
273
|
+
exports.Node.prototype.children = function children(attributes) {
|
274
|
+
var __a, __b, agg, compacted, item;
|
275
|
+
// TODO -- are these optimal impls of flatten and compact
|
276
|
+
// .. do better ones exist in a stdlib?
|
277
|
+
agg = [];
|
278
|
+
__a = attributes;
|
279
|
+
for (__b = 0; __b < __a.length; __b++) {
|
280
|
+
item = __a[__b];
|
281
|
+
agg = flatten(agg, item);
|
282
|
+
}
|
283
|
+
compacted = compact(agg);
|
284
|
+
return this.children = function children() {
|
285
|
+
return compacted;
|
286
|
+
};
|
287
|
+
};
|
288
|
+
exports.Node.prototype.write = function write(code) {
|
289
|
+
// hm..
|
290
|
+
// TODO -- should print to STDOUT in "VERBOSE" how to
|
291
|
+
// go about this.. ? jsonify 'this'?
|
292
|
+
// use node's puts ??
|
293
|
+
return code;
|
294
|
+
};
|
295
|
+
// This is extremely important -- we convert JS statements into expressions
|
296
|
+
// by wrapping them in a closure, only if it's possible, and we're not at
|
297
|
+
// the top level of a block (which would be unnecessary), and we haven't
|
298
|
+
// already been asked to return the result.
|
299
|
+
exports.Node.prototype.compile = function compile(o) {
|
300
|
+
var closure, opts, top;
|
301
|
+
// TODO -- need JS dup/clone
|
302
|
+
opts = (typeof !o !== "undefined" && !o !== null) ? {
|
303
|
+
} : o;
|
304
|
+
this.options = opts;
|
305
|
+
this.indent = opts.indent;
|
306
|
+
top = this.options.top;
|
307
|
+
!this.is_top_sentitive() ? (this.options.top = undefined) : null;
|
308
|
+
closure = this.is_statement() && !this.is_statement_only() && !top && typeof (this) === "CommentNode";
|
309
|
+
closure = closure && !this.do_i_contain(function(n) {
|
310
|
+
return n.is_statement_only();
|
311
|
+
});
|
312
|
+
return closure ? this.compile_closure(this.options) : compile_node(this.options);
|
313
|
+
};
|
314
|
+
// Statements converted into expressions share scope with their parent
|
315
|
+
// closure, to preserve JavaScript-style lexical scope.
|
316
|
+
exports.Node.prototype.compile_closure = function compile_closure(o) {
|
317
|
+
var opts;
|
318
|
+
opts = (typeof !o !== "undefined" && !o !== null) ? {
|
319
|
+
} : o;
|
320
|
+
this.indent = opts.indent;
|
321
|
+
opts.shared_scope = o.scope;
|
322
|
+
return exports.ClosureNode.wrap(this).compile(opts);
|
323
|
+
};
|
324
|
+
// Quick short method for the current indentation level, plus tabbing in.
|
325
|
+
exports.Node.prototype.idt = function idt(tLvl) {
|
326
|
+
var __a, __b, __c, __d, tabAmt, tabs, x;
|
327
|
+
tabs = (typeof tLvl !== "undefined" && tLvl !== null) ? tLvl : 0;
|
328
|
+
tabAmt = '';
|
329
|
+
__c = 0; __d = tabs;
|
330
|
+
for (__b=0, x=__c; (__c <= __d ? x < __d : x > __d); (__c <= __d ? x += 1 : x -= 1), __b++) {
|
331
|
+
tabAmt = tabAmt + this.TAB;
|
332
|
+
}
|
333
|
+
return this.indent + tabAmt;
|
334
|
+
};
|
335
|
+
//Does this node, or any of it's children, contain a node of a certain kind?
|
336
|
+
exports.Node.prototype.do_i_contain = function do_i_contain(block) {
|
337
|
+
var __a, __b, node;
|
338
|
+
__a = this.children;
|
339
|
+
for (__b = 0; __b < __a.length; __b++) {
|
340
|
+
node = __a[__b];
|
341
|
+
if (block(node)) {
|
342
|
+
return true;
|
343
|
+
}
|
344
|
+
if (node instanceof exports.Node && node.do_i_contain(block)) {
|
345
|
+
return true;
|
346
|
+
}
|
347
|
+
}
|
348
|
+
return false;
|
349
|
+
};
|
350
|
+
// Default implementations of the common node methods.
|
351
|
+
exports.Node.prototype.unwrap = function unwrap() {
|
352
|
+
return this;
|
353
|
+
};
|
354
|
+
exports.Node.prototype.children = [];
|
355
|
+
exports.Node.prototype.is_a_statement = function is_a_statement() {
|
356
|
+
return false;
|
357
|
+
};
|
358
|
+
exports.Node.prototype.is_a_statement_only = function is_a_statement_only() {
|
359
|
+
return false;
|
360
|
+
};
|
361
|
+
exports.Node.prototype.is_top_sensitive = function is_top_sensitive() {
|
362
|
+
return false;
|
363
|
+
};
|
364
|
+
// A collection of nodes, each one representing an expression.
|
365
|
+
// exports.Expressions: (nodes) ->
|
366
|
+
// this.mark_as_statement()
|
367
|
+
// this.expressions: []
|
368
|
+
// this.children([this.expressions])
|
369
|
+
// for n in nodes
|
370
|
+
// this.expressions: flatten this.expressions, n
|
371
|
+
// exports.Expressions extends exports.Node
|
372
|
+
exports.Expressions.prototype.TRAILING_WHITESPACE = /\s+$/;
|
373
|
+
// Wrap up a node as an Expressions, unless it already is.
|
374
|
+
exports.Expressions.prototype.wrap = function wrap(nodes) {
|
375
|
+
if (nodes.length === 1 && nodes[0] instanceof exports.Expressions) {
|
376
|
+
return nodes[0];
|
377
|
+
}
|
378
|
+
return new Expressions(nodes);
|
379
|
+
};
|
380
|
+
// Tack an expression on to the end of this expression list.
|
381
|
+
exports.Expressions.prototype.push = function push(node) {
|
382
|
+
this.expressions.push(node);
|
383
|
+
return this;
|
384
|
+
};
|
385
|
+
// Tack an expression on to the beginning of this expression list.
|
386
|
+
exports.Expressions.prototype.unshift = function unshift(node) {
|
387
|
+
this.expressions.unshift(node);
|
388
|
+
return this;
|
389
|
+
};
|
390
|
+
// If this Expressions consists of a single node, pull it back out.
|
391
|
+
exports.Expressions.prototype.unwrap = function unwrap() {
|
392
|
+
return this.expressions.length === 1 ? this.expressions[0] : this;
|
393
|
+
};
|
394
|
+
// Is this an empty block of code?
|
395
|
+
exports.Expressions.prototype.is_empty = function is_empty() {
|
396
|
+
return this.expressions.length === 0;
|
397
|
+
};
|
398
|
+
// Is the node last in this block of expressions.
|
399
|
+
exports.Expressions.prototype.is_last = function is_last(node) {
|
400
|
+
var arr_length;
|
401
|
+
arr_length = this.expressions.length;
|
402
|
+
this.last_index = this.last_index || this.expressions[arr_length - 1] instanceof exports.CommentNode ? -2 : -1;
|
403
|
+
return node === this.expressions[arr_length - this.last_index];
|
404
|
+
};
|
405
|
+
exports.Expressions.prototype.compile = function compile(o) {
|
406
|
+
var opts;
|
407
|
+
opts = (typeof o !== "undefined" && o !== null) ? o : {
|
408
|
+
};
|
409
|
+
return opts.scope ? exports.Expressions.__superClass__.compile.call(this, dup(opts)) : this.compile_root(o);
|
410
|
+
};
|
411
|
+
// Compile each expression in the Expressions body.
|
412
|
+
exports.Expressions.prototype.compile_node = function compile_node(options) {
|
413
|
+
var __a, __b, __c, __d, __e, code, compiled, e, line, opts;
|
414
|
+
opts = (typeof options !== "undefined" && options !== null) ? options : {
|
415
|
+
};
|
416
|
+
compiled = [];
|
417
|
+
__a = this.expressions;
|
418
|
+
for (__b = 0; __b < __a.length; __b++) {
|
419
|
+
e = __a[__b];
|
420
|
+
compiled.push(this.compile_expression(e, dup(options)));
|
421
|
+
}
|
422
|
+
code = '';
|
423
|
+
__c = []; __d = compiled;
|
424
|
+
for (__e = 0; __e < __d.length; __e++) {
|
425
|
+
line = __d[__e];
|
426
|
+
__c.push((code = code + line + '\n'));
|
427
|
+
}
|
428
|
+
return __c;
|
429
|
+
};
|
430
|
+
// If this is the top-level Expressions, wrap everything in a safety closure.
|
431
|
+
exports.Expressions.prototype.compile_root = function compile_root(o) {
|
432
|
+
var code, indent, opts;
|
433
|
+
opts = (typeof o !== "undefined" && o !== null) ? o : {
|
434
|
+
};
|
435
|
+
indent = opts.no_wrap ? '' : this.TAB;
|
436
|
+
this.indent = indent;
|
437
|
+
opts.indent = indent;
|
438
|
+
opts.scope = new Scope(null, this, null);
|
439
|
+
code = opts.globals ? compile_node(opts) : compile_with_declarations(opts);
|
440
|
+
code.replace(this.TRAILING_WHITESPACE, '');
|
441
|
+
return this.write(opts.no_wrap ? code : "(function(){\n" + code + "\n})();");
|
442
|
+
};
|
443
|
+
})();
|