Chromium Code Reviews| Index: sdk/lib/_internal/compiler/implementation/dart_backend/dart_tree.dart |
| diff --git a/sdk/lib/_internal/compiler/implementation/dart_backend/dart_tree.dart b/sdk/lib/_internal/compiler/implementation/dart_backend/dart_tree.dart |
| index dcaf7e96cc29f6238ccdad8799335290f3bf3981..32884864d076ca0d8626624052229605089ab27e 100644 |
| --- a/sdk/lib/_internal/compiler/implementation/dart_backend/dart_tree.dart |
| +++ b/sdk/lib/_internal/compiler/implementation/dart_backend/dart_tree.dart |
| @@ -65,6 +65,22 @@ class Variable extends Expression { |
| } |
| /** |
| + * A sequence of expressions. |
| + * |
| + * The value of the sequence is the value of the last expression. All but |
|
Kevin Millikin (Google)
2014/04/03 12:00:56
I'm going to remove this comment about the semanti
|
| + * the last are evaluated for their effect. |
| + */ |
| +class Sequence extends Expression { |
| + final List<Expression> expressions; |
| + |
| + Sequence(this.expressions); |
| + |
| + bool get isPure => expressions.every((e) => e.isPure); |
|
floitsch
2014/04/03 12:31:16
Probably not an issue yet, but should we cache it?
|
| + |
| + accept(Visitor visitor) => visitor.visitSequence(this); |
| +} |
| + |
| +/** |
| * A local binding of a [Variable] to an [Expression]. |
| * |
| * In contrast to the CPS-based IR, non-primitive expressions can be named |
| @@ -134,6 +150,7 @@ abstract class Visitor<T> { |
| // Concrete classes. |
| T visitVariable(Variable node) => visitExpression(node); |
| + T visitSequence(Sequence node) => visitExpression(node); |
| T visitLetVal(LetVal node) => visitExpression(node); |
| T visitInvokeStatic(InvokeStatic node) => visitExpression(node); |
| T visitReturn(Return node) => visitExpression(node); |
| @@ -197,10 +214,14 @@ class Builder extends ir.Visitor<Expression> { |
| Expression visitLetPrim(ir.LetPrim node) { |
| // LetPrim is translated to LetVal. |
| - Variable variable = new Variable(); |
| Expression definition = node.primitive.accept(this); |
| - variables[node.primitive] = variable; |
| - return new LetVal(variable, definition, node.body.accept(this)); |
| + if (node.primitive.hasAtLeastOneUse) { |
|
floitsch
2014/04/03 12:31:16
Should we create a helper function?
The code here
|
| + Variable variable = new Variable(); |
| + variables[node.primitive] = variable; |
| + return new LetVal(variable, definition, node.body.accept(this)); |
| + } else { |
| + return new Sequence([definition, node.body.accept(this)]); |
| + } |
| } |
| Expression visitLetCont(ir.LetCont node) { |
| @@ -220,9 +241,13 @@ class Builder extends ir.Visitor<Expression> { |
| return new Return(invoke); |
| } else { |
| assert(cont.hasExactlyOneUse); |
| - Variable variable = new Variable(); |
| - variables[cont.parameter] = variable; |
| - return new LetVal(variable, invoke, cont.body.accept(this)); |
| + if (cont.parameter.hasAtLeastOneUse) { |
| + Variable variable = new Variable(); |
| + variables[cont.parameter] = variable; |
| + return new LetVal(variable, invoke, cont.body.accept(this)); |
| + } else { |
| + return new Sequence([invoke, cont.body.accept(this)]); |
| + } |
| } |
| } |
| @@ -320,6 +345,13 @@ class Unnamer extends Visitor<Expression> { |
| return node; |
| } |
| + Expression visitSequence(Sequence node) { |
| + for (int i = 0; i < node.expressions.length; ++i) { |
| + node.expressions[i] = node.expressions[i].accept(this); |
| + } |
| + return node; |
| + } |
| + |
| Expression visitLetVal(LetVal node) { |
| environment.add(node); |
| Expression body = node.body.accept(this); |
| @@ -479,6 +511,12 @@ class Emitter extends Visitor<ast.Node> { |
| semicolon, |
| value); |
| } |
| + } else if (body is ast.Block) { |
| + // Remove a final 'return null' that ends the body block. |
| + List<ast.Node> statements = |
| + (body as ast.Block).statements.nodes.toList(); |
| + statements.removeLast(); |
|
floitsch
2014/04/03 12:31:16
assert that it's a Return null.
Kevin Millikin (Google)
2014/04/03 12:52:46
Ack, that's just a bug. Thanks for catching it.
|
| + body = makeBlock(statements); |
| } |
| return new ast.FunctionExpression(name, parameters, body, returnType, |
| @@ -534,6 +572,10 @@ class Emitter extends Visitor<ast.Node> { |
| return new ast.Send(null, node.identifier); |
| } |
| + ast.Node visitSequence(Sequence node) { |
| + return node.expressions.map((e) => e.accept(this)).reduce(concatenate); |
| + } |
| + |
| ast.Node visitLetVal(LetVal node) { |
| // Let bindings translate into assignments. |
| ast.Identifier identifier = node.variable.assignIdentifier(); |