UNPKG

12.4 kBJavaScriptView Raw
1// Generated by CoffeeScript 1.10.0
2(function() {
3 var ActiveScope, ActiveVisitor, DisabledVisitor, Scope, Visitor, assert, commonForIter, commonWhile, isLoop, kit, policy, ref, ref1, rewriteForIter, wrapP;
4
5 kit = require("./kit");
6
7 ref = require("./scope"), Scope = ref.Scope, ActiveScope = ref.ActiveScope;
8
9 policy = require("./policy");
10
11 require("./graph");
12
13 require("./expr");
14
15 assert = require("assert");
16
17 ref1 = require("./visitor"), Visitor = ref1.Visitor, ActiveVisitor = ref1.ActiveVisitor, DisabledVisitor = ref1.DisabledVisitor;
18
19 isLoop = function(stmt) {
20 return stmt.type === "ForStatement";
21 };
22
23 ActiveVisitor.prototype.LabeledStatement = function(stmt) {
24 var block, name, nlab, old, res;
25 name = stmt.label.name;
26 if (isLoop(stmt.body)) {
27 res = this.ctx.stmt(stmt.body, name);
28 res.orig = stmt;
29 return res;
30 }
31 old = this.ctx.lab;
32 block = this.ctx.controlNode();
33 this.ctx.lab = nlab = Object.create(old);
34 block.labname = name;
35 nlab[name] = {
36 brk: block
37 };
38 block.setLabel("" + name).setBody(this.ctx.stmt(stmt.body, name));
39 this.ctx.lab = old;
40 return block;
41 };
42
43 ActiveVisitor.prototype.ContinueStatement = function(stmt) {
44 var l, name;
45 name = stmt.label != null ? stmt.label.name : "#";
46 l = this.ctx.lab[name];
47 if (!((l != null) && (l.cnt != null))) {
48 throw new Error("no such label " + name);
49 }
50 return l.cnt.breakNode();
51 };
52
53 ActiveVisitor.prototype.BreakStatement = function(stmt) {
54 var l, name;
55 name = stmt.label != null ? stmt.label.name : "#";
56 l = this.ctx.lab[name];
57 if (!((l != null) && (l.brk != null))) {
58 throw new Error("no such label " + name);
59 }
60 return l.brk.breakNode();
61 };
62
63 ActiveVisitor.prototype.BlockStatement = function(stmt) {
64 return this.ctx.stmts(stmt.body);
65 };
66
67 ActiveVisitor.prototype.EmptyStatement = function(stmt) {
68 return this.ctx.pureNode([stmt]);
69 };
70
71 Visitor.prototype.ExpressionStatement = function(stmt) {
72 return this.ctx.expr(stmt.expression).ignoreResult().setOrig(false);
73 };
74
75 ActiveVisitor.prototype.IfStatement = function(stmt) {
76 var e, i, res, t;
77 i = stmt.test, t = stmt.consequent, e = stmt.alternate;
78 res = this.ctx.branchedNode(function(t, e) {
79 stmt.consequent = t;
80 stmt.alternate = e;
81 return stmt;
82 }, stmt).setOrig(stmt).setDeps(this.ctx.stmt(t), e != null ? this.ctx.stmt(e) : this.ctx.emptyNode());
83 return this.ctx.bindNode(res, [this.ctx.expr(i).setPosition([stmt, "test"])]);
84 };
85
86 ActiveVisitor.prototype.SwitchStatement = function(stmt) {
87 var block, i, j, len, nlab, old, ref2, res, s, x;
88 old = this.ctx.lab;
89 this.ctx.lab = nlab = Object.create(old);
90 res = this.ctx.controlNode();
91 nlab["#"] = {
92 brk: res
93 };
94 block = this.ctx.blockNode();
95 s = this.ctx.sharedNode(this.ctx.expr(stmt.discriminant), block);
96 res.setBody(s);
97 ref2 = stmt.cases;
98 for (x = j = 0, len = ref2.length; j < len; x = ++j) {
99 i = ref2[x];
100 if (i.test != null) {
101 block.append(this.IfStatement(kit.ifte(kit.eq(s._ref, i.test), i.consequent)));
102 } else {
103 block.append(this.ctx.stmts(i.consequent));
104 }
105 }
106 return res;
107 };
108
109 ActiveVisitor.prototype.ReturnStatement = function(s) {
110 var a;
111 a = s.argument;
112 if (a == null) {
113 return this.ctx.root.breakNode();
114 }
115 return this.ctx.root.breakNode(this.ctx.expr(a));
116 };
117
118 Visitor.prototype.postDecl = function(stmt) {
119 return this.ctx.pureNode([stmt]);
120 };
121
122 ActiveVisitor.prototype.postDecl = function(stmt) {
123 this.ctx.glob.decls.push(stmt);
124 return this.ctx.emptyNode();
125 };
126
127 Visitor.prototype.FunctionDeclaration = function(stmt) {
128 var ctx, i, j, len, ref2, ref3, v;
129 ctx = this.ctx.subScope(stmt);
130 if (stmt.params != null) {
131 ref2 = stmt.params;
132 for (j = 0, len = ref2.length; j < len; j++) {
133 i = ref2[j];
134 if (i.name) {
135 ctx.vars[i.name] = true;
136 }
137 }
138 }
139 if (ctx == null) {
140 return this.ctx.pureNode([stmt]);
141 }
142 ctx.policy = this.policy;
143 stmt.body = ctx.prog(stmt.body);
144 if (stmt.generator) {
145 stmt.generator = false;
146 }
147 ref3 = ctx.upds;
148 for (i in ref3) {
149 v = ref3[i];
150 if (v && !ctx.vars[i]) {
151 this.ctx.refs[i] = true;
152 }
153 }
154 return this.postDecl(stmt);
155 };
156
157 Visitor.prototype.VariableDeclaration = function(stmt) {
158 var en, i, j, len, ref2;
159 ref2 = stmt.declarations;
160 for (j = 0, len = ref2.length; j < len; j++) {
161 i = ref2[j];
162 if (!i.init) {
163 continue;
164 }
165 this.policy.nameDetails(i.id, "=");
166 en = this.ctx.expr(i.init);
167 assert.ok(en.pureExpr != null);
168 i.init = en.pureExpr;
169 }
170 return this.ctx.pureNode([stmt]);
171 };
172
173 ActiveVisitor.prototype.VariableDeclaration = function(stmt) {
174 var asgn, cur, declarations, e, i, j, len, orig, ref2;
175 cur = this.ctx.emptyNode();
176 declarations = [];
177 orig = [];
178 ref2 = stmt.declarations;
179 for (j = 0, len = ref2.length; j < len; j++) {
180 i = ref2[j];
181 this.ctx.vars[i.id.name] = true;
182 if (!i.id.$dm$orig) {
183 this.ctx.ids[i.id.name] = true;
184 }
185 declarations.push({
186 type: "VariableDeclarator",
187 id: i.id
188 });
189 if (this.policy.opts.varCapt === false) {
190 this.ctx.refs[i.id.name] = true;
191 }
192 if (i.init != null) {
193 asgn = kit.assign(i.id, i.init);
194 e = this.ctx.stmt(kit.exprStmt(asgn));
195 cur = cur.append(e);
196 orig.push(asgn);
197 }
198 }
199 this.ctx.glob.decls.push({
200 type: "VariableDeclaration",
201 declarations: declarations,
202 kind: "var"
203 });
204 if (cur.pureBlock != null) {
205 cur.setOrig(kit.block(cur.pureBlock()));
206 } else {
207 cur.setOrig(kit.exprStmt(kit.seqExpr.apply(kit, orig)));
208 }
209 return cur;
210 };
211
212 ActiveVisitor.prototype.ForStatement = function(stmt, label) {
213 var body, exprs, i, init, j, len, lexpr, ref2, test, update, wbody;
214 wbody = [];
215 init = stmt.init, test = stmt.test, update = stmt.update, body = stmt.body;
216 if (test == null) {
217 test = kit.lit(true);
218 }
219 if (init != null) {
220 if (init.type === "VariableDeclaration") {
221 wbody.push(init);
222 exprs = [];
223 ref2 = init.declarations;
224 for (j = 0, len = ref2.length; j < len; j++) {
225 i = ref2[j];
226 if (i.init) {
227 exprs.push(kit.assign(i.id, i.init));
228 }
229 }
230 stmt.init = kit.seqExpr.apply(kit, exprs);
231 } else {
232 wbody.push(kit.exprStmt(init));
233 }
234 }
235 lexpr = {
236 type: "WhileStatement",
237 test: test,
238 body: body,
239 $dm$update: update
240 };
241 if (label != null) {
242 lexpr = {
243 type: "LabeledStatement",
244 body: lexpr,
245 label: kit.id(label)
246 };
247 }
248 wbody.push(lexpr);
249 return this.ctx.stmts(wbody);
250 };
251
252 wrapP = function(nowrap, v) {
253 if (nowrap) {
254 return v;
255 } else {
256 return kit.call(kit.packId("p"), [v]);
257 }
258 };
259
260 rewriteForIter = function(itername, stmt, label, nowrap) {
261 var body, init, iterCtr, iterDecl, iterName, left, pat, resDecls, right, update;
262 left = stmt.left, right = stmt.right, body = stmt.body;
263 iterName = this.ctx.uniqId("iter");
264 iterCtr = kit.call(kit.packId(itername), [right]);
265 init = wrapP(nowrap, iterCtr);
266 iterDecl = {
267 type: "VariableDeclarator",
268 id: iterName,
269 init: init
270 };
271 resDecls = [iterDecl];
272 init = {
273 type: "VariableDeclaration",
274 kind: "var",
275 declarations: resDecls
276 };
277 if (left.type === "VariableDeclaration") {
278 if (left.declarations.length !== 1) {
279 throw new Error("NOT IMPLEMENTED");
280 }
281 stmt.left = pat = left.declarations[0].id;
282 this.ctx.glob.decls.push(left);
283 } else {
284 pat = left;
285 }
286 body = kit.flatBlock(kit.exprStmt(kit.assign(pat, kit.mem(iterName, kit.id("value")))), body);
287 update = kit.assign(iterName, wrapP(nowrap, kit.call(iterName, [])));
288 return [
289 {
290 type: "ForStatement",
291 init: init,
292 test: iterName,
293 update: update,
294 body: body
295 }, iterCtr
296 ];
297 };
298
299 commonForIter = function(itername, stmt, label) {
300 var b, bn, iterCtr, ref2;
301 ref2 = rewriteForIter.call(this, itername, stmt, label), b = ref2[0], iterCtr = ref2[1];
302 bn = this.ForStatement(b, label);
303 return this.ctx.bindNode(bn, [this.ctx.expr(stmt.right).setPosition([iterCtr["arguments"], 0])]);
304 };
305
306 ActiveVisitor.prototype.ForInStatement = function(stmt, label) {
307 return commonForIter.call(this, "forInIterator", stmt, label);
308 };
309
310 ActiveVisitor.prototype.ForOfStatement = function(stmt, label) {
311 var b, name, orig;
312 name = this.policy.opts.varCapt === false ? "iterator" : "iteratorBuf";
313 b = commonForIter.call(this, name, stmt, label);
314 if (!this.policy.opts.keepForOf) {
315 orig = rewriteForIter.call(this, "iterator", stmt, label, true)[0];
316 b.setOrig(orig);
317 }
318 return b;
319 };
320
321 commonWhile = function(pre) {
322 return function(stmt, label) {
323 var bexpr, body, bodyNode, bodyv, brkControl, cntControl, inner, labDef, loopBranch, nlab, old, test, testNode, upd, update;
324 test = stmt.test, body = stmt.body;
325 bexpr = kit.ifte(test, [], []);
326 loopBranch = this.ctx.branchedNode(function(c, a) {
327 bexpr.consequent = kit.flatBlock(c);
328 if (a != null) {
329 bexpr.alternate = kit.flatBlock(a);
330 }
331 return bexpr;
332 }, bexpr);
333 update = stmt.$dm$update;
334 if (update != null) {
335 upd = this.ctx.expr(update).ignoreResult();
336 }
337 brkControl = this.ctx.loopNode();
338 cntControl = this.ctx.controlNode();
339 if (label != null) {
340 brkControl.setLabel(label + "Brk");
341 cntControl.setLabel(label + "Cont");
342 } else {
343 brkControl.setLabel("brk");
344 cntControl.setLabel("cont");
345 }
346 old = this.ctx.lab;
347 this.ctx.lab = nlab = Object.create(old);
348 labDef = {
349 brk: brkControl,
350 cnt: cntControl
351 };
352 nlab["#"] = labDef;
353 if (label != null) {
354 nlab[label] = labDef;
355 }
356 bodyNode = this.ctx.stmtNode(body);
357 bodyv = pre ? (testNode = this.ctx.expr(test).setPosition([bexpr, "test"]), this.ctx.bindNode(loopBranch.setDeps(bodyNode, brkControl.breakNode()), [testNode])) : (bexpr.test = test = kit.not(test), testNode = this.ctx.expr(test).setPosition([bexpr, "test"]), this.ctx.blockNode().append(bodyNode, this.ctx.bindNode(loopBranch.setDeps(brkControl.breakNode(), this.ctx.emptyNode()), [testNode])));
358 this.ctx.lab = old;
359 if (label != null) {
360 if (bodyv.name == null) {
361 bodyv.name = this.ctx.uniqId("{label}Loop");
362 }
363 }
364 inner = cntControl.setBody(bodyv);
365 if (upd != null) {
366 inner = inner.append(upd);
367 }
368 brkControl.test = testNode;
369 brkControl.inner = bodyNode;
370 brkControl.update = upd != null ? upd : this.ctx.emptyNode();
371 brkControl.pre = pre;
372 brkControl.cont = cntControl;
373 return brkControl.setBody(this.ctx.repeatNode(inner));
374 };
375 };
376
377 ActiveVisitor.prototype.WhileStatement = commonWhile(true);
378
379 ActiveVisitor.prototype.DoWhileStatement = commonWhile();
380
381 ActiveVisitor.prototype.ThrowStatement = function(stmt) {
382 var e, ea;
383 e = stmt.argument;
384 ea = this.ctx.expr(e);
385 return this.ctx.throwNode(ea);
386 };
387
388 ActiveVisitor.prototype.TryStatement = function(stmt) {
389 var block, finalizer, handler, res;
390 block = stmt.block, handler = stmt.handler, finalizer = stmt.finalizer;
391 res = this.ctx.tryCatchNode().setBody(this.ctx.stmt(block));
392 if (finalizer != null) {
393 res.setFin(this.ctx.stmt(finalizer));
394 }
395 if (handler != null) {
396 res.setHandler(handler.param, this.ctx.stmt(handler.body));
397 }
398 return res;
399 };
400
401 ActiveVisitor.prototype.WithStatement = function(stmt) {
402 var res;
403 res = this.ctx.branchedNode(function(b) {
404 stmt.body = b;
405 return stmt;
406 }, stmt).setOrig(stmt).setDeps(this.ctx.stmt(stmt.body));
407 return this.ctx.bindNode(res, [this.ctx.expr(stmt.object).setPosition([stmt, "object"])]);
408 };
409
410 Visitor.prototype.defaultStmt = function(stmt) {
411 return this.ctx.pureNode([stmt]);
412 };
413
414}).call(this);