UNPKG

2.42 kBJavaScriptView Raw
1var assert = require('assert');
2var syntax = require('./syntax');
3var traverse = require('./traverse');
4
5var continuationIdentifier = exports.continuationIdentifier = '_$cont';
6exports.errName = '_$err';
7exports.contName = 'cont';
8exports.obtainName = 'obtain';
9
10exports.__defineGetter__('continuationStatement', function () {
11 return new syntax.ExpressionStatement(new syntax.CallExpression(new syntax.Identifier(continuationIdentifier)));
12});
13
14exports.extractVariableDeclarations = function (block) {
15 var decMap = {};
16
17 traverse(block, {currentScope: true}, function (node) {
18 if (node.type === 'VariableDeclaration') {
19 var assignments = [];
20 node.declarations.forEach(function (dec) {
21 decMap[dec.id.name] = dec;
22 if (dec.init !== null) {
23 //Replace variable declaration with assignment
24 assignments.push(new syntax.ExpressionStatement(new syntax.AssignmentExpression('=', dec.id, dec.init)));
25 dec.init = null;
26 } else if (node.forIn) {
27 assignments = dec.id;
28 }
29 });
30 node = assignments;
31 }
32 return node;
33 });
34
35 var declarations = [];
36 Object.keys(decMap).forEach(function (name) {
37 var dec = decMap[name];
38 dec.init = null;
39 declarations.push(dec);
40 });
41
42 return new syntax.VariableDeclaration(declarations, 'var');
43};
44
45function findContinuation(args) {
46 //Todo check multiple continuations && defer
47 for (var i = 0; i < args.length; i++) {
48 var arg = args[i];
49 if (arg.type === 'CallExpression' && arg.callee.name === 'continuation') {
50 return i;
51 }
52 }
53 return -1;
54}
55
56exports.makeCPS = function (innerPlace, nextPlace) {
57 return new syntax.ExpressionStatement(new syntax.CallExpression(
58 new syntax.FunctionExpression(
59 null,
60 [new syntax.Identifier(continuationIdentifier)],
61 new syntax.BlockStatement(innerPlace)
62 ),
63 [new syntax.FunctionExpression(
64 null,
65 [],
66 new syntax.BlockStatement(nextPlace)
67 )]
68 ));
69};
70
71var loopCount = 0;
72exports.getLoopFunctionName = function () {
73 var name = '_$loop_' + loopCount;
74 loopCount ++;
75 return name;
76};
77
78exports.reset = function () {
79 loopCount = 0;
80};
81
82exports.isContinuationStatement = function (statement) {
83 return statement.type === 'ExpressionStatement' &&
84 statement.expression.type === 'CallExpression' &&
85 statement.expression.callee.name === continuationIdentifier;
86};