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

Unified Diff: sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_builder.dart

Issue 686743002: Support while loop in analyzer2dart. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 2 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: sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_builder.dart
diff --git a/sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_builder.dart b/sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_builder.dart
index 5a006dc834027723cd6672385b1d4c21e6a19a24..d6bf2704f4ae12e0c3ac45cf999ffa1bbf13dac6 100644
--- a/sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_builder.dart
@@ -777,6 +777,90 @@ class IrBuilder {
}
}
+
+ /// Creates a while loop in which the condition and body are created by
+ /// [buildCondition] and [buildBody], respectively.
+ ///
+ /// The jump [target] is used to identify which `break` and `continue`
+ /// statements that have this `while` statement as their target.
+ void buildWhile({SubbuildFunction buildCondition,
+ SubbuildFunction buildBody,
+ JumpTarget target}) {
+ assert(isOpen);
+ // While loops use four named continuations: the entry to the body, the
+ // loop exit, the loop back edge (continue), and the loop exit (break).
+ // The CPS translation of [[while (condition) body; successor]] is:
+ //
+ // let cont continue(x, ...) =
+ // let prim cond = [[condition]] in
+ // let cont break() = [[successor]] in
+ // let cont exit() = break(v, ...) in
+ // let cont body() = [[body]]; continue(v, ...) in
+ // branch cond (body, exit) in
+ // continue(v, ...)
+ //
+ // If there are no breaks in the body, the break continuation is inlined
+ // in the exit continuation (i.e., the translation of the successor
+ // statement occurs in the exit continuation).
+
+ // The condition and body are delimited.
+ IrBuilder condBuilder = new IrBuilder.recursive(this);
+ ir.Primitive condition = buildCondition(condBuilder);
+
+ JumpCollector breakCollector = new JumpCollector(target);
+ JumpCollector continueCollector = new JumpCollector(target);
+ state.breakCollectors.add(breakCollector);
+ state.continueCollectors.add(continueCollector);
+
+ IrBuilder bodyBuilder = new IrBuilder.delimited(condBuilder);
+ buildBody(bodyBuilder);
+ assert(state.breakCollectors.last == breakCollector);
+ assert(state.continueCollectors.last == continueCollector);
+ state.breakCollectors.removeLast();
+ state.continueCollectors.removeLast();
+
+ // Create body entry and loop exit continuations and a branch to them.
+ ir.Continuation bodyContinuation = new ir.Continuation([]);
+ ir.Continuation exitContinuation = new ir.Continuation([]);
+ ir.LetCont branch =
+ new ir.LetCont(exitContinuation,
+ new ir.LetCont(bodyContinuation,
+ new ir.Branch(new ir.IsTrue(condition),
+ bodyContinuation,
+ exitContinuation)));
+ // If there are breaks in the body, then there must be a join-point
+ // continuation for the normal exit and the breaks.
+ bool hasBreaks = !breakCollector.isEmpty;
+ ir.LetCont letJoin;
+ if (hasBreaks) {
+ letJoin = new ir.LetCont(null, branch);
+ condBuilder.add(letJoin);
+ condBuilder._current = branch;
+ } else {
+ condBuilder.add(branch);
+ }
+ ir.Continuation loopContinuation =
+ new ir.Continuation(condBuilder._parameters);
+ if (bodyBuilder.isOpen) continueCollector.addJump(bodyBuilder);
+ invokeFullJoin(loopContinuation, continueCollector, recursive: true);
+ bodyContinuation.body = bodyBuilder._root;
+
+ loopContinuation.body = condBuilder._root;
+ add(new ir.LetCont(loopContinuation,
+ new ir.InvokeContinuation(loopContinuation,
+ environment.index2value)));
+ if (hasBreaks) {
+ _current = branch;
+ environment = condBuilder.environment;
+ breakCollector.addJump(this);
+ letJoin.continuation = createJoin(environment.length, breakCollector);
+ _current = letJoin;
+ } else {
+ _current = condBuilder._current;
+ environment = condBuilder.environment;
+ }
+ }
+
/// Create a return statement `return value;` or `return;` if [value] is
/// null.
void buildReturn([ir.Primitive value]) {
« no previous file with comments | « pkg/analyzer2dart/test/sexpr_data.dart ('k') | sdk/lib/_internal/compiler/implementation/cps_ir/cps_ir_builder_visitor.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698