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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/dart_backend/dart_tree.dart

Issue 223783002: Support ExpressionStatement in the dart2dart backend. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | sdk/lib/_internal/compiler/implementation/ir/ir_builder.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library dart_tree; 5 library dart_tree;
6 6
7 import '../dart2jslib.dart' as dart2js; 7 import '../dart2jslib.dart' as dart2js;
8 import '../dart_types.dart'; 8 import '../dart_types.dart';
9 import '../util/util.dart'; 9 import '../util/util.dart';
10 import '../elements/elements.dart' show FunctionElement, FunctionSignature; 10 import '../elements/elements.dart' show FunctionElement, FunctionSignature;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 identifier = Emitter.makeIdentifier(name); 58 identifier = Emitter.makeIdentifier(name);
59 return identifier; 59 return identifier;
60 } 60 }
61 61
62 final bool isPure = true; 62 final bool isPure = true;
63 63
64 accept(Visitor visitor) => visitor.visitVariable(this); 64 accept(Visitor visitor) => visitor.visitVariable(this);
65 } 65 }
66 66
67 /** 67 /**
68 * A sequence of expressions.
69 *
70 * 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
71 * the last are evaluated for their effect.
72 */
73 class Sequence extends Expression {
74 final List<Expression> expressions;
75
76 Sequence(this.expressions);
77
78 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?
79
80 accept(Visitor visitor) => visitor.visitSequence(this);
81 }
82
83 /**
68 * A local binding of a [Variable] to an [Expression]. 84 * A local binding of a [Variable] to an [Expression].
69 * 85 *
70 * In contrast to the CPS-based IR, non-primitive expressions can be named 86 * In contrast to the CPS-based IR, non-primitive expressions can be named
71 * with let. 87 * with let.
72 */ 88 */
73 class LetVal extends Expression { 89 class LetVal extends Expression {
74 final Variable variable; 90 final Variable variable;
75 final Expression definition; 91 final Expression definition;
76 final Expression body; 92 final Expression body;
77 93
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 accept(Visitor visitor) => visitor.visitConstant(this); 143 accept(Visitor visitor) => visitor.visitConstant(this);
128 } 144 }
129 145
130 abstract class Visitor<T> { 146 abstract class Visitor<T> {
131 // Abstract classes. 147 // Abstract classes.
132 T visitNode(Node node) => node.accept(this); 148 T visitNode(Node node) => node.accept(this);
133 T visitExpression(Expression node) => visitNode(node); 149 T visitExpression(Expression node) => visitNode(node);
134 150
135 // Concrete classes. 151 // Concrete classes.
136 T visitVariable(Variable node) => visitExpression(node); 152 T visitVariable(Variable node) => visitExpression(node);
153 T visitSequence(Sequence node) => visitExpression(node);
137 T visitLetVal(LetVal node) => visitExpression(node); 154 T visitLetVal(LetVal node) => visitExpression(node);
138 T visitInvokeStatic(InvokeStatic node) => visitExpression(node); 155 T visitInvokeStatic(InvokeStatic node) => visitExpression(node);
139 T visitReturn(Return node) => visitExpression(node); 156 T visitReturn(Return node) => visitExpression(node);
140 T visitConstant(Constant node) => visitExpression(node); 157 T visitConstant(Constant node) => visitExpression(node);
141 } 158 }
142 159
143 /** 160 /**
144 * Builder translates from CPS-based IR to direct-style Tree. 161 * Builder translates from CPS-based IR to direct-style Tree.
145 * 162 *
146 * A call `Invoke(fun, cont, args)`, where cont is a singly-referenced 163 * A call `Invoke(fun, cont, args)`, where cont is a singly-referenced
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 207
191 Expression visitFunction(ir.Function node) { 208 Expression visitFunction(ir.Function node) {
192 // Functions are simplistically translated to their bodies. For now this 209 // Functions are simplistically translated to their bodies. For now this
193 // is good enough. 210 // is good enough.
194 returnContinuation = node.returnContinuation; 211 returnContinuation = node.returnContinuation;
195 return node.body.accept(this); 212 return node.body.accept(this);
196 } 213 }
197 214
198 Expression visitLetPrim(ir.LetPrim node) { 215 Expression visitLetPrim(ir.LetPrim node) {
199 // LetPrim is translated to LetVal. 216 // LetPrim is translated to LetVal.
200 Variable variable = new Variable();
201 Expression definition = node.primitive.accept(this); 217 Expression definition = node.primitive.accept(this);
202 variables[node.primitive] = variable; 218 if (node.primitive.hasAtLeastOneUse) {
floitsch 2014/04/03 12:31:16 Should we create a helper function? The code here
203 return new LetVal(variable, definition, node.body.accept(this)); 219 Variable variable = new Variable();
220 variables[node.primitive] = variable;
221 return new LetVal(variable, definition, node.body.accept(this));
222 } else {
223 return new Sequence([definition, node.body.accept(this)]);
224 }
204 } 225 }
205 226
206 Expression visitLetCont(ir.LetCont node) { 227 Expression visitLetCont(ir.LetCont node) {
207 // TODO(kmillikin): Allow continuations to have multiple uses. This could 228 // TODO(kmillikin): Allow continuations to have multiple uses. This could
208 // arise due to the representation of local control flow or due to 229 // arise due to the representation of local control flow or due to
209 // optimization. 230 // optimization.
210 assert(node.continuation.hasAtMostOneUse); 231 assert(node.continuation.hasAtMostOneUse);
211 return node.body.accept(this); 232 return node.body.accept(this);
212 } 233 }
213 234
214 Expression visitInvokeStatic(ir.InvokeStatic node) { 235 Expression visitInvokeStatic(ir.InvokeStatic node) {
215 // Calls are translated to direct style. 236 // Calls are translated to direct style.
216 List<Expression> arguments = translateArguments(node.arguments); 237 List<Expression> arguments = translateArguments(node.arguments);
217 Expression invoke = new InvokeStatic(node.target, arguments); 238 Expression invoke = new InvokeStatic(node.target, arguments);
218 ir.Continuation cont = node.continuation.definition; 239 ir.Continuation cont = node.continuation.definition;
219 if (cont == returnContinuation) { 240 if (cont == returnContinuation) {
220 return new Return(invoke); 241 return new Return(invoke);
221 } else { 242 } else {
222 assert(cont.hasExactlyOneUse); 243 assert(cont.hasExactlyOneUse);
223 Variable variable = new Variable(); 244 if (cont.parameter.hasAtLeastOneUse) {
224 variables[cont.parameter] = variable; 245 Variable variable = new Variable();
225 return new LetVal(variable, invoke, cont.body.accept(this)); 246 variables[cont.parameter] = variable;
247 return new LetVal(variable, invoke, cont.body.accept(this));
248 } else {
249 return new Sequence([invoke, cont.body.accept(this)]);
250 }
226 } 251 }
227 } 252 }
228 253
229 Expression visitInvokeContinuation(ir.InvokeContinuation node) { 254 Expression visitInvokeContinuation(ir.InvokeContinuation node) {
230 // TODO(kmillikin): Support non-return continuations. These could arise 255 // TODO(kmillikin): Support non-return continuations. These could arise
231 // due to local control flow or due to inlining or other optimization. 256 // due to local control flow or due to inlining or other optimization.
232 assert(node.continuation.definition == returnContinuation); 257 assert(node.continuation.definition == returnContinuation);
233 return new Return(variables[node.argument.definition]); 258 return new Return(variables[node.argument.definition]);
234 } 259 }
235 260
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
313 } else if (!environment[i].definition.isPure) { 338 } else if (!environment[i].definition.isPure) {
314 // Once the first impure definition is seen, impure definitions should 339 // Once the first impure definition is seen, impure definitions should
315 // no longer be propagated. Continue searching for a pure definition. 340 // no longer be propagated. Continue searching for a pure definition.
316 seenImpure = true; 341 seenImpure = true;
317 } 342 }
318 } 343 }
319 // If the definition could not be propagated, leave the variable use. 344 // If the definition could not be propagated, leave the variable use.
320 return node; 345 return node;
321 } 346 }
322 347
348 Expression visitSequence(Sequence node) {
349 for (int i = 0; i < node.expressions.length; ++i) {
350 node.expressions[i] = node.expressions[i].accept(this);
351 }
352 return node;
353 }
354
323 Expression visitLetVal(LetVal node) { 355 Expression visitLetVal(LetVal node) {
324 environment.add(node); 356 environment.add(node);
325 Expression body = node.body.accept(this); 357 Expression body = node.body.accept(this);
326 358
327 // TODO(kmillikin): Allow definitions that are not propagated. Currently, 359 // TODO(kmillikin): Allow definitions that are not propagated. Currently,
328 // the only bindings are anonymous intermediate values (which only have one 360 // the only bindings are anonymous intermediate values (which only have one
329 // use in the absence of optimizations) and they are not reordered. 361 // use in the absence of optimizations) and they are not reordered.
330 assert(!environment.contains(node)); 362 assert(!environment.contains(node));
331 return body; 363 return body;
332 } 364 }
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
472 ast.Expression value = (body as ast.Return).expression; 504 ast.Expression value = (body as ast.Return).expression;
473 if (value is ast.LiteralNull) { 505 if (value is ast.LiteralNull) {
474 // '{ return null; }' is '{}'. 506 // '{ return null; }' is '{}'.
475 body = makeBlock([]); 507 body = makeBlock([]);
476 } else { 508 } else {
477 // '{ return e; }' is '=> e;'. 509 // '{ return e; }' is '=> e;'.
478 body = new ast.Return(new SymbolToken(FUNCTION_INFO, -1), 510 body = new ast.Return(new SymbolToken(FUNCTION_INFO, -1),
479 semicolon, 511 semicolon,
480 value); 512 value);
481 } 513 }
514 } else if (body is ast.Block) {
515 // Remove a final 'return null' that ends the body block.
516 List<ast.Node> statements =
517 (body as ast.Block).statements.nodes.toList();
518 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.
519 body = makeBlock(statements);
482 } 520 }
483 521
484 return new ast.FunctionExpression(name, parameters, body, returnType, 522 return new ast.FunctionExpression(name, parameters, body, returnType,
485 ast.Modifiers.EMPTY, null, null); 523 ast.Modifiers.EMPTY, null, null);
486 } 524 }
487 525
488 /** 526 /**
489 * Translate a list of arguments to an AST NodeList. 527 * Translate a list of arguments to an AST NodeList.
490 */ 528 */
491 ast.NodeList translateArguments(List<Expression> args) { 529 ast.NodeList translateArguments(List<Expression> args) {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
527 new ast.NodeList(openBrace, statements.toLink(), closeBrace)); 565 new ast.NodeList(openBrace, statements.toLink(), closeBrace));
528 } 566 }
529 567
530 ast.Node visitVariable(Variable node) { 568 ast.Node visitVariable(Variable node) {
531 // The scope of variables is the body of their binding, so a name has 569 // The scope of variables is the body of their binding, so a name has
532 // already been generated when we visit a variable. 570 // already been generated when we visit a variable.
533 assert(node.identifier != null); 571 assert(node.identifier != null);
534 return new ast.Send(null, node.identifier); 572 return new ast.Send(null, node.identifier);
535 } 573 }
536 574
575 ast.Node visitSequence(Sequence node) {
576 return node.expressions.map((e) => e.accept(this)).reduce(concatenate);
577 }
578
537 ast.Node visitLetVal(LetVal node) { 579 ast.Node visitLetVal(LetVal node) {
538 // Let bindings translate into assignments. 580 // Let bindings translate into assignments.
539 ast.Identifier identifier = node.variable.assignIdentifier(); 581 ast.Identifier identifier = node.variable.assignIdentifier();
540 variables.add(identifier); 582 variables.add(identifier);
541 583
542 ast.Expression expression = node.definition.accept(this); 584 ast.Expression expression = node.definition.accept(this);
543 ast.Expression assignment = makeAssignment(identifier, expression); 585 ast.Expression assignment = makeAssignment(identifier, expression);
544 586
545 ast.Node rest = node.body.accept(this); 587 ast.Node rest = node.body.accept(this);
546 return concatenate(assignment, rest); 588 return concatenate(assignment, rest);
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
669 } 711 }
670 712
671 ast.Expression visitInterceptor(dart2js.InterceptorConstant constant) { 713 ast.Expression visitInterceptor(dart2js.InterceptorConstant constant) {
672 return unimplemented(); 714 return unimplemented();
673 } 715 }
674 716
675 ast.Expression visitDummy(dart2js.DummyConstant constant) { 717 ast.Expression visitDummy(dart2js.DummyConstant constant) {
676 return unimplemented(); 718 return unimplemented();
677 } 719 }
678 } 720 }
OLDNEW
« no previous file with comments | « no previous file | sdk/lib/_internal/compiler/implementation/ir/ir_builder.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698