Chromium Code Reviews| Index: lib/compiler/implementation/js/nodes.dart |
| diff --git a/lib/compiler/implementation/js/nodes.dart b/lib/compiler/implementation/js/nodes.dart |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..8ad951e0e51c1c102784399b257e6db4f312229d |
| --- /dev/null |
| +++ b/lib/compiler/implementation/js/nodes.dart |
| @@ -0,0 +1,841 @@ |
| +// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| +// for details. All rights reserved. Use of this source code is governed by a |
| +// BSD-style license that can be found in the LICENSE file. |
| + |
| +interface NodeVisitor<T> { |
| + T visitProgram(Program program); |
| + |
| + T visitBlock(Block block); |
| + T visitExpressionStatement(ExpressionStatement expressionStatement); |
| + T visitNOP(NOP nop); |
| + T visitIf(If node); |
| + T visitFor(For loop); |
| + T visitForIn(ForIn loop); |
| + T visitWhile(While loop); |
| + T visitDo(Do loop); |
| + T visitContinue(Continue cont); |
| + T visitBreak(Break node); |
| + T visitReturn(Return node); |
| + T visitThrow(Throw node); |
| + T visitTry(Try node); |
| + T visitCatch(Catch node); |
| + T visitWith(With node); |
| + T visitSwitch(Switch node); |
| + T visitCase(Case node); |
| + T visitDefault(Default node); |
| + T visitFunctionDeclaration(FunctionDeclaration declaration); |
| + T visitLabeled(Labeled node); |
| + T visitStatementBlob(StatementBlob node); |
| + |
| + T visitExpressionBlob(ExpressionBlob blob); |
|
Lasse Reichstein Nielsen
2012/08/08 11:16:38
LiteralExpression.
floitsch
2012/08/09 16:24:07
Done.
|
| + T visitVariableDeclarationList(VariableDeclarationList list); |
| + T visitSequence(Sequence sequence); |
| + 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.
|
| + T visitInit(Init init); |
|
Lasse Reichstein Nielsen
2012/08/08 11:16:38
Initialize? Initializer? Initialization?
|
| + T visitAccsign(Accsign accsign); |
|
Lasse Reichstein Nielsen
2012/08/08 11:16:38
Wut?
|
| + T visitVassignOp(VassignOp vassignOp); |
|
Lasse Reichstein Nielsen
2012/08/08 11:16:38
VariableAssignOperation? Operator?
|
| + T visitAccsignOp(AccsignOp accsignOp); |
| + T visitConditional(Conditional cond); |
| + T visitNew(New node); |
| + T visitCall(Call call); |
| + 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
|
| + T visitUnary(Unary unary); |
| + T visitPostfix(Postfix postfix); |
| + |
| + T visitRef(Ref ref); |
|
Lasse Reichstein Nielsen
2012/08/08 11:16:38
Wut?
|
| + T visitThis(This node); |
| + T visitDecl(Decl decl); |
|
Lasse Reichstein Nielsen
2012/08/08 11:16:38
Declaration.
|
| + T visitParam(Param param); |
|
Lasse Reichstein Nielsen
2012/08/08 11:16:38
Parameter ... you get the idea. Don't abbreviate n
|
| + T visitAccess(Access access); |
|
Lasse Reichstein Nielsen
2012/08/08 11:16:38
What is an "Access"? Better name?
|
| + |
| + T visitNamedFunction(NamedFunction namedFunction); |
| + T visitFun(Fun fun); |
| + |
| + 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.
|
| + T visitStringLiteral(StringLiteral node); |
| + T visitNumberLiteral(NumberLiteral node); |
| + T visitNullLiteral(NullLiteral node); |
| + |
| + T visitArrayLiteral(ArrayLiteral node); |
| + 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
|
| + T visitObjectLiteral(ObjectLiteral node); |
| + T visitPropertyInit(PropertyInit node); |
| + T visitRegExpLiteral(RegExpLiteral node); |
| +} |
| + |
| +class BaseVisitor<T> implements NodeVisitor { |
| + T visitNode(Node node) { |
| + node.visitChildren(this); |
| + return null; |
| + } |
| + |
| + T visitProgram(Program node) => visitNode(node); |
| + |
| + T visitStatement(Statement node) => visitNode(node); |
| + T visitLoop(Loop node) => visitStatement(node); |
| + T visitInterruption(Statement node) => visitStatement(node); |
| + |
| + T visitBlock(Block node) => visitStatement(node); |
| + T visitExpressionStatement(ExpressionStatement node) |
| + => visitStatement(node); |
| + T visitNOP(NOP node) => visitStatement(node); |
| + T visitIf(If node) => visitStatement(node); |
| + T visitFor(For node) => visitLoop(node); |
| + T visitForIn(ForIn node) => visitLoop(node); |
| + T visitWhile(While node) => visitLoop(node); |
| + T visitDo(Do node) => visitLoop(node); |
| + 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.
|
| + T visitBreak(Break node) => visitInterruption(node); |
| + T visitReturn(Return node) => visitInterruption(node); |
| + T visitThrow(Throw node) => visitInterruption(node); |
| + T visitTry(Try node) => visitStatement(node); |
| + T visitWith(With node) => visitStatement(node); |
| + T visitSwitch(Switch node) => visitStatement(node); |
| + T visitFunctionDeclaration(FunctionDeclaration node) |
| + => visitStatement(node); |
| + T visitLabeled(Labeled node) => visitStatement(node); |
| + T visitStatementBlob(StatementBlob node) => visitStatement(node); |
| + |
| + T visitCatch(Catch node) => visitNode(node); |
| + T visitCase(Case node) => visitNode(node); |
| + T visitDefault(Default node) => visitNode(node); |
| + |
| + T visitExpression(Expression node) => visitNode(node); |
| + T visitAssign(Assign node) => visitExpression(node); |
| + |
| + T visitExpressionBlob(ExpressionBlob node) => visitExpression(node); |
| + T visitVariableDeclarationList(VariableDeclarationList node) |
| + => visitExpression(node); |
| + T visitSequence(Sequence node) => visitExpression(node); |
| + T visitVassign(Vassign node) => visitAssign(node); |
| + T visitInit(Init node) { |
| + if (node.value != null) { |
| + visitAssign(node); |
| + } else { |
| + visitExpression(node); |
| + } |
| + } |
| + T visitAccsign(Accsign node) => visitAssign(node); |
| + T visitVassignOp(VassignOp node) => visitVassign(node); |
| + T visitAccsignOp(AccsignOp node) => visitAccsign(node); |
| + T visitConditional(Conditional node) => visitExpression(node); |
| + T visitNew(New node) => visitExpression(node); |
| + T visitCall(Call node) => visitExpression(node); |
| + T visitBinary(Binary node) => visitCall(node); |
| + T visitUnary(Unary node) => visitCall(node); |
| + T visitPostfix(Postfix node) => visitCall(node); |
| + T visitAccess(Access node) => visitExpression(node); |
| + |
| + T visitRef(Ref node) => visitExpression(node); |
| + T visitDecl(Decl node) => visitRef(node); |
| + T visitParam(Param node) => visitDecl(node); |
| + T visitThis(This node) => visitParam(node); |
| + |
| + T visitNamedFunction(NamedFunction node) => visitExpression(node); |
| + T visitFun(Fun node) => visitExpression(node); |
| + |
| + T visitLiteral(Literal node) => visitExpression(node); |
| + |
| + T visitBoolLiteral(BoolLiteral node) => visitLiteral(node); |
| + T visitStringLiteral(StringLiteral node) => visitLiteral(node); |
| + T visitNumberLiteral(NumberLiteral node) => visitLiteral(node); |
| + T visitNullLiteral(NullLiteral node) => visitLiteral(node); |
| + |
| + T visitArrayLiteral(ArrayLiteral node) => visitExpression(node); |
| + T visitArrayElement(ArrayElement node) => visitNode(node); |
| + T visitObjectLiteral(ObjectLiteral node) => visitExpression(node); |
| + T visitPropertyInit(PropertyInit node) => visitNode(node); |
| + T visitRegExpLiteral(RegExpLiteral node) => visitExpression(node); |
| +} |
| + |
| +class Node implements Hashable { |
| + // I don't really like static state, but the alternatives seem even more |
| + // annoying. |
| + static int nodeCounter = 0; |
| + |
| + final int nodeId; |
| + 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
|
| + Dynamic endSourcePosition; |
| + |
| + Node() : nodeId = nodeCounter++ & 0x7FFFFFFF; |
| + |
| + abstract accept(NodeVisitor visitor); |
| + abstract void visitChildren(NodeVisitor visitor); |
| + int hashCode() => nodeId; |
| +} |
| + |
| +class Program extends Node { |
| + List<Statement> body; |
| + Program(this.body); |
| + |
| + accept(NodeVisitor visitor) => visitor.visitProgram(this); |
| + void visitChildren(NodeVisitor visitor) { |
| + for (Statement statement in body) statement.accept(visitor); |
| + } |
| +} |
| + |
| +abstract class Statement extends Node { |
| +} |
| + |
| +class Block extends Statement { |
| + List<Statement> elements; |
|
Lasse Reichstein Nielsen
2012/08/08 11:16:38
elements -> statements?
floitsch
2012/08/09 16:24:07
Done.
|
| + Block(this.elements); |
| + Block.empty() : this.elements = <Statement>[]; |
| + |
| + accept(NodeVisitor visitor) => visitor.visitBlock(this); |
| + void visitChildren(NodeVisitor visitor) { |
| + for (Statement statement in elements) statement.accept(visitor); |
| + } |
| +} |
| + |
| +class ExpressionStatement extends Statement { |
| + Expression expr; |
|
Lasse Reichstein Nielsen
2012/08/08 11:16:38
Don't abbreviate.
floitsch
2012/08/09 16:24:07
Done.
|
| + ExpressionStatement(this.expr); |
| + |
| + accept(NodeVisitor visitor) => visitor.visitExpressionStatement(this); |
| + void visitChildren(NodeVisitor visitor) { expr.accept(visitor); } |
| +} |
| + |
| +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.
|
| + NOP(); |
| + |
| + accept(NodeVisitor visitor) => visitor.visitNOP(this); |
| + void visitChildren(NodeVisitor visitor) {} |
| +} |
| + |
| +class If extends Statement { |
| + Node test; |
|
Lasse Reichstein Nielsen
2012/08/08 11:16:38
"Expression test;" ?
floitsch
2012/08/09 16:24:07
Done.
|
| + Node then; |
| + Node otherwise; |
| + If(this.test, this.then, this.otherwise); |
| + 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
|
| + bool get hasElse() => otherwise is !NOP; |
| + |
| + accept(NodeVisitor visitor) => visitor.visitIf(this); |
| + void visitChildren(NodeVisitor visitor) { |
| + test.accept(visitor); |
| + then.accept(visitor); |
| + otherwise.accept(visitor); |
| + } |
| +} |
| + |
| +abstract class Loop extends Statement { |
| + Statement body; |
| + Loop(this.body); |
| +} |
| + |
| +class For extends Loop { |
| + Expression init; |
| + Expression test; |
|
kasperl
2012/08/07 07:46:45
test -> condition?
floitsch
2012/08/09 16:24:07
Done.
|
| + 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.
|
| + For(this.init, this.test, this.incr, Statement body) : super(body); |
| + |
| + accept(NodeVisitor visitor) => visitor.visitFor(this); |
| + void visitChildren(NodeVisitor visitor) { |
| + if (init !== null) init.accept(visitor); |
| + if (test !== null) test.accept(visitor); |
| + if (incr !== null) incr.accept(visitor); |
| + body.accept(visitor); |
| + } |
| +} |
| + |
| +class ForIn extends Loop { |
| + 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.
|
| + Expression obj; |
| + ForIn(this.lhs, this.obj, Statement body) : super(body); |
| + |
| + accept(NodeVisitor visitor) => visitor.visitForIn(this); |
| + void visitChildren(NodeVisitor visitor) { |
| + lhs.accept(visitor); |
| + obj.accept(visitor); |
| + body.accept(visitor); |
| + } |
| +} |
| + |
| +class While extends Loop { |
| + Node test; |
| + While(this.test, Statement body) : super(body); |
| + |
| + accept(NodeVisitor visitor) => visitor.visitWhile(this); |
| + void visitChildren(NodeVisitor visitor) { |
| + test.accept(visitor); |
| + body.accept(visitor); |
| + } |
| +} |
| + |
| +class Do extends Loop { |
| + Node test; |
| + Do(Statement body, this.test) : super(body); |
| + |
| + accept(NodeVisitor visitor) => visitor.visitDo(this); |
| + void visitChildren(NodeVisitor visitor) { |
| + body.accept(visitor); |
| + test.accept(visitor); |
| + } |
| +} |
| + |
| +class Continue extends Statement { |
| + 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.
|
| + Continue(this.id); |
| + |
| + accept(NodeVisitor visitor) => visitor.visitContinue(this); |
| + void visitChildren(NodeVisitor visitor) {} |
| +} |
| + |
| +class Break extends Statement { |
| + String id; // Can be null. |
| + Break(this.id); |
| + |
| + accept(NodeVisitor visitor) => visitor.visitBreak(this); |
| + void visitChildren(NodeVisitor visitor) {} |
| +} |
| + |
| +class Return extends Statement { |
| + Expression expr; // Can be null. |
| + Return(this.expr); |
|
Lasse Reichstein Nielsen
2012/08/08 11:16:38
make this.expr optional.
floitsch
2012/08/09 16:24:07
Done.
|
| + |
| + accept(NodeVisitor visitor) => visitor.visitReturn(this); |
| + void visitChildren(NodeVisitor visitor) { |
| + 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.
|
| + } |
| +} |
| + |
| +class Throw extends Statement { |
| + Expression expr; |
| + Throw(this.expr); |
| + |
| + accept(NodeVisitor visitor) => visitor.visitThrow(this); |
| + void visitChildren(NodeVisitor visitor) { |
| + expr.accept(visitor); |
| + } |
| +} |
| + |
| +class Try extends Statement { |
| + Block body; |
| + Catch catchPart; |
| + 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.
|
| + Try(this.body, this.catchPart, this.finallyPart); |
| + |
| + accept(NodeVisitor visitor) => visitor.visitTry(this); |
| + void visitChildren(NodeVisitor visitor) { |
| + body.accept(visitor); |
| + if (catchPart !== null) catchPart.accept(visitor); |
| + if (finallyPart !== null) finallyPart.accept(visitor); |
| + } |
| +} |
| + |
| +class Catch extends Node { |
| + Decl decl; |
| + Block body; |
| + Catch(this.decl, this.body); |
| + |
| + accept(NodeVisitor visitor) => visitor.visitCatch(this); |
| + void visitChildren(NodeVisitor visitor) { |
| + decl.accept(visitor); |
| + body.accept(visitor); |
| + } |
| +} |
| + |
| +class With extends Statement { |
|
kasperl
2012/08/07 07:46:45
Do we need this?
floitsch
2012/08/09 16:24:07
Done.
|
| + Expression object; |
| + Statement body; |
| + With(this.object, this.body); |
| + |
| + accept(NodeVisitor visitor) => visitor.visitWith(this); |
| + void visitChildren(NodeVisitor visitor) { |
| + object.accept(visitor); |
| + body.accept(visitor); |
| + } |
| +} |
| + |
| +class Switch extends Statement { |
| + Expression key; |
| + List<SwitchClause> cases; |
| + Switch(this.key, this.cases); |
| + |
| + accept(NodeVisitor visitor) => visitor.visitSwitch(this); |
| + void visitChildren(NodeVisitor visitor) { |
| + key.accept(visitor); |
| + for (SwitchClause clause in cases) clause.accept(visitor); |
| + } |
| +} |
| + |
| +abstract class SwitchClause extends Node { |
| + Block body; |
| + SwitchClause(this.body); |
| +} |
| + |
| +class Case extends SwitchClause { |
| + Expression expr; |
| + Case(this.expr, Block body) : super(body); |
| + |
| + accept(NodeVisitor visitor) => visitor.visitCase(this); |
| + void visitChildren(NodeVisitor visitor) { |
| + expr.accept(visitor); |
| + body.accept(visitor); |
| + } |
| +} |
| + |
| +class Default extends SwitchClause { |
| + Default(Block body) : super(body); |
| + |
| + accept(NodeVisitor visitor) => visitor.visitDefault(this); |
| + void visitChildren(NodeVisitor visitor) { |
| + body.accept(visitor); |
| + } |
| +} |
| + |
| +class FunctionDeclaration extends Statement { |
| + Decl id; |
| + Fun fun; |
| + FunctionDeclaration(this.id, this.fun); |
| + |
| + accept(NodeVisitor visitor) => visitor.visitFunctionDeclaration(this); |
| + void visitChildren(NodeVisitor visitor) { |
| + id.accept(visitor); |
| + fun.accept(visitor); |
| + } |
| +} |
| + |
| +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.
|
| + String id; |
|
Lasse Reichstein Nielsen
2012/08/08 11:16:38
id -> label.
floitsch
2012/08/09 16:24:07
Done.
|
| + Statement body; |
| + Labeled(this.id, this.body); |
| + |
| + accept(NodeVisitor visitor) => visitor.visitLabeled(this); |
| + void visitChildren(NodeVisitor visitor) { |
| + body.accept(visitor); |
| + } |
| +} |
| + |
| +class StatementBlob extends Statement { |
| + String blob; |
| + StatementBlob(this.blob); |
| + |
| + accept(NodeVisitor visitor) => visitor.visitStatementBlob(this); |
| + void visitChildren(NodeVisitor visitor) { } |
| +} |
| + |
| +abstract class Expression extends Node { |
| + abstract int get precedenceLevel(); |
| +} |
| + |
| +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.
|
| + String blob; |
| + List<Expression> data; |
| + ExpressionBlob(this.blob); |
| + ExpressionBlob.withData(this.blob, this.data); |
| + |
| + accept(NodeVisitor visitor) => visitor.visitExpressionBlob(this); |
| + void visitChildren(NodeVisitor visitor) { |
| + for (Expression expr in data) expr.accept(visitor); |
| + } |
| + |
| + 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
|
| +} |
| + |
| +class VariableDeclarationList extends Expression { |
| + List<Init> declarations; |
| + VariableDeclarationList(this.declarations); |
| + |
| + accept(NodeVisitor visitor) => visitor.visitVariableDeclarationList(this); |
| + void visitChildren(NodeVisitor visitor) { |
| + for (Init init in declarations) init.accept(visitor); |
| + } |
| + |
| + int get precedenceLevel() => EXPRESSION; |
| +} |
| + |
| +class Sequence extends Expression { |
| + List<Expression> expressions; |
| + Sequence(this.expressions); |
| + |
| + accept(NodeVisitor visitor) => visitor.visitSequence(this); |
| + void visitChildren(NodeVisitor visitor) { |
| + for (Expression expr in expressions) expr.accept(visitor); |
| + } |
| + |
| + int get precedenceLevel() => EXPRESSION; |
| +} |
| + |
| +class Assign extends Expression { |
| + 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.
|
| + Expression value; // May be null, for [Init]s. |
| + Assign(this.value); |
| + |
| + int get precedenceLevel() => ASSIGNMENT; |
| +} |
| + |
| +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.
|
| + Ref lhs; |
| + Vassign(this.lhs, Expression value): super(value); |
| + |
| + accept(NodeVisitor visitor) => visitor.visitVassign(this); |
| + void visitChildren(NodeVisitor visitor) { |
| + lhs.accept(visitor); |
| + value.accept(visitor); |
| + } |
| +} |
| + |
| +class Init extends Vassign { |
| + /** [value] may be null. */ |
| + Init(Decl decl, Expression value) : super(decl, value); |
| + |
| + Ref get decl() => lhs; |
| + |
| + accept(NodeVisitor visitor) => visitor.visitInit(this); |
| + void visitChildren(NodeVisitor visitor) { |
| + decl.accept(visitor); |
| + if (value !== null) value.accept(visitor); |
| + } |
| +} |
| + |
| +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
|
| + Ref target; |
| + VassignOp(Ref lhs, String op, Expression value) |
| + : target = new Ref(op), super(lhs, value); |
| + |
| + String get op() => target.id; |
| + |
| + accept(NodeVisitor visitor) => visitor.visitVassignOp(this); |
| + void visitChildren(NodeVisitor visitor) { |
| + lhs.accept(visitor); |
| + target.accept(visitor); |
| + value.accept(visitor); |
| + } |
| +} |
| + |
| +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.
|
| + Access lhs; |
| + Accsign(this.lhs, Expression value): super(value); |
| + |
| + accept(NodeVisitor visitor) => visitor.visitAccsign(this); |
| + void visitChildren(NodeVisitor visitor) { |
| + lhs.accept(visitor); |
| + value.accept(visitor); |
| + } |
| +} |
| + |
| +class AccsignOp extends Accsign { |
| + Ref target; |
| + AccsignOp(Access lhs, String op, Expression value) |
| + : target = new Ref(op), super(lhs, value); |
| + |
| + String get op() => target.id; |
| + |
| + accept(NodeVisitor visitor) => visitor.visitAccsignOp(this); |
| + void visitChildren(NodeVisitor visitor) { |
| + lhs.accept(visitor); |
| + target.accept(visitor); |
| + value.accept(visitor); |
| + } |
| +} |
| + |
| +class Conditional extends Expression { |
| + Expression test; |
| + Expression then; |
| + Expression otherwise; |
| + Conditional(this.test, this.then, this.otherwise); |
| + |
| + accept(NodeVisitor visitor) => visitor.visitConditional(this); |
| + void visitChildren(NodeVisitor visitor) { |
| + test.accept(visitor); |
| + then.accept(visitor); |
| + otherwise.accept(visitor); |
| + } |
| + |
| + int get precedenceLevel() => ASSIGNMENT; |
| +} |
| + |
| +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.
|
| + Expression cls; |
| + List<Expression> arguments; |
| + New(this.cls, this.arguments); |
| + |
| + accept(NodeVisitor visitor) => visitor.visitNew(this); |
| + void visitChildren(NodeVisitor visitor) { |
| + cls.accept(visitor); |
| + for (Expression arg in arguments) arg.accept(visitor); |
| + } |
| + |
| + int get precedenceLevel() => CALL; |
| +} |
| + |
| +class Call extends Expression { |
| + Expression target; |
| + List<Expression> arguments; |
| + Call(this.target, this.arguments); |
| + |
| + accept(NodeVisitor visitor) => visitor.visitCall(this); |
| + void visitChildren(NodeVisitor visitor) { |
| + target.accept(visitor); |
| + for (Expression arg in arguments) arg.accept(visitor); |
| + } |
| + |
| + int get precedenceLevel() => CALL; |
| +} |
| + |
| +class Binary extends Call { |
| + Binary(String op, Expression left, Expression right) |
| + : 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
|
| + |
| + String get op() { |
| + return (target as Ref).id; |
| + } |
| + Expression get left() => arguments[0]; |
| + Expression get right() => arguments[1]; |
| + |
| + accept(NodeVisitor visitor) => visitor.visitBinary(this); |
| + // Inherit visitChildren from [Call]. |
| + |
| + int get precedenceLevel() { |
| + switch (op) { |
| + case "*": |
| + case "/": |
| + case "%": |
| + return MULTIPLICATIVE; |
| + case "+": |
| + case "-": |
| + return ADDITIVE; |
| + case "<<": |
| + case ">>": |
| + case ">>>": |
| + return SHIFT; |
| + case "<": |
| + case ">": |
| + case "<=": |
| + case ">=": |
| + case "instanceof": |
| + case "in": |
| + return RELATIONAL; |
| + case "==": |
| + case "===": |
| + case "!=": |
| + case "!==": |
| + return EQUALITY; |
| + case "&": |
| + return BIT_AND; |
| + case "^": |
| + return BIT_XOR; |
| + case "|": |
| + return BIT_OR; |
| + case "&&": |
| + return LOGICAL_AND; |
| + case "||": |
| + return LOGICAL_OR; |
| + default: |
| + throw new CompilerCancelledException( |
| + "Internal Error: Unhandled binary operator: $op"); |
| + } |
| + } |
| +} |
| + |
| +class Unary extends Call { |
| + 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.
|
| + |
| + String get op() { |
| + return (target as Ref).id; |
| + } |
| + Expression get arg() => arguments[0]; |
| + |
| + accept(NodeVisitor visitor) => visitor.visitUnary(this); |
| + // Inherit visitChildren from [Call]. |
| + |
| + int get precedenceLevel() => UNARY; |
| +} |
| + |
| +class Postfix extends Call { |
| + Postfix(String op, Expression arg) : super(new Ref(op), <Expression>[arg]); |
| + |
| + String get op() { |
| + return (target as Ref).id; |
| + } |
| + Expression get arg() => arguments[0]; |
| + |
| + accept(NodeVisitor visitor) => visitor.visitPostfix(this); |
| + // Inherit visitChildren from [Call]. |
| + |
| + int get precedenceLevel() => UNARY; |
| +} |
| + |
| +class Ref extends Expression { |
| + final String id; |
| + final bool isOperator = false; |
| + final bool isUnaryOperator = false; |
| + |
| + Ref(this.id); |
| + Ref.operator(this.id) : isOperator = true; |
| + Ref.unaryOperator(this.id) : isOperator = true, isUnaryOperator = true; |
| + |
| + accept(NodeVisitor visitor) => visitor.visitRef(this); |
| + void visitChildren(NodeVisitor visitor) {} |
| + |
| + int get precedenceLevel() => PRIMARY; |
| +} |
| + |
| +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.
|
| + Decl(String id) : super(id); |
| + |
| + accept(NodeVisitor visitor) => visitor.visitDecl(this); |
| + // Inherit visitChildren from [Ref]. |
| +} |
| + |
| +class Param extends Decl { |
| + Param(String id) : super(id); |
| + |
| + accept(NodeVisitor visitor) => visitor.visitParam(this); |
| + // Inherit visitChildren from [Ref]. |
| +} |
| + |
| +class This extends Param { |
| + This() : super("this"); |
|
Lasse Reichstein Nielsen
2012/08/08 11:16:38
Clever.
|
| + |
| + accept(NodeVisitor visitor) => visitor.visitThis(this); |
| + // Inherit visitChildren from [Ref]. |
| +} |
| + |
| +class NamedFunction extends Expression { |
| + Decl id; |
| + Fun fun; |
| + NamedFunction(this.id, this.fun); |
| + |
| + accept(NodeVisitor visitor) => visitor.visitNamedFunction(this); |
| + void visitChildren(NodeVisitor visitor) { |
| + id.accept(visitor); |
| + fun.accept(visitor); |
| + } |
| + |
| + int get precedenceLevel() => CALL; |
| +} |
| + |
| +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.
|
| + List<Param> params; |
| + Block body; |
| + Fun(this.params, this.body); |
| + |
| + accept(NodeVisitor visitor) => visitor.visitFun(this); |
| + void visitChildren(NodeVisitor visitor) { |
| + for (Param param in params) param.accept(visitor); |
| + body.accept(visitor); |
| + } |
| + |
| + int get precedenceLevel() => CALL; |
| +} |
| + |
| +class Access extends Expression { |
| + Expression receiver; |
| + Expression selector; |
| + Access(this.receiver, this.selector); |
| + Access.field(this.receiver, String fieldName) |
| + : selector = new StringLiteral("'$fieldName'"); |
| + |
| + accept(NodeVisitor visitor) => visitor.visitAccess(this); |
| + void visitChildren(NodeVisitor visitor) { |
| + receiver.accept(visitor); |
| + selector.accept(visitor); |
| + } |
| + |
| + int get precedenceLevel() => CALL; |
| +} |
| + |
| +abstract class Literal extends Expression { |
| + void visitChildren(NodeVisitor visitor) {} |
| + |
| + int get precedenceLevel() => PRIMARY; |
| +} |
| + |
| +class BoolLiteral extends Literal { |
| + final bool value; |
| + BoolLiteral(this.value); |
| + |
| + accept(NodeVisitor visitor) => visitor.visitBoolLiteral(this); |
| + // [visitChildren] inherited from [Literal]. |
| +} |
| + |
| +class NullLiteral extends Literal { |
| + NullLiteral(); |
| + |
| + accept(NodeVisitor visitor) => visitor.visitNullLiteral(this); |
| + // [visitChildren] inherited from [Literal]. |
| +} |
| + |
| +class StringLiteral extends Literal { |
| + final String value; |
| + StringLiteral(this.value); |
| + |
| + accept(NodeVisitor visitor) => visitor.visitStringLiteral(this); |
| + // [visitChildren] inherited from [Literal]. |
| +} |
| + |
| +class NumberLiteral extends Literal { |
| + final String value; |
| + NumberLiteral(this.value); |
| + |
| + accept(NodeVisitor visitor) => visitor.visitNumberLiteral(this); |
| + // [visitChildren] inherited from [Literal]. |
| +} |
| + |
| +// Despite being called "Literal" the [ArrayLiteral] does not inherit from |
| +// [Literal]. |
|
Lasse Reichstein Nielsen
2012/08/08 11:16:38
Why not?
floitsch
2012/08/09 16:24:07
Changed name to ArrayInitialization.
|
| +class ArrayLiteral extends Expression { |
| + int length; |
| + List<ArrayElement> elements; |
| + ArrayLiteral(this.length, this.elements); |
| + |
| + accept(NodeVisitor visitor) => visitor.visitArrayLiteral(this); |
| + void visitChildren(NodeVisitor visitor) { |
| + for (ArrayElement element in elements) element.accept(visitor); |
| + } |
| + |
| + int get precedenceLevel() => PRIMARY; |
| +} |
| + |
| +class ArrayElement extends Node { |
| + 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
|
| + Expression value; |
| + ArrayElement(this.index, this.value); |
| + |
| + accept(NodeVisitor visitor) => visitor.visitArrayElement(this); |
| + void visitChildren(NodeVisitor visitor) { |
| + value.accept(visitor); |
| + } |
| +} |
| + |
| +// Despite being called "Literal" the [ObjectLiteral] does not inherit from |
| +// [Literal]. |
| +class ObjectLiteral extends Expression { |
| + 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.
|
| + ObjectLiteral(this.properties); |
| + |
| + accept(NodeVisitor visitor) => visitor.visitObjectLiteral(this); |
| + void visitChildren(NodeVisitor visitor) { |
| + for (PropertyInit init in properties) init.accept(visitor); |
| + } |
| + |
| + int get precedenceLevel() => PRIMARY; |
| +} |
| + |
| +class PropertyInit extends Node { |
| + Literal name; |
| + Expression value; |
| + PropertyInit(this.name, this.value); |
| + |
| + accept(NodeVisitor visitor) => visitor.visitPropertyInit(this); |
| + void visitChildren(NodeVisitor visitor) { |
| + name.accept(visitor); |
| + value.accept(visitor); |
| + } |
| +} |
| + |
| +// Despite being called "Literal" the [RegExpLiteral] does not inherit from |
| +// [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-
|
| +class RegExpLiteral extends Expression { |
| + /** Contains the pattern and the flags.*/ |
| + String pattern; |
| + RegExpLiteral(this.pattern); |
| + |
| + accept(NodeVisitor visitor) => visitor.visitRegExpLiteral(this); |
| + void visitChildren(NodeVisitor visitor) {} |
| + |
| + int get precedenceLevel() => PRIMARY; |
| +} |