Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(724)

Side by Side Diff: lib/compiler/implementation/js/nodes.dart

Issue 10825180: Add JavaScript AST. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: updated. Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 interface NodeVisitor<T> {
6 T visitProgram(Program program);
7
8 T visitBlock(Block block);
9 T visitExpressionStatement(ExpressionStatement expressionStatement);
10 T visitNOP(NOP nop);
11 T visitIf(If node);
12 T visitFor(For loop);
13 T visitForIn(ForIn loop);
14 T visitWhile(While loop);
15 T visitDo(Do loop);
16 T visitContinue(Continue cont);
17 T visitBreak(Break node);
18 T visitReturn(Return node);
19 T visitThrow(Throw node);
20 T visitTry(Try node);
21 T visitCatch(Catch node);
22 T visitWith(With node);
23 T visitSwitch(Switch node);
24 T visitCase(Case node);
25 T visitDefault(Default node);
26 T visitFunctionDeclaration(FunctionDeclaration declaration);
27 T visitLabeled(Labeled node);
28 T visitStatementBlob(StatementBlob node);
29
30 T visitExpressionBlob(ExpressionBlob blob);
Lasse Reichstein Nielsen 2012/08/08 11:16:38 LiteralExpression.
floitsch 2012/08/09 16:24:07 Done.
31 T visitVariableDeclarationList(VariableDeclarationList list);
32 T visitSequence(Sequence sequence);
33 T visitVassign(Vassign vassign);
Lasse Reichstein Nielsen 2012/08/08 11:16:38 Expand name. What's a "Vassign"?
floitsch 2012/08/09 16:24:07 Simplified.
34 T visitInit(Init init);
Lasse Reichstein Nielsen 2012/08/08 11:16:38 Initialize? Initializer? Initialization?
35 T visitAccsign(Accsign accsign);
Lasse Reichstein Nielsen 2012/08/08 11:16:38 Wut?
36 T visitVassignOp(VassignOp vassignOp);
Lasse Reichstein Nielsen 2012/08/08 11:16:38 VariableAssignOperation? Operator?
37 T visitAccsignOp(AccsignOp accsignOp);
38 T visitConditional(Conditional cond);
39 T visitNew(New node);
40 T visitCall(Call call);
41 T visitBinary(Binary binary);
Lasse Reichstein Nielsen 2012/08/08 11:16:38 Perhaps BinaryOperation? But not necessarily, just
floitsch 2012/08/09 16:24:07 Prefer to call it Binary. Otherwise Prefix and Pos
42 T visitUnary(Unary unary);
43 T visitPostfix(Postfix postfix);
44
45 T visitRef(Ref ref);
Lasse Reichstein Nielsen 2012/08/08 11:16:38 Wut?
46 T visitThis(This node);
47 T visitDecl(Decl decl);
Lasse Reichstein Nielsen 2012/08/08 11:16:38 Declaration.
48 T visitParam(Param param);
Lasse Reichstein Nielsen 2012/08/08 11:16:38 Parameter ... you get the idea. Don't abbreviate n
49 T visitAccess(Access access);
Lasse Reichstein Nielsen 2012/08/08 11:16:38 What is an "Access"? Better name?
50
51 T visitNamedFunction(NamedFunction namedFunction);
52 T visitFun(Fun fun);
53
54 T visitBoolLiteral(BoolLiteral node);
Lasse Reichstein Nielsen 2012/08/08 11:16:38 I prefer "LiteralBool", but that's subjective.
floitsch 2012/08/09 16:24:07 Done.
55 T visitStringLiteral(StringLiteral node);
56 T visitNumberLiteral(NumberLiteral node);
57 T visitNullLiteral(NullLiteral node);
58
59 T visitArrayLiteral(ArrayLiteral node);
60 T visitArrayElement(ArrayElement node);
Lasse Reichstein Nielsen 2012/08/08 11:16:38 What is an ArrayElement?
floitsch 2012/08/09 16:24:07 An element in an ArrayInitializer. Couldn't find a
61 T visitObjectLiteral(ObjectLiteral node);
62 T visitPropertyInit(PropertyInit node);
63 T visitRegExpLiteral(RegExpLiteral node);
64 }
65
66 class BaseVisitor<T> implements NodeVisitor {
67 T visitNode(Node node) {
68 node.visitChildren(this);
69 return null;
70 }
71
72 T visitProgram(Program node) => visitNode(node);
73
74 T visitStatement(Statement node) => visitNode(node);
75 T visitLoop(Loop node) => visitStatement(node);
76 T visitInterruption(Statement node) => visitStatement(node);
77
78 T visitBlock(Block node) => visitStatement(node);
79 T visitExpressionStatement(ExpressionStatement node)
80 => visitStatement(node);
81 T visitNOP(NOP node) => visitStatement(node);
82 T visitIf(If node) => visitStatement(node);
83 T visitFor(For node) => visitLoop(node);
84 T visitForIn(ForIn node) => visitLoop(node);
85 T visitWhile(While node) => visitLoop(node);
86 T visitDo(Do node) => visitLoop(node);
87 T visitContinue(Continue node) => visitInterruption(node);
Lasse Reichstein Nielsen 2012/08/08 11:16:38 I'd prefer visitControlFlow or visitJump. Interrup
floitsch 2012/08/09 16:24:07 Done.
88 T visitBreak(Break node) => visitInterruption(node);
89 T visitReturn(Return node) => visitInterruption(node);
90 T visitThrow(Throw node) => visitInterruption(node);
91 T visitTry(Try node) => visitStatement(node);
92 T visitWith(With node) => visitStatement(node);
93 T visitSwitch(Switch node) => visitStatement(node);
94 T visitFunctionDeclaration(FunctionDeclaration node)
95 => visitStatement(node);
96 T visitLabeled(Labeled node) => visitStatement(node);
97 T visitStatementBlob(StatementBlob node) => visitStatement(node);
98
99 T visitCatch(Catch node) => visitNode(node);
100 T visitCase(Case node) => visitNode(node);
101 T visitDefault(Default node) => visitNode(node);
102
103 T visitExpression(Expression node) => visitNode(node);
104 T visitAssign(Assign node) => visitExpression(node);
105
106 T visitExpressionBlob(ExpressionBlob node) => visitExpression(node);
107 T visitVariableDeclarationList(VariableDeclarationList node)
108 => visitExpression(node);
109 T visitSequence(Sequence node) => visitExpression(node);
110 T visitVassign(Vassign node) => visitAssign(node);
111 T visitInit(Init node) {
112 if (node.value != null) {
113 visitAssign(node);
114 } else {
115 visitExpression(node);
116 }
117 }
118 T visitAccsign(Accsign node) => visitAssign(node);
119 T visitVassignOp(VassignOp node) => visitVassign(node);
120 T visitAccsignOp(AccsignOp node) => visitAccsign(node);
121 T visitConditional(Conditional node) => visitExpression(node);
122 T visitNew(New node) => visitExpression(node);
123 T visitCall(Call node) => visitExpression(node);
124 T visitBinary(Binary node) => visitCall(node);
125 T visitUnary(Unary node) => visitCall(node);
126 T visitPostfix(Postfix node) => visitCall(node);
127 T visitAccess(Access node) => visitExpression(node);
128
129 T visitRef(Ref node) => visitExpression(node);
130 T visitDecl(Decl node) => visitRef(node);
131 T visitParam(Param node) => visitDecl(node);
132 T visitThis(This node) => visitParam(node);
133
134 T visitNamedFunction(NamedFunction node) => visitExpression(node);
135 T visitFun(Fun node) => visitExpression(node);
136
137 T visitLiteral(Literal node) => visitExpression(node);
138
139 T visitBoolLiteral(BoolLiteral node) => visitLiteral(node);
140 T visitStringLiteral(StringLiteral node) => visitLiteral(node);
141 T visitNumberLiteral(NumberLiteral node) => visitLiteral(node);
142 T visitNullLiteral(NullLiteral node) => visitLiteral(node);
143
144 T visitArrayLiteral(ArrayLiteral node) => visitExpression(node);
145 T visitArrayElement(ArrayElement node) => visitNode(node);
146 T visitObjectLiteral(ObjectLiteral node) => visitExpression(node);
147 T visitPropertyInit(PropertyInit node) => visitNode(node);
148 T visitRegExpLiteral(RegExpLiteral node) => visitExpression(node);
149 }
150
151 class Node implements Hashable {
152 // I don't really like static state, but the alternatives seem even more
153 // annoying.
154 static int nodeCounter = 0;
155
156 final int nodeId;
157 Dynamic sourcePosition;
kasperl 2012/08/07 07:46:45 var
Lasse Reichstein Nielsen 2012/08/08 11:16:38 Or something better, if possible.
floitsch 2012/08/09 16:24:07 Done.
floitsch 2012/08/09 16:24:07 Not sure that is easy. I don't think the AST shoul
158 Dynamic endSourcePosition;
159
160 Node() : nodeId = nodeCounter++ & 0x7FFFFFFF;
161
162 abstract accept(NodeVisitor visitor);
163 abstract void visitChildren(NodeVisitor visitor);
164 int hashCode() => nodeId;
165 }
166
167 class Program extends Node {
168 List<Statement> body;
169 Program(this.body);
170
171 accept(NodeVisitor visitor) => visitor.visitProgram(this);
172 void visitChildren(NodeVisitor visitor) {
173 for (Statement statement in body) statement.accept(visitor);
174 }
175 }
176
177 abstract class Statement extends Node {
178 }
179
180 class Block extends Statement {
181 List<Statement> elements;
Lasse Reichstein Nielsen 2012/08/08 11:16:38 elements -> statements?
floitsch 2012/08/09 16:24:07 Done.
182 Block(this.elements);
183 Block.empty() : this.elements = <Statement>[];
184
185 accept(NodeVisitor visitor) => visitor.visitBlock(this);
186 void visitChildren(NodeVisitor visitor) {
187 for (Statement statement in elements) statement.accept(visitor);
188 }
189 }
190
191 class ExpressionStatement extends Statement {
192 Expression expr;
Lasse Reichstein Nielsen 2012/08/08 11:16:38 Don't abbreviate.
floitsch 2012/08/09 16:24:07 Done.
193 ExpressionStatement(this.expr);
194
195 accept(NodeVisitor visitor) => visitor.visitExpressionStatement(this);
196 void visitChildren(NodeVisitor visitor) { expr.accept(visitor); }
197 }
198
199 class NOP extends Statement {
kasperl 2012/08/07 07:46:45 I would call this EmptyStatement. I don't like the
Lasse Reichstein Nielsen 2012/08/08 11:16:38 +1
floitsch 2012/08/09 16:24:07 Done.
200 NOP();
201
202 accept(NodeVisitor visitor) => visitor.visitNOP(this);
203 void visitChildren(NodeVisitor visitor) {}
204 }
205
206 class If extends Statement {
207 Node test;
Lasse Reichstein Nielsen 2012/08/08 11:16:38 "Expression test;" ?
floitsch 2012/08/09 16:24:07 Done.
208 Node then;
209 Node otherwise;
210 If(this.test, this.then, this.otherwise);
211 If.then(this.test, this.then) : this.otherwise = new NOP();
Lasse Reichstein Nielsen 2012/08/08 11:16:38 Could you reuse an empty statement, or would it be
floitsch 2012/08/09 16:24:07 I think of an AST as a tree, and not as a DAG. We
212 bool get hasElse() => otherwise is !NOP;
213
214 accept(NodeVisitor visitor) => visitor.visitIf(this);
215 void visitChildren(NodeVisitor visitor) {
216 test.accept(visitor);
217 then.accept(visitor);
218 otherwise.accept(visitor);
219 }
220 }
221
222 abstract class Loop extends Statement {
223 Statement body;
224 Loop(this.body);
225 }
226
227 class For extends Loop {
228 Expression init;
229 Expression test;
kasperl 2012/08/07 07:46:45 test -> condition?
floitsch 2012/08/09 16:24:07 Done.
230 Expression incr;
kasperl 2012/08/07 07:46:45 incr -> update?
Lasse Reichstein Nielsen 2012/08/08 11:16:38 What Kasper said!
floitsch 2012/08/09 16:24:07 Done.
floitsch 2012/08/09 16:24:07 Done.
231 For(this.init, this.test, this.incr, Statement body) : super(body);
232
233 accept(NodeVisitor visitor) => visitor.visitFor(this);
234 void visitChildren(NodeVisitor visitor) {
235 if (init !== null) init.accept(visitor);
236 if (test !== null) test.accept(visitor);
237 if (incr !== null) incr.accept(visitor);
238 body.accept(visitor);
239 }
240 }
241
242 class ForIn extends Loop {
243 Expression lhs;
kasperl 2012/08/07 07:46:45 I would try to cut down on the abbreviations (if p
Lasse Reichstein Nielsen 2012/08/08 11:16:38 I'd say cut it all the way down to zero, and it be
Lasse Reichstein Nielsen 2012/08/08 11:16:38 The lhs can be a declaration: for (var i in beep)
floitsch 2012/08/09 16:24:07 trying :)
floitsch 2012/08/09 16:24:07 var x is a an expression in this AST.
floitsch 2012/08/09 16:24:07 Done.
244 Expression obj;
245 ForIn(this.lhs, this.obj, Statement body) : super(body);
246
247 accept(NodeVisitor visitor) => visitor.visitForIn(this);
248 void visitChildren(NodeVisitor visitor) {
249 lhs.accept(visitor);
250 obj.accept(visitor);
251 body.accept(visitor);
252 }
253 }
254
255 class While extends Loop {
256 Node test;
257 While(this.test, Statement body) : super(body);
258
259 accept(NodeVisitor visitor) => visitor.visitWhile(this);
260 void visitChildren(NodeVisitor visitor) {
261 test.accept(visitor);
262 body.accept(visitor);
263 }
264 }
265
266 class Do extends Loop {
267 Node test;
268 Do(Statement body, this.test) : super(body);
269
270 accept(NodeVisitor visitor) => visitor.visitDo(this);
271 void visitChildren(NodeVisitor visitor) {
272 body.accept(visitor);
273 test.accept(visitor);
274 }
275 }
276
277 class Continue extends Statement {
278 String id; // Can be null.
kasperl 2012/08/07 07:46:45 Can more of these fields be final? Seems like that
Lasse Reichstein Nielsen 2012/08/08 11:16:38 id -> targetLabel. Ditto for break.
floitsch 2012/08/09 16:24:07 Done.
279 Continue(this.id);
280
281 accept(NodeVisitor visitor) => visitor.visitContinue(this);
282 void visitChildren(NodeVisitor visitor) {}
283 }
284
285 class Break extends Statement {
286 String id; // Can be null.
287 Break(this.id);
288
289 accept(NodeVisitor visitor) => visitor.visitBreak(this);
290 void visitChildren(NodeVisitor visitor) {}
291 }
292
293 class Return extends Statement {
294 Expression expr; // Can be null.
295 Return(this.expr);
Lasse Reichstein Nielsen 2012/08/08 11:16:38 make this.expr optional.
floitsch 2012/08/09 16:24:07 Done.
296
297 accept(NodeVisitor visitor) => visitor.visitReturn(this);
298 void visitChildren(NodeVisitor visitor) {
299 expr.accept(visitor);
Lasse Reichstein Nielsen 2012/08/08 11:16:38 if (expr !== null) expr.accept(visitor);
floitsch 2012/08/09 16:24:07 Done.
300 }
301 }
302
303 class Throw extends Statement {
304 Expression expr;
305 Throw(this.expr);
306
307 accept(NodeVisitor visitor) => visitor.visitThrow(this);
308 void visitChildren(NodeVisitor visitor) {
309 expr.accept(visitor);
310 }
311 }
312
313 class Try extends Statement {
314 Block body;
315 Catch catchPart;
316 Block finallyPart;
Lasse Reichstein Nielsen 2012/08/08 11:16:38 Add comment saying that either, but not both, of c
floitsch 2012/08/09 16:24:07 Done.
317 Try(this.body, this.catchPart, this.finallyPart);
318
319 accept(NodeVisitor visitor) => visitor.visitTry(this);
320 void visitChildren(NodeVisitor visitor) {
321 body.accept(visitor);
322 if (catchPart !== null) catchPart.accept(visitor);
323 if (finallyPart !== null) finallyPart.accept(visitor);
324 }
325 }
326
327 class Catch extends Node {
328 Decl decl;
329 Block body;
330 Catch(this.decl, this.body);
331
332 accept(NodeVisitor visitor) => visitor.visitCatch(this);
333 void visitChildren(NodeVisitor visitor) {
334 decl.accept(visitor);
335 body.accept(visitor);
336 }
337 }
338
339 class With extends Statement {
kasperl 2012/08/07 07:46:45 Do we need this?
floitsch 2012/08/09 16:24:07 Done.
340 Expression object;
341 Statement body;
342 With(this.object, this.body);
343
344 accept(NodeVisitor visitor) => visitor.visitWith(this);
345 void visitChildren(NodeVisitor visitor) {
346 object.accept(visitor);
347 body.accept(visitor);
348 }
349 }
350
351 class Switch extends Statement {
352 Expression key;
353 List<SwitchClause> cases;
354 Switch(this.key, this.cases);
355
356 accept(NodeVisitor visitor) => visitor.visitSwitch(this);
357 void visitChildren(NodeVisitor visitor) {
358 key.accept(visitor);
359 for (SwitchClause clause in cases) clause.accept(visitor);
360 }
361 }
362
363 abstract class SwitchClause extends Node {
364 Block body;
365 SwitchClause(this.body);
366 }
367
368 class Case extends SwitchClause {
369 Expression expr;
370 Case(this.expr, Block body) : super(body);
371
372 accept(NodeVisitor visitor) => visitor.visitCase(this);
373 void visitChildren(NodeVisitor visitor) {
374 expr.accept(visitor);
375 body.accept(visitor);
376 }
377 }
378
379 class Default extends SwitchClause {
380 Default(Block body) : super(body);
381
382 accept(NodeVisitor visitor) => visitor.visitDefault(this);
383 void visitChildren(NodeVisitor visitor) {
384 body.accept(visitor);
385 }
386 }
387
388 class FunctionDeclaration extends Statement {
389 Decl id;
390 Fun fun;
391 FunctionDeclaration(this.id, this.fun);
392
393 accept(NodeVisitor visitor) => visitor.visitFunctionDeclaration(this);
394 void visitChildren(NodeVisitor visitor) {
395 id.accept(visitor);
396 fun.accept(visitor);
397 }
398 }
399
400 class Labeled extends Statement {
Lasse Reichstein Nielsen 2012/08/08 11:16:38 LabeledStatement (Labeled isn't a noun phrase).
floitsch 2012/08/09 16:24:07 Done.
401 String id;
Lasse Reichstein Nielsen 2012/08/08 11:16:38 id -> label.
floitsch 2012/08/09 16:24:07 Done.
402 Statement body;
403 Labeled(this.id, this.body);
404
405 accept(NodeVisitor visitor) => visitor.visitLabeled(this);
406 void visitChildren(NodeVisitor visitor) {
407 body.accept(visitor);
408 }
409 }
410
411 class StatementBlob extends Statement {
412 String blob;
413 StatementBlob(this.blob);
414
415 accept(NodeVisitor visitor) => visitor.visitStatementBlob(this);
416 void visitChildren(NodeVisitor visitor) { }
417 }
418
419 abstract class Expression extends Node {
420 abstract int get precedenceLevel();
421 }
422
423 class ExpressionBlob extends Expression {
Lasse Reichstein Nielsen 2012/08/08 11:16:38 ExpressionBlob -> LiteralExpression. blob -> sourc
floitsch 2012/08/09 16:24:07 blob -> template. data -> inputs. done.
424 String blob;
425 List<Expression> data;
426 ExpressionBlob(this.blob);
427 ExpressionBlob.withData(this.blob, this.data);
428
429 accept(NodeVisitor visitor) => visitor.visitExpressionBlob(this);
430 void visitChildren(NodeVisitor visitor) {
431 for (Expression expr in data) expr.accept(visitor);
432 }
433
434 int get precedenceLevel() => EXPRESSION;
kasperl 2012/08/07 07:46:45 Put this in Expression?
floitsch 2012/08/09 16:24:07 It's not duplicated that often, and I prefer to be
435 }
436
437 class VariableDeclarationList extends Expression {
438 List<Init> declarations;
439 VariableDeclarationList(this.declarations);
440
441 accept(NodeVisitor visitor) => visitor.visitVariableDeclarationList(this);
442 void visitChildren(NodeVisitor visitor) {
443 for (Init init in declarations) init.accept(visitor);
444 }
445
446 int get precedenceLevel() => EXPRESSION;
447 }
448
449 class Sequence extends Expression {
450 List<Expression> expressions;
451 Sequence(this.expressions);
452
453 accept(NodeVisitor visitor) => visitor.visitSequence(this);
454 void visitChildren(NodeVisitor visitor) {
455 for (Expression expr in expressions) expr.accept(visitor);
456 }
457
458 int get precedenceLevel() => EXPRESSION;
459 }
460
461 class Assign extends Expression {
462 abstract Expression get lhs();
Lasse Reichstein Nielsen 2012/08/08 11:16:38 Getters below constructors. Only fields above.
floitsch 2012/08/09 16:24:07 Done.
463 Expression value; // May be null, for [Init]s.
464 Assign(this.value);
465
466 int get precedenceLevel() => ASSIGNMENT;
467 }
468
469 class Vassign extends Assign {
kasperl 2012/08/07 07:46:45 Vassign? Maybe think of a better name.
Lasse Reichstein Nielsen 2012/08/08 11:16:38 No "maybe". Do! I'm guessing "VariableAssignment"
floitsch 2012/08/09 16:24:07 Removed.
470 Ref lhs;
471 Vassign(this.lhs, Expression value): super(value);
472
473 accept(NodeVisitor visitor) => visitor.visitVassign(this);
474 void visitChildren(NodeVisitor visitor) {
475 lhs.accept(visitor);
476 value.accept(visitor);
477 }
478 }
479
480 class Init extends Vassign {
481 /** [value] may be null. */
482 Init(Decl decl, Expression value) : super(decl, value);
483
484 Ref get decl() => lhs;
485
486 accept(NodeVisitor visitor) => visitor.visitInit(this);
487 void visitChildren(NodeVisitor visitor) {
488 decl.accept(visitor);
489 if (value !== null) value.accept(visitor);
490 }
491 }
492
493 class VassignOp extends Vassign {
kasperl 2012/08/07 07:46:45 Vassign.
Lasse Reichstein Nielsen 2012/08/08 11:16:38 Is this, e.g., v += 42; ? Is it necessary to have
494 Ref target;
495 VassignOp(Ref lhs, String op, Expression value)
496 : target = new Ref(op), super(lhs, value);
497
498 String get op() => target.id;
499
500 accept(NodeVisitor visitor) => visitor.visitVassignOp(this);
501 void visitChildren(NodeVisitor visitor) {
502 lhs.accept(visitor);
503 target.accept(visitor);
504 value.accept(visitor);
505 }
506 }
507
508 class Accsign extends Assign {
kasperl 2012/08/07 07:46:45 Accsign?
Lasse Reichstein Nielsen 2012/08/08 11:16:38 What is an Access? I'm *guessing* it's, e.g., x.y.
509 Access lhs;
510 Accsign(this.lhs, Expression value): super(value);
511
512 accept(NodeVisitor visitor) => visitor.visitAccsign(this);
513 void visitChildren(NodeVisitor visitor) {
514 lhs.accept(visitor);
515 value.accept(visitor);
516 }
517 }
518
519 class AccsignOp extends Accsign {
520 Ref target;
521 AccsignOp(Access lhs, String op, Expression value)
522 : target = new Ref(op), super(lhs, value);
523
524 String get op() => target.id;
525
526 accept(NodeVisitor visitor) => visitor.visitAccsignOp(this);
527 void visitChildren(NodeVisitor visitor) {
528 lhs.accept(visitor);
529 target.accept(visitor);
530 value.accept(visitor);
531 }
532 }
533
534 class Conditional extends Expression {
535 Expression test;
536 Expression then;
537 Expression otherwise;
538 Conditional(this.test, this.then, this.otherwise);
539
540 accept(NodeVisitor visitor) => visitor.visitConditional(this);
541 void visitChildren(NodeVisitor visitor) {
542 test.accept(visitor);
543 then.accept(visitor);
544 otherwise.accept(visitor);
545 }
546
547 int get precedenceLevel() => ASSIGNMENT;
548 }
549
550 class New extends Expression {
Lasse Reichstein Nielsen 2012/08/08 11:16:38 Could "New" extend "Call"? They have the same fiel
floitsch 2012/08/09 16:24:07 Nice suggestion. done.
551 Expression cls;
552 List<Expression> arguments;
553 New(this.cls, this.arguments);
554
555 accept(NodeVisitor visitor) => visitor.visitNew(this);
556 void visitChildren(NodeVisitor visitor) {
557 cls.accept(visitor);
558 for (Expression arg in arguments) arg.accept(visitor);
559 }
560
561 int get precedenceLevel() => CALL;
562 }
563
564 class Call extends Expression {
565 Expression target;
566 List<Expression> arguments;
567 Call(this.target, this.arguments);
568
569 accept(NodeVisitor visitor) => visitor.visitCall(this);
570 void visitChildren(NodeVisitor visitor) {
571 target.accept(visitor);
572 for (Expression arg in arguments) arg.accept(visitor);
573 }
574
575 int get precedenceLevel() => CALL;
576 }
577
578 class Binary extends Call {
579 Binary(String op, Expression left, Expression right)
580 : super(new Ref(op), <Expression>[left, right]);
Lasse Reichstein Nielsen 2012/08/08 11:16:38 That seems wrong. The "op" is not referencing a va
floitsch 2012/08/09 16:24:07 Depends on how you look at operators. For Schemers
581
582 String get op() {
583 return (target as Ref).id;
584 }
585 Expression get left() => arguments[0];
586 Expression get right() => arguments[1];
587
588 accept(NodeVisitor visitor) => visitor.visitBinary(this);
589 // Inherit visitChildren from [Call].
590
591 int get precedenceLevel() {
592 switch (op) {
593 case "*":
594 case "/":
595 case "%":
596 return MULTIPLICATIVE;
597 case "+":
598 case "-":
599 return ADDITIVE;
600 case "<<":
601 case ">>":
602 case ">>>":
603 return SHIFT;
604 case "<":
605 case ">":
606 case "<=":
607 case ">=":
608 case "instanceof":
609 case "in":
610 return RELATIONAL;
611 case "==":
612 case "===":
613 case "!=":
614 case "!==":
615 return EQUALITY;
616 case "&":
617 return BIT_AND;
618 case "^":
619 return BIT_XOR;
620 case "|":
621 return BIT_OR;
622 case "&&":
623 return LOGICAL_AND;
624 case "||":
625 return LOGICAL_OR;
626 default:
627 throw new CompilerCancelledException(
628 "Internal Error: Unhandled binary operator: $op");
629 }
630 }
631 }
632
633 class Unary extends Call {
634 Unary(String op, Expression arg) : super(new Ref(op), <Expression>[arg]);
Lasse Reichstein Nielsen 2012/08/08 11:16:38 new Ref.unaryOperator(op) ?
floitsch 2012/08/09 16:24:07 Done.
635
636 String get op() {
637 return (target as Ref).id;
638 }
639 Expression get arg() => arguments[0];
640
641 accept(NodeVisitor visitor) => visitor.visitUnary(this);
642 // Inherit visitChildren from [Call].
643
644 int get precedenceLevel() => UNARY;
645 }
646
647 class Postfix extends Call {
648 Postfix(String op, Expression arg) : super(new Ref(op), <Expression>[arg]);
649
650 String get op() {
651 return (target as Ref).id;
652 }
653 Expression get arg() => arguments[0];
654
655 accept(NodeVisitor visitor) => visitor.visitPostfix(this);
656 // Inherit visitChildren from [Call].
657
658 int get precedenceLevel() => UNARY;
659 }
660
661 class Ref extends Expression {
662 final String id;
663 final bool isOperator = false;
664 final bool isUnaryOperator = false;
665
666 Ref(this.id);
667 Ref.operator(this.id) : isOperator = true;
668 Ref.unaryOperator(this.id) : isOperator = true, isUnaryOperator = true;
669
670 accept(NodeVisitor visitor) => visitor.visitRef(this);
671 void visitChildren(NodeVisitor visitor) {}
672
673 int get precedenceLevel() => PRIMARY;
674 }
675
676 class Decl extends Ref {
Lasse Reichstein Nielsen 2012/08/08 11:16:38 Extends Ref? I thought both referred to a variable
floitsch 2012/08/09 16:24:07 As discussed. Added VariableReference super class.
677 Decl(String id) : super(id);
678
679 accept(NodeVisitor visitor) => visitor.visitDecl(this);
680 // Inherit visitChildren from [Ref].
681 }
682
683 class Param extends Decl {
684 Param(String id) : super(id);
685
686 accept(NodeVisitor visitor) => visitor.visitParam(this);
687 // Inherit visitChildren from [Ref].
688 }
689
690 class This extends Param {
691 This() : super("this");
Lasse Reichstein Nielsen 2012/08/08 11:16:38 Clever.
692
693 accept(NodeVisitor visitor) => visitor.visitThis(this);
694 // Inherit visitChildren from [Ref].
695 }
696
697 class NamedFunction extends Expression {
698 Decl id;
699 Fun fun;
700 NamedFunction(this.id, this.fun);
701
702 accept(NodeVisitor visitor) => visitor.visitNamedFunction(this);
703 void visitChildren(NodeVisitor visitor) {
704 id.accept(visitor);
705 fun.accept(visitor);
706 }
707
708 int get precedenceLevel() => CALL;
709 }
710
711 class Fun extends Expression {
kasperl 2012/08/07 07:46:45 Function?
floitsch 2012/08/09 16:24:07 This would shadow the global Function type.
712 List<Param> params;
713 Block body;
714 Fun(this.params, this.body);
715
716 accept(NodeVisitor visitor) => visitor.visitFun(this);
717 void visitChildren(NodeVisitor visitor) {
718 for (Param param in params) param.accept(visitor);
719 body.accept(visitor);
720 }
721
722 int get precedenceLevel() => CALL;
723 }
724
725 class Access extends Expression {
726 Expression receiver;
727 Expression selector;
728 Access(this.receiver, this.selector);
729 Access.field(this.receiver, String fieldName)
730 : selector = new StringLiteral("'$fieldName'");
731
732 accept(NodeVisitor visitor) => visitor.visitAccess(this);
733 void visitChildren(NodeVisitor visitor) {
734 receiver.accept(visitor);
735 selector.accept(visitor);
736 }
737
738 int get precedenceLevel() => CALL;
739 }
740
741 abstract class Literal extends Expression {
742 void visitChildren(NodeVisitor visitor) {}
743
744 int get precedenceLevel() => PRIMARY;
745 }
746
747 class BoolLiteral extends Literal {
748 final bool value;
749 BoolLiteral(this.value);
750
751 accept(NodeVisitor visitor) => visitor.visitBoolLiteral(this);
752 // [visitChildren] inherited from [Literal].
753 }
754
755 class NullLiteral extends Literal {
756 NullLiteral();
757
758 accept(NodeVisitor visitor) => visitor.visitNullLiteral(this);
759 // [visitChildren] inherited from [Literal].
760 }
761
762 class StringLiteral extends Literal {
763 final String value;
764 StringLiteral(this.value);
765
766 accept(NodeVisitor visitor) => visitor.visitStringLiteral(this);
767 // [visitChildren] inherited from [Literal].
768 }
769
770 class NumberLiteral extends Literal {
771 final String value;
772 NumberLiteral(this.value);
773
774 accept(NodeVisitor visitor) => visitor.visitNumberLiteral(this);
775 // [visitChildren] inherited from [Literal].
776 }
777
778 // Despite being called "Literal" the [ArrayLiteral] does not inherit from
779 // [Literal].
Lasse Reichstein Nielsen 2012/08/08 11:16:38 Why not?
floitsch 2012/08/09 16:24:07 Changed name to ArrayInitialization.
780 class ArrayLiteral extends Expression {
781 int length;
782 List<ArrayElement> elements;
783 ArrayLiteral(this.length, this.elements);
784
785 accept(NodeVisitor visitor) => visitor.visitArrayLiteral(this);
786 void visitChildren(NodeVisitor visitor) {
787 for (ArrayElement element in elements) element.accept(visitor);
788 }
789
790 int get precedenceLevel() => PRIMARY;
791 }
792
793 class ArrayElement extends Node {
794 int index;
Lasse Reichstein Nielsen 2012/08/08 11:16:38 When is that useful?
floitsch 2012/08/09 16:24:07 added comment. An ArrayInitialization has a sparse
795 Expression value;
796 ArrayElement(this.index, this.value);
797
798 accept(NodeVisitor visitor) => visitor.visitArrayElement(this);
799 void visitChildren(NodeVisitor visitor) {
800 value.accept(visitor);
801 }
802 }
803
804 // Despite being called "Literal" the [ObjectLiteral] does not inherit from
805 // [Literal].
806 class ObjectLiteral extends Expression {
807 List<PropertyInit> properties;
Lasse Reichstein Nielsen 2012/08/08 11:16:38 Just "Property". The "Init" makes no sense.
floitsch 2012/08/09 16:24:07 Done.
808 ObjectLiteral(this.properties);
809
810 accept(NodeVisitor visitor) => visitor.visitObjectLiteral(this);
811 void visitChildren(NodeVisitor visitor) {
812 for (PropertyInit init in properties) init.accept(visitor);
813 }
814
815 int get precedenceLevel() => PRIMARY;
816 }
817
818 class PropertyInit extends Node {
819 Literal name;
820 Expression value;
821 PropertyInit(this.name, this.value);
822
823 accept(NodeVisitor visitor) => visitor.visitPropertyInit(this);
824 void visitChildren(NodeVisitor visitor) {
825 name.accept(visitor);
826 value.accept(visitor);
827 }
828 }
829
830 // Despite being called "Literal" the [RegExpLiteral] does not inherit from
831 // [Literal].
Lasse Reichstein Nielsen 2012/08/08 11:16:38 Why not, it doesn't even need to extend visitChild
floitsch 2012/08/09 16:24:07 As discussed. It is evaluated and thus has a side-
832 class RegExpLiteral extends Expression {
833 /** Contains the pattern and the flags.*/
834 String pattern;
835 RegExpLiteral(this.pattern);
836
837 accept(NodeVisitor visitor) => visitor.visitRegExpLiteral(this);
838 void visitChildren(NodeVisitor visitor) {}
839
840 int get precedenceLevel() => PRIMARY;
841 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698