1 /*
2 Copyright 2015 Google Inc. All rights reserved.
3 
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7 
8     http://www.apache.org/licenses/LICENSE-2.0
9 
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 */
16 
17 #include "pass.h"
18 
fodder(Fodder & fodder)19 void CompilerPass::fodder(Fodder &fodder)
20 {
21     for (auto &f : fodder)
22         fodderElement(f);
23 }
24 
specs(std::vector<ComprehensionSpec> & specs)25 void CompilerPass::specs(std::vector<ComprehensionSpec> &specs)
26 {
27     for (auto &spec : specs) {
28         fodder(spec.openFodder);
29         switch (spec.kind) {
30             case ComprehensionSpec::FOR:
31                 fodder(spec.varFodder);
32                 fodder(spec.inFodder);
33                 expr(spec.expr);
34                 break;
35             case ComprehensionSpec::IF: expr(spec.expr); break;
36         }
37     }
38 }
39 
params(Fodder & fodder_l,ArgParams & params,Fodder & fodder_r)40 void CompilerPass::params(Fodder &fodder_l, ArgParams &params, Fodder &fodder_r)
41 {
42     fodder(fodder_l);
43     for (auto &param : params) {
44         fodder(param.idFodder);
45         if (param.expr) {
46             fodder(param.eqFodder);
47             expr(param.expr);
48         }
49         fodder(param.commaFodder);
50     }
51     fodder(fodder_r);
52 }
53 
fieldParams(ObjectField & field)54 void CompilerPass::fieldParams(ObjectField &field)
55 {
56     if (field.methodSugar) {
57         params(field.fodderL, field.params, field.fodderR);
58     }
59 }
60 
fields(ObjectFields & fields)61 void CompilerPass::fields(ObjectFields &fields)
62 {
63     for (auto &field : fields) {
64         switch (field.kind) {
65             case ObjectField::LOCAL: {
66                 fodder(field.fodder1);
67                 fodder(field.fodder2);
68                 fieldParams(field);
69                 fodder(field.opFodder);
70                 expr(field.expr2);
71             } break;
72 
73             case ObjectField::FIELD_ID:
74             case ObjectField::FIELD_STR:
75             case ObjectField::FIELD_EXPR: {
76                 if (field.kind == ObjectField::FIELD_ID) {
77                     fodder(field.fodder1);
78 
79                 } else if (field.kind == ObjectField::FIELD_STR) {
80                     expr(field.expr1);
81 
82                 } else if (field.kind == ObjectField::FIELD_EXPR) {
83                     fodder(field.fodder1);
84                     expr(field.expr1);
85                     fodder(field.fodder2);
86                 }
87                 fieldParams(field);
88                 fodder(field.opFodder);
89                 expr(field.expr2);
90 
91             } break;
92 
93             case ObjectField::ASSERT: {
94                 fodder(field.fodder1);
95                 expr(field.expr2);
96                 if (field.expr3 != nullptr) {
97                     fodder(field.opFodder);
98                     expr(field.expr3);
99                 }
100             } break;
101         }
102 
103         fodder(field.commaFodder);
104     }
105 }
106 
expr(AST * & ast_)107 void CompilerPass::expr(AST *&ast_)
108 {
109     fodder(ast_->openFodder);
110     visitExpr(ast_);
111 }
112 
visit(Apply * ast)113 void CompilerPass::visit(Apply *ast)
114 {
115     expr(ast->target);
116     params(ast->fodderL, ast->args, ast->fodderR);
117     if (ast->tailstrict) {
118         fodder(ast->tailstrictFodder);
119     }
120 }
121 
visit(ApplyBrace * ast)122 void CompilerPass::visit(ApplyBrace *ast)
123 {
124     expr(ast->left);
125     expr(ast->right);
126 }
127 
visit(Array * ast)128 void CompilerPass::visit(Array *ast)
129 {
130     for (auto &element : ast->elements) {
131         expr(element.expr);
132         fodder(element.commaFodder);
133     }
134     fodder(ast->closeFodder);
135 }
136 
visit(ArrayComprehension * ast)137 void CompilerPass::visit(ArrayComprehension *ast)
138 {
139     expr(ast->body);
140     fodder(ast->commaFodder);
141     specs(ast->specs);
142     fodder(ast->closeFodder);
143 }
144 
visit(Assert * ast)145 void CompilerPass::visit(Assert *ast)
146 {
147     expr(ast->cond);
148     if (ast->message != nullptr) {
149         fodder(ast->colonFodder);
150         expr(ast->message);
151     }
152     fodder(ast->semicolonFodder);
153     expr(ast->rest);
154 }
155 
visit(Binary * ast)156 void CompilerPass::visit(Binary *ast)
157 {
158     expr(ast->left);
159     fodder(ast->opFodder);
160     expr(ast->right);
161 }
162 
visit(Conditional * ast)163 void CompilerPass::visit(Conditional *ast)
164 {
165     expr(ast->cond);
166     fodder(ast->thenFodder);
167     if (ast->branchFalse != nullptr) {
168         expr(ast->branchTrue);
169         fodder(ast->elseFodder);
170         expr(ast->branchFalse);
171     } else {
172         expr(ast->branchTrue);
173     }
174 }
175 
visit(Error * ast)176 void CompilerPass::visit(Error *ast)
177 {
178     expr(ast->expr);
179 }
180 
visit(Function * ast)181 void CompilerPass::visit(Function *ast)
182 {
183     params(ast->parenLeftFodder, ast->params, ast->parenRightFodder);
184     expr(ast->body);
185 }
186 
visit(Import * ast)187 void CompilerPass::visit(Import *ast)
188 {
189     visit(ast->file);
190 }
191 
visit(Importstr * ast)192 void CompilerPass::visit(Importstr *ast)
193 {
194     visit(ast->file);
195 }
196 
visit(InSuper * ast)197 void CompilerPass::visit(InSuper *ast)
198 {
199     expr(ast->element);
200 }
201 
visit(Index * ast)202 void CompilerPass::visit(Index *ast)
203 {
204     expr(ast->target);
205     if (ast->id != nullptr) {
206     } else {
207         if (ast->isSlice) {
208             if (ast->index != nullptr)
209                 expr(ast->index);
210             if (ast->end != nullptr)
211                 expr(ast->end);
212             if (ast->step != nullptr)
213                 expr(ast->step);
214         } else {
215             expr(ast->index);
216         }
217     }
218 }
219 
visit(Local * ast)220 void CompilerPass::visit(Local *ast)
221 {
222     assert(ast->binds.size() > 0);
223     for (auto &bind : ast->binds) {
224         fodder(bind.varFodder);
225         if (bind.functionSugar) {
226             params(bind.parenLeftFodder, bind.params, bind.parenRightFodder);
227         }
228         fodder(bind.opFodder);
229         expr(bind.body);
230         fodder(bind.closeFodder);
231     }
232     expr(ast->body);
233 }
234 
visit(Object * ast)235 void CompilerPass::visit(Object *ast)
236 {
237     fields(ast->fields);
238     fodder(ast->closeFodder);
239 }
240 
visit(DesugaredObject * ast)241 void CompilerPass::visit(DesugaredObject *ast)
242 {
243     for (AST *assert : ast->asserts) {
244         expr(assert);
245     }
246     for (auto &field : ast->fields) {
247         expr(field.name);
248         expr(field.body);
249     }
250 }
251 
visit(ObjectComprehension * ast)252 void CompilerPass::visit(ObjectComprehension *ast)
253 {
254     fields(ast->fields);
255     specs(ast->specs);
256     fodder(ast->closeFodder);
257 }
258 
visit(ObjectComprehensionSimple * ast)259 void CompilerPass::visit(ObjectComprehensionSimple *ast)
260 {
261     expr(ast->field);
262     expr(ast->value);
263     expr(ast->array);
264 }
265 
visit(Parens * ast)266 void CompilerPass::visit(Parens *ast)
267 {
268     expr(ast->expr);
269     fodder(ast->closeFodder);
270 }
271 
visit(SuperIndex * ast)272 void CompilerPass::visit(SuperIndex *ast)
273 {
274     if (ast->id != nullptr) {
275     } else {
276         expr(ast->index);
277     }
278 }
279 
visit(Unary * ast)280 void CompilerPass::visit(Unary *ast)
281 {
282     expr(ast->expr);
283 }
284 
285 #define VISIT(var,astType,astClass) \
286    case astType: { \
287      assert(dynamic_cast<astClass *>(var)); \
288      auto *ast = static_cast<astClass *>(var); \
289      visit(ast); \
290    } break
291 
visitExpr(AST * & ast_)292 void CompilerPass::visitExpr(AST *&ast_)
293 {
294     switch(ast_->type) {
295         VISIT(ast_, AST_APPLY, Apply);
296         VISIT(ast_, AST_APPLY_BRACE, ApplyBrace);
297         VISIT(ast_, AST_ARRAY, Array);
298         VISIT(ast_, AST_ARRAY_COMPREHENSION, ArrayComprehension);
299         // VISIT(ast_, AST_ARRAY_COMPREHENSION, ArrayComprehensionSimple);
300         VISIT(ast_, AST_ASSERT, Assert);
301         VISIT(ast_, AST_BINARY, Binary);
302         VISIT(ast_, AST_BUILTIN_FUNCTION, BuiltinFunction);
303         VISIT(ast_, AST_CONDITIONAL, Conditional);
304         VISIT(ast_, AST_DESUGARED_OBJECT, DesugaredObject);
305         VISIT(ast_, AST_DOLLAR, Dollar);
306         VISIT(ast_, AST_ERROR, Error);
307         VISIT(ast_, AST_FUNCTION, Function);
308         VISIT(ast_, AST_IMPORT, Import);
309         VISIT(ast_, AST_IMPORTSTR, Importstr);
310         VISIT(ast_, AST_INDEX, Index);
311         VISIT(ast_, AST_IN_SUPER, InSuper);
312         VISIT(ast_, AST_LITERAL_BOOLEAN, LiteralBoolean);
313         VISIT(ast_, AST_LITERAL_NULL, LiteralNull);
314         VISIT(ast_, AST_LITERAL_NUMBER, LiteralNumber);
315         VISIT(ast_, AST_LITERAL_STRING, LiteralString);
316         VISIT(ast_, AST_LOCAL, Local);
317         VISIT(ast_, AST_OBJECT, Object);
318         VISIT(ast_, AST_OBJECT_COMPREHENSION, ObjectComprehension);
319         VISIT(ast_, AST_OBJECT_COMPREHENSION_SIMPLE, ObjectComprehensionSimple);
320         VISIT(ast_, AST_PARENS, Parens);
321         VISIT(ast_, AST_SELF, Self);
322         VISIT(ast_, AST_SUPER_INDEX, SuperIndex);
323         VISIT(ast_, AST_UNARY, Unary);
324         VISIT(ast_, AST_VAR, Var);
325         default:
326             std::cerr << "INTERNAL ERROR: Unknown AST: " << ast_ << std::endl;
327             std::abort();
328             break;
329     }
330 }
331 
file(AST * & body,Fodder & final_fodder)332 void CompilerPass::file(AST *&body, Fodder &final_fodder)
333 {
334     expr(body);
335     fodder(final_fodder);
336 }
337 
338 /** A pass that clones the AST it is given. */
339 class ClonePass : public CompilerPass {
340    public:
ClonePass(Allocator & alloc)341     ClonePass(Allocator &alloc) : CompilerPass(alloc) {}
342     virtual void expr(AST *&ast);
343 };
344 
345 #define CLONE(var,astType,astClass) \
346    case astType: { \
347      assert(dynamic_cast<astClass *>(var)); \
348      auto *ast = static_cast<astClass *>(var); \
349      var = alloc.clone(ast); \
350    } break
351 
expr(AST * & ast_)352 void ClonePass::expr(AST *&ast_)
353 {
354     switch(ast_->type) {
355         CLONE(ast_, AST_APPLY, Apply);
356         CLONE(ast_, AST_APPLY_BRACE, ApplyBrace);
357         CLONE(ast_, AST_ARRAY, Array);
358         CLONE(ast_, AST_ARRAY_COMPREHENSION, ArrayComprehension);
359         // CLONE(ast_, AST_ARRAY_COMPREHENSION, ArrayComprehensionSimple);
360         CLONE(ast_, AST_ASSERT, Assert);
361         CLONE(ast_, AST_BINARY, Binary);
362         CLONE(ast_, AST_BUILTIN_FUNCTION, BuiltinFunction);
363         CLONE(ast_, AST_CONDITIONAL, Conditional);
364         CLONE(ast_, AST_DESUGARED_OBJECT, DesugaredObject);
365         CLONE(ast_, AST_DOLLAR, Dollar);
366         CLONE(ast_, AST_ERROR, Error);
367         CLONE(ast_, AST_FUNCTION, Function);
368         CLONE(ast_, AST_IMPORT, Import);
369         CLONE(ast_, AST_IMPORTSTR, Importstr);
370         CLONE(ast_, AST_INDEX, Index);
371         CLONE(ast_, AST_IN_SUPER, InSuper);
372         CLONE(ast_, AST_LITERAL_BOOLEAN, LiteralBoolean);
373         CLONE(ast_, AST_LITERAL_NULL, LiteralNull);
374         CLONE(ast_, AST_LITERAL_NUMBER, LiteralNumber);
375         CLONE(ast_, AST_LITERAL_STRING, LiteralString);
376         CLONE(ast_, AST_LOCAL, Local);
377         CLONE(ast_, AST_OBJECT, Object);
378         CLONE(ast_, AST_OBJECT_COMPREHENSION, ObjectComprehension);
379         CLONE(ast_, AST_OBJECT_COMPREHENSION_SIMPLE, ObjectComprehensionSimple);
380         CLONE(ast_, AST_PARENS, Parens);
381         CLONE(ast_, AST_SELF, Self);
382         CLONE(ast_, AST_SUPER_INDEX, SuperIndex);
383         CLONE(ast_, AST_UNARY, Unary);
384         CLONE(ast_, AST_VAR, Var);
385         default:
386             std::cerr << "INTERNAL ERROR: Unknown AST: " << ast_ << std::endl;
387             std::abort();
388             break;
389     }
390 
391     CompilerPass::expr(ast_);
392 }
393 
clone_ast(Allocator & alloc,AST * ast)394 AST *clone_ast(Allocator &alloc, AST *ast)
395 {
396     AST *r = ast;
397     ClonePass(alloc).expr(r);
398     return r;
399 }
400