Chromium Code Reviews| OLD | NEW |
|---|---|
| (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 } | |
| OLD | NEW |