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

Unified Diff: pkg/kernel/lib/interpreter/interpreter.dart

Issue 2806483003: Implement expression evaluation in Coninuation Passing Style (Closed)
Patch Set: Apply comments Created 3 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/kernel/lib/interpreter/interpreter.dart
diff --git a/pkg/kernel/lib/interpreter/interpreter.dart b/pkg/kernel/lib/interpreter/interpreter.dart
index 857d065f61b08c16c298c3f500c05fbfe5bcb072..9b0babf4994b503e8bc8ddffe852322cc8faa082 100644
--- a/pkg/kernel/lib/interpreter/interpreter.dart
+++ b/pkg/kernel/lib/interpreter/interpreter.dart
@@ -24,8 +24,9 @@ class Interpreter {
assert(program.libraries.isEmpty);
Procedure mainMethod = program.mainMethod;
Statement statementBlock = mainMethod.function.body;
- Continuation cont = new Continuation(statementBlock, new State.initial());
- visitor.trampolinedExecution(cont);
+ StatementConfiguration configuration =
+ new StatementConfiguration(statementBlock, new State.initial());
+ visitor.trampolinedExecution(configuration);
}
}
@@ -74,168 +75,181 @@ class Environment {
}
/// Evaluate expressions.
-class Evaluator extends ExpressionVisitor1<Value> {
- Value eval(Expression expr, Environment env) => expr.accept1(this, env);
+class Evaluator extends ExpressionVisitor1<Configuration> {
+ Configuration eval(Expression expr, ExpressionState state) =>
+ expr.accept1(this, state);
- Value defaultExpression(Expression node, env) {
+ Configuration defaultExpression(Expression node, state) {
throw new NotImplemented('Evaluation for expressions of type '
'${node.runtimeType} is not implemented.');
}
- Value visitInvalidExpression1(InvalidExpression node, env) {
+ Configuration visitInvalidExpression1(InvalidExpression node, state) {
throw 'Invalid expression at ${node.location.toString()}';
}
- Value visitVariableGet(VariableGet node, env) {
- return env.lookup(node.variable);
+ Configuration visitVariableGet(VariableGet node, state) {
+ Value value = state.environment.lookup(node.variable);
+ return new ContinuationConfiguration(state.continuation, value);
}
- Value visitVariableSet(VariableSet node, env) {
- return env.assign(node.variable, eval(node.value, env));
+ Configuration visitVariableSet(VariableSet node, state) {
+ var cont = new VariableSetContinuation(state, node.variable);
+ return new ExpressionConfiguration(
+ node.value, state.withContinuation(cont));
}
- Value visitPropertyGet(PropertyGet node, env) {
- Value receiver = eval(node.receiver, env);
- return receiver.class_.lookupGetter(node.name)(receiver);
+ Configuration visitPropertyGet(PropertyGet node, state) {
+ var cont = new PropertyGetContinuation(node.name, state);
+ return new ExpressionConfiguration(
+ node.receiver, state.withContinuation(cont));
}
- Value visitPropertySet(PropertySet node, env) {
- Value receiver = eval(node.receiver, env);
- Value value = eval(node.value, env);
- receiver.class_.lookupSetter(node.name)(receiver, value);
- return value;
+ Configuration visitPropertySet(PropertySet node, state) {
+ var cont = new PropertySetContinuation(node.value, node.name, state);
+ return new ExpressionConfiguration(
+ node.receiver, state.withContinuation(cont));
}
- Value visitDirectPropertyGet(DirectPropertyGet node, env) {
- Value receiver = eval(node.receiver, env);
- return receiver.class_.getProperty(receiver, node.target);
- }
-
- Value visitDirectPropertySet(DirectPropertySet node, env) {
- Value receiver = eval(node.receiver, env);
- Value value = eval(node.value, env);
- receiver.class_.setProperty(receiver, node.target, value);
- return value;
- }
+ Configuration visitStaticGet(StaticGet node, state) =>
+ defaultExpression(node, state);
+ Configuration visitStaticSet(StaticSet node, state) =>
+ defaultExpression(node, state);
- Value visitStaticGet(StaticGet node, env) => defaultExpression(node, env);
- Value visitStaticSet(StaticSet node, env) => defaultExpression(node, env);
-
- Value visitStaticInvocation(StaticInvocation node, env) {
+ Configuration visitStaticInvocation(StaticInvocation node, state) {
if ('print' == node.name.toString()) {
- // Special evaluation of print.
- var res = eval(node.arguments.positional[0], env);
- print(res.value);
- return Value.nullInstance;
+ return new ExpressionConfiguration(node.arguments.positional.first,
+ state.withContinuation(new PrintContinuation(state)));
} else {
- throw new NotImplemented('Support for statement type '
- '${node.runtimeType} is not implemented');
+ // Currently supports only static invocations with no arguments.
+ if (node.arguments.positional.isEmpty && node.arguments.named.isEmpty) {
+ State statementState = new State.initial()
+ .withExpressionContinuation(state.continuation)
+ .withConfiguration(new ExitConfiguration(state.continuation));
+
+ return new StatementConfiguration(
+ node.target.function.body, statementState);
+ }
+ throw new NotImplemented(
+ 'Support for static invocation with arguments is not implemented');
}
}
- Value visitMethodInvocation(MethodInvocation node, env) {
+ Configuration visitMethodInvocation(MethodInvocation node, state) {
// Currently supports only method invocation with <2 arguments and is used
// to evaluate implemented operators for int, double and String values.
- var receiver = eval(node.receiver, env);
- if (node.arguments.positional.isNotEmpty) {
- var argValue = eval(node.arguments.positional.first, env);
- return receiver.invokeMethod(node.name, argValue);
- } else {
- return receiver.invokeMethod(node.name);
- }
+ var cont =
+ new MethodInvocationContinuation(node.arguments, node.name, state);
+
+ return new ExpressionConfiguration(
+ node.receiver, state.withContinuation(cont));
}
- Value visitConstructorInvocation(ConstructorInvocation node, env) {
+ Configuration visitConstructorInvocation(ConstructorInvocation node, state) {
Class class_ = new Class(node.target.enclosingClass.reference);
- Environment emptyEnv = new Environment.empty();
// Currently we don't support initializers.
// TODO: Modify to respect dart semantics for initialization.
// 1. Init fields and eval initializers, repeat the same with super.
// 2. Eval the Function body of the constructor.
- List<Value> fields = class_.instanceFields
- .map((Field f) => eval(f.initializer ?? new NullLiteral(), emptyEnv))
- .toList(growable: false);
+ List<Value> fields = <Value>[];
- return new ObjectValue(class_, fields);
+ return new ContinuationConfiguration(
+ state.continuation, new ObjectValue(class_, fields));
}
- Value visitNot(Not node, env) {
- Value operand = eval(node.operand, env).toBoolean();
- return identical(operand, Value.trueInstance)
- ? Value.falseInstance
- : Value.trueInstance;
+ Configuration visitNot(Not node, state) {
+ return new ExpressionConfiguration(
+ node.operand, state.withContinuation(new NotContinuation(state)));
}
- Value visitLogicalExpression(LogicalExpression node, env) {
+ Configuration visitLogicalExpression(LogicalExpression node, state) {
if ('||' == node.operator) {
- BoolValue left = eval(node.left, env).toBoolean();
- return identical(left, Value.trueInstance)
- ? Value.trueInstance
- : eval(node.right, env).toBoolean();
+ var cont = new OrContinuation(node.right, state);
+ return new ExpressionConfiguration(
+ node.left, state.withContinuation(cont));
} else {
assert('&&' == node.operator);
- BoolValue left = eval(node.left, env).toBoolean();
- return identical(left, Value.falseInstance)
- ? Value.falseInstance
- : eval(node.right, env).toBoolean();
+ var cont = new AndContinuation(node.right, state);
+ return new ExpressionConfiguration(
+ node.left, state.withContinuation(cont));
}
}
- Value visitConditionalExpression(ConditionalExpression node, env) {
- var condition = eval(node.condition, env).toBoolean();
- return identical(condition, Value.trueInstance)
- ? eval(node.then, env)
- : eval(node.otherwise, env);
+ Configuration visitConditionalExpression(ConditionalExpression node, state) {
+ var cont = new ConditionalContinuation(node.then, node.otherwise, state);
+ return new ExpressionConfiguration(
+ node.condition, state.withContinuation(cont));
}
- Value visitStringConcatenation(StringConcatenation node, env) {
- StringBuffer res = new StringBuffer();
- for (Expression e in node.expressions) {
- res.write(eval(e, env).value);
- }
- return new StringValue(res.toString());
+ Configuration visitStringConcatenation(StringConcatenation node, state) {
+ var cont = new StringConcatenationContinuation(node.expressions, state);
+ return new ExpressionConfiguration(
+ node.expressions.first, state.withContinuation(cont));
}
// Evaluation of BasicLiterals.
- Value visitStringLiteral(StringLiteral node, env) =>
- new StringValue(node.value);
- Value visitIntLiteral(IntLiteral node, env) => new IntValue(node.value);
- Value visitDoubleLiteral(DoubleLiteral node, env) =>
- new DoubleValue(node.value);
- Value visitBoolLiteral(BoolLiteral node, env) =>
- node.value ? Value.trueInstance : Value.falseInstance;
- Value visitNullLiteral(NullLiteral node, env) => Value.nullInstance;
+ Configuration visitStringLiteral(StringLiteral node, state) {
+ return new ContinuationConfiguration(
+ state.continuation, new StringValue(node.value));
+ }
+
+ Configuration visitIntLiteral(IntLiteral node, state) {
+ return new ContinuationConfiguration(
+ state.continuation, new IntValue(node.value));
+ }
+
+ Configuration visitDoubleLiteral(DoubleLiteral node, state) {
+ return new ContinuationConfiguration(
+ state.continuation, new DoubleValue(node.value));
+ }
- Value visitLet(Let node, env) {
- var value = eval(node.variable.initializer, env);
- var letEnv = new Environment(env);
- letEnv.expand(node.variable, value);
- return eval(node.body, letEnv);
+ Configuration visitBoolLiteral(BoolLiteral node, state) {
+ Value value = node.value ? Value.trueInstance : Value.falseInstance;
+ return new ContinuationConfiguration(state.continuation, value);
+ }
+
+ Configuration visitNullLiteral(NullLiteral node, state) {
+ return new ContinuationConfiguration(
+ state.continuation, Value.nullInstance);
+ }
+
+ Configuration visitLet(Let node, state) {
+ var letCont = new LetContinuation(node.variable, node.body, state);
+ return new ExpressionConfiguration(
+ node.variable.initializer, state.withContinuation(letCont));
}
}
-/// Represents a state which consists of current environment, continuation to be
-/// applied and the current label.
+/// Represents a state for statement execution.
class State {
final Environment environment;
final Label labels;
- final Continuation continuation;
+ final StatementConfiguration statementConfiguration;
+
+ final ExpressionContinuation returnContinuation;
- State(this.environment, this.labels, this.continuation);
- State.initial() : this(new Environment.empty(), null, null);
+ State(this.environment, this.labels, this.statementConfiguration,
+ this.returnContinuation);
+
+ State.initial() : this(new Environment.empty(), null, null, null);
State withEnvironment(Environment env) {
- return new State(env, labels, continuation);
+ return new State(env, labels, statementConfiguration, returnContinuation);
}
State withBreak(Statement stmt) {
+ Label breakLabels = new Label(stmt, statementConfiguration, labels);
return new State(
- environment, new Label(stmt, continuation, labels), continuation);
+ environment, breakLabels, statementConfiguration, returnContinuation);
+ }
+
+ State withConfiguration(Configuration config) {
+ return new State(environment, labels, config, returnContinuation);
}
- State withContinuation(Continuation cont) {
- return new State(environment, labels, cont);
+ State withExpressionContinuation(ExpressionContinuation cont) {
+ return new State(environment, labels, statementConfiguration, cont);
}
Label lookupLabel(LabeledStatement s) {
@@ -244,22 +258,37 @@ class State {
}
}
-/// Represent the continuation for execution of statement.
-class Continuation {
- final Statement statement;
- final State state;
+/// Represents a state for expression evaluation.
+class ExpressionState {
+ /// Environment in which the expression is evaluated.
+ final Environment environment;
+
+ /// Next continuation to be applied.
+ final ExpressionContinuation continuation;
+
+ ExpressionState(this.environment, this.continuation);
+
+ ExpressionState.fromStatementState(State state)
+ : this(state.environment,
+ new ExpressionStatementContinuation(state.statementConfiguration));
+
+ ExpressionState withEnvironment(Environment env) {
+ return new ExpressionState(env, continuation);
+ }
- Continuation(this.statement, this.state);
+ ExpressionState withContinuation(ExpressionContinuation cont) {
+ return new ExpressionState(environment, cont);
+ }
}
/// Represents a labeled statement, the corresponding continuation and the
/// enclosing label.
class Label {
final LabeledStatement statement;
- final Continuation continuation;
+ final StatementConfiguration configuration;
final Label enclosingLabel;
- Label(this.statement, this.continuation, this.enclosingLabel);
+ Label(this.statement, this.configuration, this.enclosingLabel);
Label lookupLabel(LabeledStatement s) {
if (identical(s, statement)) return this;
@@ -268,6 +297,328 @@ class Label {
}
}
+abstract class Configuration {
+ /// Executes the current and returns the next configuration.
+ Configuration step(StatementExecuter executer);
+}
+
+/// Represents the configuration for execution of statement.
+class StatementConfiguration extends Configuration {
+ final Statement statement;
+ final State state;
+
+ StatementConfiguration(this.statement, this.state);
+
+ Configuration step(StatementExecuter executer) =>
+ executer.exec(statement, state);
+}
+
+class ExitConfiguration extends StatementConfiguration {
+ final ExpressionContinuation returnContinuation;
+
+ ExitConfiguration(this.returnContinuation) : super(null, null);
+
+ Configuration step(StatementExecuter executer) {
+ return returnContinuation(Value.nullInstance);
+ }
+}
+
+/// Represents the configuration for applying an [ExpressionContinuation].
+class ContinuationConfiguration extends Configuration {
+ final ExpressionContinuation continuation;
+ final Value value;
+
+ ContinuationConfiguration(this.continuation, this.value);
+
+ Configuration step(StatementExecuter executer) => continuation(value);
+}
+
+/// Represents the configuration for evaluating an [Expression].
+class ExpressionConfiguration extends Configuration {
+ final Expression expression;
+ final ExpressionState state;
+
+ ExpressionConfiguration(this.expression, this.state);
+
+ Configuration step(StatementExecuter executer) =>
+ executer.eval(expression, state);
+}
+
+/// Represents an expression continuation.
+abstract class ExpressionContinuation {
+ Configuration call(Value v);
+}
+
+/// Represents a continuation that returns the next [StatementConfiguration]
+/// to be executed.
+class ExpressionStatementContinuation extends ExpressionContinuation {
+ final StatementConfiguration configuration;
+
+ ExpressionStatementContinuation(this.configuration);
+
+ Configuration call(Value _) {
+ return configuration;
+ }
+}
+
+class PrintContinuation extends ExpressionContinuation {
+ final ExpressionState state;
+
+ PrintContinuation(this.state);
+
+ Configuration call(Value v) {
+ print(v.value);
+ return new ContinuationConfiguration(
+ state.continuation, Value.nullInstance);
+ }
+}
+
+class PropertyGetContinuation extends ExpressionContinuation {
+ final Name name;
+ final ExpressionState state;
+
+ PropertyGetContinuation(this.name, this.state);
+
+ Configuration call(Value receiver) {
+ // TODO: CPS the invocation of the getter.
+ Value propertyValue = receiver.class_.lookupGetter(name)(receiver);
+ return new ContinuationConfiguration(state.continuation, propertyValue);
+ }
+}
+
+class PropertySetContinuation extends ExpressionContinuation {
+ final Expression value;
+ final Name setterName;
+ final ExpressionState state;
+
+ PropertySetContinuation(this.value, this.setterName, this.state);
+
+ Configuration call(Value receiver) {
+ var cont = new SetterContinuation(receiver, setterName, state);
+ return new ExpressionConfiguration(value, state.withContinuation(cont));
+ }
+}
+
+class SetterContinuation extends ExpressionContinuation {
+ final Value receiver;
+ final Name name;
+ final ExpressionState state;
+
+ SetterContinuation(this.receiver, this.name, this.state);
+
+ Configuration call(Value v) {
+ Setter setter = receiver.class_.lookupSetter(name);
+ setter(receiver, v);
+ return new ContinuationConfiguration(state.continuation, v);
+ }
+}
+
+class StaticInvocationContinuation extends ExpressionContinuation {
+ final ExpressionState state;
+
+ StaticInvocationContinuation(this.state);
+
+ Configuration call(Value v) {
+ return new ContinuationConfiguration(state.continuation, v);
+ }
+}
+
+class MethodInvocationContinuation extends ExpressionContinuation {
+ final Arguments arguments;
+ final Name methodName;
+ final ExpressionState state;
+
+ MethodInvocationContinuation(this.arguments, this.methodName, this.state);
+
+ Configuration call(Value receiver) {
+ if (arguments.positional.isEmpty) {
+ Value returnValue = receiver.invokeMethod(methodName);
+ return new ContinuationConfiguration(state.continuation, returnValue);
+ }
+ var cont =
+ new ArgumentsContinuation(receiver, methodName, arguments, state);
+
+ return new ExpressionConfiguration(
+ arguments.positional.first, state.withContinuation(cont));
+ }
+}
+
+class ArgumentsContinuation extends ExpressionContinuation {
+ final Value receiver;
+ final Name methodName;
+ final Arguments arguments;
+ final ExpressionState state;
+
+ ArgumentsContinuation(
+ this.receiver, this.methodName, this.arguments, this.state);
+
+ Configuration call(Value value) {
+ // Currently evaluates only one argument, for simple method invocations
+ // with 1 argument.
+ Value returnValue = receiver.invokeMethod(methodName, value);
+ return new ContinuationConfiguration(state.continuation, returnValue);
+ }
+}
+
+class VariableSetContinuation extends ExpressionContinuation {
+ final ExpressionState state;
+ final VariableDeclaration variable;
+
+ VariableSetContinuation(this.state, this.variable);
+
+ Configuration call(Value value) {
+ state.environment.assign(variable, value);
+ return new ContinuationConfiguration(state.continuation, value);
+ }
+}
+
+class NotContinuation extends ExpressionContinuation {
+ final ExpressionState state;
+
+ NotContinuation(this.state);
+
+ Configuration call(Value value) {
+ Value notValue = identical(Value.trueInstance, value)
+ ? Value.falseInstance
+ : Value.trueInstance;
+ return new ContinuationConfiguration(state.continuation, notValue);
+ }
+}
+
+class OrContinuation extends ExpressionContinuation {
+ final Expression right;
+ final ExpressionState state;
+
+ OrContinuation(this.right, this.state);
+
+ Configuration call(Value left) {
+ return identical(Value.trueInstance, left)
+ ? new ContinuationConfiguration(state.continuation, Value.trueInstance)
+ : new ExpressionConfiguration(right, state);
+ }
+}
+
+class AndContinuation extends ExpressionContinuation {
+ final Expression right;
+ final ExpressionState state;
+
+ AndContinuation(this.right, this.state);
+
+ Configuration call(Value left) {
+ return identical(Value.falseInstance, left)
+ ? new ContinuationConfiguration(state.continuation, Value.falseInstance)
+ : new ExpressionConfiguration(right, state);
+ }
+}
+
+class ConditionalContinuation extends ExpressionContinuation {
+ final Expression then;
+ final Expression otherwise;
+ final ExpressionState state;
+
+ ConditionalContinuation(this.then, this.otherwise, this.state);
+
+ Configuration call(Value value) {
+ return identical(Value.trueInstance, value)
+ ? new ExpressionConfiguration(then, state)
+ : new ExpressionConfiguration(otherwise, state);
+ }
+}
+
+class StringConcatenationContinuation extends ExpressionContinuation {
+ final List<Expression> expressions;
+ final ExpressionState state;
+
+ int _currentPosition = 0;
+ final List<Value> _values = <Value>[];
+
+ StringConcatenationContinuation(this.expressions, this.state);
+
+ Configuration call(Value value) {
+ _values.add(value);
+ if (_values.length == expressions.length) {
+ StringBuffer res = new StringBuffer();
+
+ for (int i = 0; i < expressions.length; i++) {
+ res.write(_values[i].value);
+ }
+
+ Value value = new StringValue(res.toString());
+ return new ContinuationConfiguration(state.continuation, value);
+ }
+ return new ExpressionConfiguration(
+ expressions[++_currentPosition], state.withContinuation(this));
+ }
+}
+
+class LetContinuation extends ExpressionContinuation {
+ final VariableDeclaration variable;
+ final Expression letBody;
+ final ExpressionState state;
+
+ LetContinuation(this.variable, this.letBody, this.state);
+
+ Configuration call(Value value) {
+ var letState = state.withEnvironment(new Environment(state.environment));
+ letState.environment.expand(variable, value);
+ return new ExpressionConfiguration(letBody, letState);
+ }
+}
+
+/// Represents the continuation for the condition expression in [WhileStatement].
+class WhileConditionContinuation extends ExpressionContinuation {
+ final WhileStatement node;
+ final State state;
+
+ WhileConditionContinuation(this.node, this.state);
+
+ StatementConfiguration call(Value v) {
+ if (identical(v, Value.trueInstance)) {
+ // Add configuration for the While statement to the linked list.
+ StatementConfiguration config = new StatementConfiguration(node, state);
+ // Configuration for the body of the loop.
+ return new StatementConfiguration(
+ node.body, state.withConfiguration(config));
+ }
+
+ return state.statementConfiguration;
+ }
+}
+
+/// Represents the continuation for the condition expression in [IfStatement].
+class IfConditionContinuation extends ExpressionContinuation {
+ final Statement then;
+ final Statement otherwise;
+ final State state;
+
+ IfConditionContinuation(this.then, this.otherwise, this.state);
+
+ StatementConfiguration call(Value v) {
+ if (identical(v, Value.trueInstance)) {
+ return new StatementConfiguration(then, state);
+ } else if (otherwise != null) {
+ return new StatementConfiguration(otherwise, state);
+ }
+ return state.statementConfiguration;
+ }
+}
+
+/// Represents the continuation for the initializer expression in
+/// [VariableDeclaration].
+class VariableInitializerContinuation extends ExpressionContinuation {
+ final VariableDeclaration variable;
+ final Environment environment;
+ final StatementConfiguration nextConfiguration;
+
+ VariableInitializerContinuation(
+ this.variable, this.environment, this.nextConfiguration);
+
+ StatementConfiguration call(Value v) {
+ environment.expand(variable, v);
+ return nextConfiguration;
+ }
+}
+
/// Executes statements.
///
/// Execution of a statement completes in one of the following ways:
@@ -277,95 +628,111 @@ class Label {
/// returned and applied
/// - it returns with or without value, TBD
/// - it throws, TBD
-class StatementExecuter extends StatementVisitor1<Continuation> {
+class StatementExecuter extends StatementVisitor1<Configuration> {
Evaluator evaluator = new Evaluator();
- void trampolinedExecution(Continuation continuation) {
- while (continuation != null) {
- continuation = exec(continuation.statement, continuation.state);
+ void trampolinedExecution(Configuration configuration) {
+ while (configuration != null) {
+ configuration = configuration.step(this);
}
}
- Continuation exec(Statement statement, state) =>
+ Configuration exec(Statement statement, State state) =>
statement.accept1(this, state);
- Value eval(Expression expression, env) => evaluator.eval(expression, env);
+ Configuration eval(Expression expression, ExpressionState state) =>
+ evaluator.eval(expression, state);
- Continuation defaultStatement(Statement node, state) {
+ Configuration defaultStatement(Statement node, state) {
throw notImplemented(
m: "Execution is not implemented for statement:\n$node ");
}
- Continuation visitInvalidStatement(InvalidStatement node, state) {
+ Configuration visitInvalidStatement(InvalidStatement node, state) {
throw "Invalid statement at ${node.location}";
}
- Continuation visitExpressionStatement(ExpressionStatement node, state) {
- eval(node.expression, state.environment);
- return state.continuation;
+ Configuration visitExpressionStatement(ExpressionStatement node, state) {
+ return new ExpressionConfiguration(
+ node.expression, new ExpressionState.fromStatementState(state));
}
- Continuation visitBlock(Block node, state) {
+ Configuration visitBlock(Block node, state) {
if (node.statements.isEmpty) {
- return state.continuation;
+ return state.statementConfiguration;
}
State blockState =
state.withEnvironment(new Environment(state.environment));
- Continuation cont = state.continuation;
+ StatementConfiguration configuration = state.statementConfiguration;
for (Statement s in node.statements.reversed) {
- cont = new Continuation(s, blockState.withContinuation(cont));
+ configuration = new StatementConfiguration(
+ s, blockState.withConfiguration(configuration));
}
- return cont;
+ return configuration;
}
- Continuation visitEmptyStatement(EmptyStatement node, state) {
- return state.continuation;
+ Configuration visitEmptyStatement(EmptyStatement node, state) {
+ return state.statementConfiguration;
}
- Continuation visitIfStatement(IfStatement node, state) {
- Value cond = eval(node.condition, state.environment).toBoolean();
- if (identical(Value.trueInstance, cond)) {
- return new Continuation(node.then, state);
- } else if (node.otherwise != null) {
- return new Continuation(node.otherwise, state);
- }
- return state.continuation;
+ Configuration visitIfStatement(IfStatement node, state) {
+ var expState = new ExpressionState.fromStatementState(state);
+ var cont = new IfConditionContinuation(node.then, node.otherwise, state);
+ return new ExpressionConfiguration(
+ node.condition, expState.withContinuation(cont));
}
- Continuation visitLabeledStatement(LabeledStatement node, state) {
- return new Continuation(node.body, state.withBreak(node));
+ Configuration visitLabeledStatement(LabeledStatement node, state) {
+ return new StatementConfiguration(node.body, state.withBreak(node));
}
- Continuation visitBreakStatement(BreakStatement node, state) {
- return state.lookupLabel(node.target).continuation;
+ Configuration visitBreakStatement(BreakStatement node, state) {
+ return state.lookupLabel(node.target).configuration;
}
- Continuation visitWhileStatement(WhileStatement node, state) {
- Value cond = eval(node.condition, state.environment).toBoolean();
- if (identical(Value.trueInstance, cond)) {
- // Add continuation for the While statement to the linked list.
- Continuation cont = new Continuation(node, state);
- // Continuation for the body of the loop.
- return new Continuation(node.body, state.withContinuation(cont));
- }
- return state.continuation;
+ Configuration visitWhileStatement(WhileStatement node, state) {
+ var expState = new ExpressionState.fromStatementState(state);
+ var cont = new WhileConditionContinuation(node, state);
+
+ return new ExpressionConfiguration(
+ node.condition, expState.withContinuation(cont));
}
- Continuation visitDoStatement(DoStatement node, state) {
+ Configuration visitDoStatement(DoStatement node, state) {
WhileStatement whileStatement =
new WhileStatement(node.condition, node.body);
- Continuation cont = new Continuation(whileStatement, state);
- return new Continuation(node.body, state.withContinuation(cont));
+ StatementConfiguration configuration =
+ new StatementConfiguration(whileStatement, state);
+
+ return new StatementConfiguration(
+ node.body, state.withConfiguration(configuration));
}
- Continuation visitVariableDeclaration(VariableDeclaration node, state) {
- Value value = node.initializer != null
- ? eval(node.initializer, state.environment)
- : Value.nullInstance;
- state.environment.expand(node, value);
- return state.continuation;
+ Configuration visitReturnStatement(ReturnStatement node, state) {
+ assert(state.returnContinuation != null);
+ // The new ExpressionState contains the next expression continuation.
+ var expState = new ExpressionState.fromStatementState(state)
+ .withContinuation(state.returnContinuation);
+ return new ExpressionConfiguration(
+ node.expression ?? new NullLiteral(), expState);
+ }
+
+ Configuration visitVariableDeclaration(VariableDeclaration node, state) {
+ if (node.initializer != null) {
+ var expState = new ExpressionState.fromStatementState(state);
+ var cont = new VariableInitializerContinuation(
+ node, state.environment, state.statementConfiguration);
+ return new ExpressionConfiguration(
+ node.initializer, expState.withContinuation(cont));
+ }
+ state.environment.expand(node, Value.nullInstance);
+ return state.statementConfiguration;
}
}
+// ------------------------------------------------------------------------
+// VALUES
+// ------------------------------------------------------------------------
+
typedef Value Getter(Value receiver);
typedef void Setter(Value receiver, Value value);
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698