1 |
|
2 | (function() {
|
3 | var assert, config, esast, escodegen, esutils, extend, getLit, kit, matchSingleCallBlock, merge, mkAssign, mkBlock, mkExprStmt, mkFlatBlock, mkFun, mkHalt, mkId, mkIf, mkLit, mkReturn, noThisNeeded, packId, str,
|
4 | slice = [].slice;
|
5 |
|
6 | kit = module.exports = {};
|
7 |
|
8 | config = require("./config");
|
9 |
|
10 | escodegen = require("escodegen");
|
11 |
|
12 | assert = require("assert");
|
13 |
|
14 | esutils = require("esutils");
|
15 |
|
16 | esast = esutils.ast;
|
17 |
|
18 | kit.block = mkBlock = function(args) {
|
19 | var body, i, k, len;
|
20 | if (args.length === 1 && args[0].type === "BlockStatement") {
|
21 | return args[0];
|
22 | }
|
23 | body = Array.isArray(args) ? args : [args];
|
24 | for (k = 0, len = body.length; k < len; k++) {
|
25 | i = body[k];
|
26 | assert.ok(i.type != null);
|
27 | }
|
28 | return {
|
29 | type: "BlockStatement",
|
30 | body: body
|
31 | };
|
32 | };
|
33 |
|
34 | kit.flatBlock = mkFlatBlock = function() {
|
35 | var args, body, flatten, i, k, len;
|
36 | args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
|
37 | if (!args.length) {
|
38 | return null;
|
39 | }
|
40 | body = [];
|
41 | flatten = function(cur) {
|
42 | var i, k, len, results;
|
43 | if (Array.isArray(cur)) {
|
44 | results = [];
|
45 | for (k = 0, len = cur.length; k < len; k++) {
|
46 | i = cur[k];
|
47 | results.push(flatten(i));
|
48 | }
|
49 | return results;
|
50 | } else if (cur.type === "BlockStatement") {
|
51 | return flatten(cur.body);
|
52 | } else {
|
53 | return body.push(cur);
|
54 | }
|
55 | };
|
56 | flatten(args);
|
57 | if (!body.length) {
|
58 | return null;
|
59 | }
|
60 | if (body.length === 1) {
|
61 | return body[0];
|
62 | }
|
63 | for (k = 0, len = body.length; k < len; k++) {
|
64 | i = body[k];
|
65 | assert.ok(i.type != null);
|
66 | }
|
67 | return {
|
68 | type: "BlockStatement",
|
69 | body: body
|
70 | };
|
71 | };
|
72 |
|
73 | kit.blockStmts = function(stmt) {
|
74 | if (stmt.type === "BlockStatement") {
|
75 | return stmt.body;
|
76 | }
|
77 | return [stmt];
|
78 | };
|
79 |
|
80 | kit.ret = mkReturn = function(argument) {
|
81 | return {
|
82 | type: "ReturnStatement",
|
83 | argument: argument
|
84 | };
|
85 | };
|
86 |
|
87 | kit.call = function(callee, args) {
|
88 | if (callee.substr != null) {
|
89 | callee = kit.id(callee);
|
90 | }
|
91 | return {
|
92 | type: "CallExpression",
|
93 | callee: callee,
|
94 | "arguments": args
|
95 | };
|
96 | };
|
97 |
|
98 | kit.id = mkId = function(name) {
|
99 | return {
|
100 | type: "Identifier",
|
101 | name: name
|
102 | };
|
103 | };
|
104 |
|
105 | kit.varDecl = function(n, v) {
|
106 | return {
|
107 | type: "VariableDeclaration",
|
108 | kind: "var",
|
109 | declarations: [
|
110 | {
|
111 | type: "VariableDeclarator",
|
112 | id: n,
|
113 | init: v
|
114 | }
|
115 | ]
|
116 | };
|
117 | };
|
118 |
|
119 | kit.packId = packId = function(id) {
|
120 | var p;
|
121 | p = config.packageVar;
|
122 | if (p == null) {
|
123 | return id;
|
124 | }
|
125 | return kit.mem(mkId(p), mkId(id));
|
126 | };
|
127 |
|
128 | kit.spread = function(fun) {
|
129 | return kit.call(kit.packId("spread"), [fun]);
|
130 | };
|
131 |
|
132 | kit.spreadFun = function(args, fun) {
|
133 | if (args.length === 1) {
|
134 | if ((fun.$dm$argNum != null) && fun.$dm$argNum > 1 || (fun.params != null) && fun.params.length > 1) {
|
135 | return kit.spread(fun);
|
136 | }
|
137 | return fun;
|
138 | }
|
139 | if (args.length === 0) {
|
140 | return fun;
|
141 | }
|
142 | return kit.spread(fun);
|
143 | };
|
144 |
|
145 | kit.spreadApp = function(args, fun) {
|
146 | fun = kit.spreadFun(args, fun);
|
147 | if (args.length === 0) {
|
148 | return [kit.pure(), fun];
|
149 | }
|
150 | if (args.length === 1) {
|
151 | return [args[0], fun];
|
152 | }
|
153 | return [kit.arrM(args), fun];
|
154 | };
|
155 |
|
156 | kit.halt = mkHalt = function() {
|
157 | return kit.call(kit.id("halt"), []);
|
158 | };
|
159 |
|
160 | kit.ifte = mkIf = function(test, consequent, alternate) {
|
161 | consequent = mkFlatBlock(consequent);
|
162 | if (alternate != null) {
|
163 | alternate = mkFlatBlock(alternate);
|
164 | if ((alternate != null) && (alternate.body != null) && alternate.body.length === 0) {
|
165 | alternate = null;
|
166 | }
|
167 | }
|
168 | if (consequent == null) {
|
169 | consequent = {
|
170 | type: "BlockStatement",
|
171 | body: []
|
172 | };
|
173 | }
|
174 | return {
|
175 | type: "IfStatement",
|
176 | test: test,
|
177 | consequent: consequent,
|
178 | alternate: alternate
|
179 | };
|
180 | };
|
181 |
|
182 | noThisNeeded = config.noThisNeeded;
|
183 |
|
184 | if (noThisNeeded == null) {
|
185 | noThisNeeded = {};
|
186 | }
|
187 |
|
188 | kit.matchEta = function(p, b) {
|
189 | var a, c, i, j, k, len, s, x;
|
190 | x = matchSingleCallBlock(b.body);
|
191 | if (x == null) {
|
192 | return;
|
193 | }
|
194 | c = x.callee;
|
195 | if (c.type === "MemberExpression") {
|
196 | if (!(c.object.type === "Identifier" && (noThisNeeded[c.object.name] || c.object.name === config.packageVar))) {
|
197 | return;
|
198 | }
|
199 | } else {
|
200 | if (c.type !== "Identifier") {
|
201 | return;
|
202 | }
|
203 | }
|
204 | a = x["arguments"];
|
205 | if (p.length < a.length) {
|
206 | return;
|
207 | }
|
208 | for (s = k = 0, len = a.length; k < len; s = ++k) {
|
209 | j = a[s];
|
210 | i = p[s];
|
211 | if (!(i.type === j.type && j.type === "Identifier")) {
|
212 | return;
|
213 | }
|
214 | if (i.name !== j.name) {
|
215 | return;
|
216 | }
|
217 | }
|
218 | x.callee.$dm$argNum = p.length;
|
219 | return x.callee;
|
220 | };
|
221 |
|
222 | matchSingleCallBlock = function(x) {
|
223 | if (x.length !== 1) {
|
224 | return;
|
225 | }
|
226 | x = x[0];
|
227 | if (x.type !== "ReturnStatement") {
|
228 | return;
|
229 | }
|
230 | x = x.argument;
|
231 | if (x == null) {
|
232 | return;
|
233 | }
|
234 | if (x.type !== "CallExpression") {
|
235 | return;
|
236 | }
|
237 | return x;
|
238 | };
|
239 |
|
240 | kit.fun = mkFun = function(params, stmt) {
|
241 | var eta;
|
242 | stmt = mkBlock(stmt);
|
243 | eta = kit.matchEta(params, stmt);
|
244 | if (eta != null) {
|
245 | return eta;
|
246 | }
|
247 | return {
|
248 | type: "FunctionExpression",
|
249 | params: params,
|
250 | body: stmt
|
251 | };
|
252 | };
|
253 |
|
254 | kit.lit = mkLit = function(v) {
|
255 | return {
|
256 | type: "Literal",
|
257 | value: v
|
258 | };
|
259 | };
|
260 |
|
261 | kit.coerce = function(v) {
|
262 | return kit.call(packId("coerce"), [mkFun([], v)]);
|
263 | };
|
264 |
|
265 | kit.mem = function() {
|
266 | var i, k, len, p, ref, res;
|
267 | p = 1 <= arguments.length ? slice.call(arguments, 0) : [];
|
268 | res = p[0];
|
269 | assert.ok(res.type != null);
|
270 | ref = p.slice(1);
|
271 | for (k = 0, len = ref.length; k < len; k++) {
|
272 | i = ref[k];
|
273 | assert.ok(i.type != null);
|
274 | res = {
|
275 | type: "MemberExpression",
|
276 | object: res,
|
277 | property: i
|
278 | };
|
279 | }
|
280 | return res;
|
281 | };
|
282 |
|
283 | kit.not = function(argument) {
|
284 | return {
|
285 | type: "UnaryExpression",
|
286 | prefix: true,
|
287 | operator: "!",
|
288 | argument: argument
|
289 | };
|
290 | };
|
291 |
|
292 | kit.eq = function(left, right) {
|
293 | return {
|
294 | type: "BinaryExpression",
|
295 | operator: "===",
|
296 | left: left,
|
297 | right: right
|
298 | };
|
299 | };
|
300 |
|
301 | kit.arrM = function(args) {
|
302 | return kit.call(kit.packId("arr"), [kit.arr(args)]);
|
303 | };
|
304 |
|
305 | kit.mbind = function(from, fun) {
|
306 | var ref;
|
307 | assert.ok(Array.isArray(from));
|
308 | ref = kit.spreadApp(from, fun), from = ref[0], fun = ref[1];
|
309 | assert.ok(fun != null);
|
310 | return kit.call(kit.mem(from, mkId("mbind")), [fun]);
|
311 | };
|
312 |
|
313 | kit["catch"] = function(from, arg, to) {
|
314 | var args;
|
315 | args = [];
|
316 | if (arg != null) {
|
317 | args.push(arg);
|
318 | }
|
319 | return kit.call(kit.mem(from, mkId("mhandle")), [mkFun(args, to)]);
|
320 | };
|
321 |
|
322 | kit["finally"] = function(from, to) {
|
323 | return kit.call(kit.mem(from, mkId("mfinally")), [mkFun([], to)]);
|
324 | };
|
325 |
|
326 | kit.mapply = function(from, fun) {
|
327 | var ref;
|
328 | ref = kit.spreadApp(from, fun), from = ref[0], fun = ref[1];
|
329 | return kit.call(kit.mem(from, mkId("mapply")), [fun]);
|
330 | };
|
331 |
|
332 | kit.pure = function() {
|
333 | var args, v;
|
334 | v = 1 <= arguments.length ? slice.call(arguments, 0) : [];
|
335 | args = v;
|
336 | if (v.length === 1 && (v[0] == null)) {
|
337 | args = [];
|
338 | }
|
339 | return kit.call(packId("pure"), args);
|
340 | };
|
341 |
|
342 | kit.exprStmt = mkExprStmt = function(expression) {
|
343 | assert.ok(expression != null);
|
344 | return {
|
345 | type: "ExpressionStatement",
|
346 | expression: expression
|
347 | };
|
348 | };
|
349 |
|
350 | kit.assign = mkAssign = function(left, right) {
|
351 | return {
|
352 | type: "AssignmentExpression",
|
353 | operator: "=",
|
354 | left: left,
|
355 | right: right
|
356 | };
|
357 | };
|
358 |
|
359 | kit.arr = function(els) {
|
360 | return {
|
361 | type: "ArrayExpression",
|
362 | elements: els
|
363 | };
|
364 | };
|
365 |
|
366 | kit.extend = extend = function() {
|
367 | var i, j, k, len, n, other, par, pv;
|
368 | par = arguments[0], other = 2 <= arguments.length ? slice.call(arguments, 1) : [];
|
369 | for (k = 0, len = other.length; k < len; k++) {
|
370 | i = other[k];
|
371 | if (i != null) {
|
372 | for (j in i) {
|
373 | n = i[j];
|
374 | pv = par[j];
|
375 | par[j] = n;
|
376 | }
|
377 | }
|
378 | }
|
379 | return par;
|
380 | };
|
381 |
|
382 | kit.merge = merge = function() {
|
383 | var i, j, k, len, n, other, par, ref;
|
384 | par = arguments[0], other = 2 <= arguments.length ? slice.call(arguments, 1) : [];
|
385 | for (k = 0, len = other.length; k < len; k++) {
|
386 | i = other[k];
|
387 | if (i != null) {
|
388 | for (j in i) {
|
389 | n = i[j];
|
390 | if (Array.isArray(n)) {
|
391 | (ref = (par[j] != null ? par[j] : par[j] = [])).push.apply(ref, n);
|
392 | } else if (Object(n) === n && !(n instanceof Function)) {
|
393 | merge(par[j] != null ? par[j] : par[j] = {}, n);
|
394 | } else {
|
395 | par[j] = n;
|
396 | }
|
397 | }
|
398 | }
|
399 | }
|
400 | return par;
|
401 | };
|
402 |
|
403 | kit.exprError = function(n, e) {
|
404 | var l, res;
|
405 | if ((e.loc != null) && (e.loc.start != null)) {
|
406 | l = e.loc.start.line;
|
407 | }
|
408 | if (l != null) {
|
409 | n = "Line " + l + ": " + n;
|
410 | }
|
411 | res = new Error(n, config.filename, l);
|
412 | res.loc = e.loc;
|
413 | res.lineNumber = l;
|
414 | return res;
|
415 | };
|
416 |
|
417 | kit.errorPos = function(e, f) {
|
418 | var error, ex, l;
|
419 | try {
|
420 | return f();
|
421 | } catch (error) {
|
422 | ex = error;
|
423 | if ((e.loc != null) && (e.loc.start != null)) {
|
424 | l = e.loc.start.line;
|
425 | }
|
426 | ex.loc = e.loc;
|
427 | ex.lineNumber = l;
|
428 | ex.message = "Line " + l + ": " + ex.message;
|
429 | throw ex;
|
430 | }
|
431 | };
|
432 |
|
433 | kit.seqExpr = function() {
|
434 | var expressions;
|
435 | expressions = 1 <= arguments.length ? slice.call(arguments, 0) : [];
|
436 | if (expressions.length === 1) {
|
437 | return expressions[0];
|
438 | }
|
439 | return {
|
440 | type: "SequenceExpression",
|
441 | expressions: expressions
|
442 | };
|
443 | };
|
444 |
|
445 | kit.seq = function() {
|
446 | var exprs;
|
447 | exprs = 1 <= arguments.length ? slice.call(arguments, 0) : [];
|
448 | if (exprs.length === 1) {
|
449 | return exprs[0];
|
450 | }
|
451 | return kit.call(packId("seq"), exprs);
|
452 | };
|
453 |
|
454 | kit.getMembersPath = function(e) {
|
455 | var res, walk;
|
456 | res = [];
|
457 | walk = function(e) {
|
458 | if (e.type !== "MemberExpression") {
|
459 | res.unshift(e);
|
460 | return;
|
461 | }
|
462 | res.unshift(e.property);
|
463 | return walk(e.object);
|
464 | };
|
465 | walk(e);
|
466 | return res;
|
467 | };
|
468 |
|
469 | kit.getMembersPathIds = function(e) {
|
470 | return kit.getMembersPath(e).map(kit.getId);
|
471 | };
|
472 |
|
473 | kit.getId = function(e) {
|
474 | if ((e != null) && e.type === "Identifier") {
|
475 | return e.name;
|
476 | }
|
477 | return null;
|
478 | };
|
479 |
|
480 | kit.coerceThunk = function(block) {
|
481 | return kit.call(packId("coerce"), [mkFun([], block)]);
|
482 | };
|
483 |
|
484 | kit.coerceVal = function(expr) {
|
485 | return kit.call(mkId(config.packageVar), [expr]);
|
486 | };
|
487 |
|
488 | getLit = function(e) {
|
489 | if (e.type !== "Literal") {
|
490 | return null;
|
491 | }
|
492 | return e.value;
|
493 | };
|
494 |
|
495 | kit.toStr = str = function(e) {
|
496 | var r;
|
497 | r = getLit(e);
|
498 | if (!((r != null) && (r.substr != null))) {
|
499 | throw kit.exprError("expected string", e);
|
500 | }
|
501 | return r;
|
502 | };
|
503 |
|
504 | kit.exprToStr = function(e) {
|
505 | if (e.type === "Literal") {
|
506 | return e.value;
|
507 | }
|
508 | throw new Error("cannot convert: " + escodegen.generate(e) + " to string");
|
509 | };
|
510 |
|
511 | kit.shortNodeDescr = function(s) {
|
512 | var end, loc, res, start;
|
513 | if (s == null) {
|
514 | return "<NULL>";
|
515 | }
|
516 | res = "";
|
517 | res += s.type;
|
518 | loc = s.loc;
|
519 | if (loc != null) {
|
520 | start = loc.start, end = loc.end;
|
521 | if (start != null) {
|
522 | res += "@" + start.line + ":" + start.column;
|
523 | }
|
524 | if (end != null) {
|
525 | res += "-" + end.line + ":" + end.column;
|
526 | }
|
527 | }
|
528 | return res;
|
529 | };
|
530 |
|
531 | }).call(this);
|