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

Unified 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 side-by-side diff with in-line comments
Download patch
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;
+}

Powered by Google App Engine
This is Rietveld 408576698