1 |
|
2 | (function() {
|
3 | var Scope, config, defaultVisitor, kit;
|
4 |
|
5 | config = require("./config");
|
6 |
|
7 | kit = require("./kit");
|
8 |
|
9 | defaultVisitor = require("./visitor").defaultVisitor;
|
10 |
|
11 | Scope = (function() {
|
12 | function Scope(par, visitor) {
|
13 | var ref;
|
14 | this.glob = {
|
15 | decls: []
|
16 | };
|
17 | this.vars = {};
|
18 | this.refs = {};
|
19 | this.upds = {};
|
20 | this.par = par;
|
21 | this.policy = this.par ? par.policy : this.createPolicy();
|
22 | this.visitor = visitor != null ? visitor : defaultVisitor();
|
23 | this.visitor.setCtx(this);
|
24 | this.nxt = [];
|
25 | this.lab = {};
|
26 | this.uniqIds = {};
|
27 | this.opts = {};
|
28 | this.anc = [];
|
29 | if (this.par) {
|
30 | (ref = this.anc).push.apply(ref, this.par.anc);
|
31 | }
|
32 | this.scopes = [];
|
33 | this.ids = {};
|
34 | this.uids = [];
|
35 | }
|
36 |
|
37 | Scope.prototype.updateVisitor = function() {
|
38 | this.visitor = this.visitor.update(this);
|
39 | return this;
|
40 | };
|
41 |
|
42 | Scope.prototype.subScope = function() {
|
43 | var subvisitor;
|
44 | subvisitor = this.visitor.subScope();
|
45 | if (subvisitor == null) {
|
46 | return;
|
47 | }
|
48 | return new Scope(this, subvisitor);
|
49 | };
|
50 |
|
51 | Scope.prototype.uniqId = function(p) {
|
52 | var c, ref, res;
|
53 | c = (ref = this.uniqIds[p]) != null ? ref : 0;
|
54 | this.uniqIds[p] = c + 1;
|
55 | if (!c) {
|
56 | c = "";
|
57 | }
|
58 | res = kit.id("" + p + c);
|
59 | res.$dm$orig = p;
|
60 | this.uids.push(res);
|
61 | return res;
|
62 | };
|
63 |
|
64 | Scope.prototype.commitIds = function() {
|
65 | var c, i, j, len, ref;
|
66 | ref = this.uids;
|
67 | for (j = 0, len = ref.length; j < len; j++) {
|
68 | i = ref[j];
|
69 | if (this.ids[i.name]) {
|
70 | while (true) {
|
71 | c = this.uniqIds[i.$dm$orig]++;
|
72 | i.name = "" + i.$dm$orig + c;
|
73 | if (!this.ids[i.name]) {
|
74 | break;
|
75 | }
|
76 | }
|
77 | }
|
78 | }
|
79 | };
|
80 |
|
81 | Scope.prototype.stmt = function(s, lab) {
|
82 | var r;
|
83 | r = this.visitor[s.type];
|
84 | if (r == null) {
|
85 | return this.visitor.defaultStmt(s).setOrig(s);
|
86 | }
|
87 | return this.policy.item(s, (function(_this) {
|
88 | return function() {
|
89 | return r.call(_this.visitor, s, lab).setOrig(s);
|
90 | };
|
91 | })(this));
|
92 | };
|
93 |
|
94 | Scope.prototype.expr = function(e) {
|
95 | var h;
|
96 | h = this.visitor[e.type];
|
97 | if (h == null) {
|
98 | return this.pureExprNode(e);
|
99 | }
|
100 | return this.policy.item(e, (function(_this) {
|
101 | return function() {
|
102 | return h.call(_this.visitor, e);
|
103 | };
|
104 | })(this));
|
105 | };
|
106 |
|
107 | Scope.prototype.stmts = function(body) {
|
108 | var b, i, o, s, x;
|
109 | b = this.blockNode();
|
110 | x = 0;
|
111 | while (true) {
|
112 | if (x >= body.length) {
|
113 | break;
|
114 | }
|
115 | i = body[x];
|
116 | s = this.stmt(i);
|
117 | o = s.orig;
|
118 | if (o && o.type === "EmptyStatement") {
|
119 | body.splice(x, 1);
|
120 | } else {
|
121 | if (o) {
|
122 | body[x] = o;
|
123 | }
|
124 | b = b.append(s);
|
125 | ++x;
|
126 | }
|
127 | }
|
128 | return b;
|
129 | };
|
130 |
|
131 | Scope.prototype.prog = function(p) {
|
132 | return this.policy.scope((function(_this) {
|
133 | return function() {
|
134 | return _this._prog(p);
|
135 | };
|
136 | })(this));
|
137 | };
|
138 |
|
139 | Scope.prototype._prog = function(p) {
|
140 | var body, controlNode, node, prog, res;
|
141 | this.root = controlNode = this.controlNode("scope");
|
142 | this.root.label = this.uniqId("root");
|
143 | prog = this.node = this.stmts(p.body);
|
144 | if (this.visitor.noChanges) {
|
145 | return p;
|
146 | }
|
147 | node = this.tryCatchNode().setBody(controlNode);
|
148 | controlNode.setBody(prog);
|
149 | node.fwdPass({});
|
150 | if (this.policy.opts.compile === "always") {
|
151 | controlNode.propagateEff();
|
152 | }
|
153 | node.backPass({});
|
154 | this.calcDone = true;
|
155 | this.node = node;
|
156 | res = [];
|
157 | if (this.thisVar != null) {
|
158 | res.push({
|
159 | type: "VariableDeclaration",
|
160 | kind: "var",
|
161 | declarations: [
|
162 | {
|
163 | type: "VariableDeclarator",
|
164 | id: this.thisVar,
|
165 | init: {
|
166 | type: "ThisExpression"
|
167 | }
|
168 | }
|
169 | ]
|
170 | });
|
171 | }
|
172 | res.push.apply(res, this.glob.decls);
|
173 | body = node.getFullBlock(node.eff);
|
174 | res.push.apply(res, body);
|
175 | this.eff = node.eff;
|
176 | this.commitIds();
|
177 | return kit.block(res);
|
178 | };
|
179 |
|
180 | return Scope;
|
181 |
|
182 | })();
|
183 |
|
184 | module.exports = {
|
185 | Scope: Scope
|
186 | };
|
187 |
|
188 | }).call(this);
|