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

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

Issue 666863002: Support conditional expressions in analyzer2dart. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Updated cf. comments. 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 13933850fa144f0b396bb9a6f38f35de4144037a..850ff3ccfdc70f262d7dddbc88b3efea366644f5 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
@@ -127,8 +127,11 @@ class JumpCollector {
}
}
-/// Mixin that provided encapsulated access to nested builders.
-class IrBuilderMixin {
+/// Function for building nodes in the context of the provided [builder].
+typedef ir.Node SubbuildFunction(IrBuilder builder);
+
+/// Mixin that provides encapsulated access to nested builders.
+abstract class IrBuilderMixin<N> {
IrBuilder _irBuilder;
/// Execute [f] with [builder] as the current builder.
@@ -146,8 +149,20 @@ class IrBuilderMixin {
assert(_irBuilder != null);
return _irBuilder;
}
-}
+ /// Visits the [node].
+ ir.Primitive visit(N node);
+
+ /// Builds and returns the [ir.Node] for [node] or returns `null` if
+ /// [node] is `null`.
+ ir.Node build(N node) => node != null ? visit(node) : null;
+
+ /// Returns a closure that takes an [IrBuilder] and builds [node] in its
+ /// context using [build].
+ SubbuildFunction subbuild(N node) {
+ return (IrBuilder builder) => withBuilder(builder, () => build(node));
+ }
+}
/// Shared state between nested builders.
class IrBuilderSharedState {
@@ -355,6 +370,56 @@ class IrBuilder {
state.constantSystem.createString(new ast.DartString.literal(value)));
}
+ /// Creates a conditional expression with the provided [condition] where the
+ /// then and else expression are created through the [buildThenExpression] and
+ /// [buildElseExpression] functions, respectively.
+ ir.Primitive buildConditional(
+ ir.Primitive condition,
+ ir.Primitive buildThenExpression(IrBuilder builder),
+ ir.Primitive buildElseExpression(IrBuilder builder)) {
+
+ assert(isOpen);
+
+ // The then and else expressions are delimited.
+ IrBuilder thenBuilder = new IrBuilder.delimited(this);
+ IrBuilder elseBuilder = new IrBuilder.delimited(this);
+ ir.Primitive thenValue = buildThenExpression(thenBuilder);
+ ir.Primitive elseValue = buildElseExpression(elseBuilder);
+
+ // Treat the values of the subexpressions as named values in the
+ // environment, so they will be treated as arguments to the join-point
+ // continuation.
+ assert(environment.length == thenBuilder.environment.length);
+ assert(environment.length == elseBuilder.environment.length);
+ thenBuilder.environment.extend(null, thenValue);
+ elseBuilder.environment.extend(null, elseValue);
+ JumpCollector jumps = new JumpCollector(null);
+ jumps.addJump(thenBuilder);
+ jumps.addJump(elseBuilder);
+ ir.Continuation joinContinuation =
+ createJoin(environment.length + 1, jumps);
+
+ // Build the term
+ // let cont join(x, ..., result) = [] in
+ // let cont then() = [[thenPart]]; join(v, ...) in
+ // let cont else() = [[elsePart]]; join(v, ...) in
+ // if condition (then, else)
+ ir.Continuation thenContinuation = new ir.Continuation([]);
+ ir.Continuation elseContinuation = new ir.Continuation([]);
+ thenContinuation.body = thenBuilder._root;
+ elseContinuation.body = elseBuilder._root;
+ add(new ir.LetCont(joinContinuation,
+ new ir.LetCont(thenContinuation,
+ new ir.LetCont(elseContinuation,
+ new ir.Branch(new ir.IsTrue(condition),
+ thenContinuation,
+ elseContinuation)))));
+ return (thenValue == elseValue)
+ ? thenValue
+ : joinContinuation.parameters.last;
+
+ }
+
/// Create a get access of [local].
ir.Primitive buildLocalGet(Element local) {
assert(isOpen);
@@ -447,10 +512,12 @@ class IrBuilder {
}
/// Creates an if-then-else statement with the provided [condition] where the
- /// then and else branches are created throught the [buildThenPart] and
+ /// then and else branches are created through the [buildThenPart] and
/// [buildElsePart] functions, respectively.
///
/// An if-then statement is created if [buildElsePart] is a no-op.
+ // TODO(johnniwinther): Unify implementation with [buildConditional] and
+ // [_buildLogicalOperator].
void buildIf(ir.Primitive condition,
void buildThenPart(IrBuilder builder),
void buildElsePart(IrBuilder builder)) {

Powered by Google App Engine
This is Rietveld 408576698