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 ¶ms, Fodder &fodder_r)
41 {
42 fodder(fodder_l);
43 for (auto ¶m : 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