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

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

Issue 2806483003: Implement expression evaluation in Coninuation Passing Style (Closed)
Patch Set: Refactor Executer placement 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..38d5c6996993fb8635d54c24b8c16eea79801b9a 100644
--- a/pkg/kernel/lib/interpreter/interpreter.dart
+++ b/pkg/kernel/lib/interpreter/interpreter.dart
@@ -16,7 +16,7 @@ class NotImplemented {
class Interpreter {
Program program;
- StatementExecuter visitor = new StatementExecuter();
+ static StatementExecuter visitor = new StatementExecuter();
Dmitry Stefantsov 2017/04/10 14:05:53 Why is it made static?
zhivkag 2017/04/11 11:37:39 This is a remainder from some initial experiments
Interpreter(this.program);
@@ -24,7 +24,8 @@ class Interpreter {
assert(program.libraries.isEmpty);
Procedure mainMethod = program.mainMethod;
Statement statementBlock = mainMethod.function.body;
- Continuation cont = new Continuation(statementBlock, new State.initial());
+ StatementConfiguration cont =
+ new StatementConfiguration(statementBlock, new State.initial());
visitor.trampolinedExecution(cont);
}
}
@@ -74,168 +75,171 @@ 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 ExpressionConfiguration(value, state.continuation);
}
- 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 eval(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 eval(node.receiver, state.continuation(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, this);
+ return eval(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 eval(node.arguments.positional.first,
+ state.withContinuation(new PrintContinuation(state.statementState)));
} 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) {
+ var cont = new StaticInvocationContinuation(state);
+ return new StatementConfiguration(node.target.function.body,
+ state.statementState.withExpressionContinuation(cont));
+ }
+ 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, this);
+
+ return eval(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 ExpressionConfiguration(
+ new ObjectValue(class_, fields), state.continuation);
}
- 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 eval(node.operand,
+ state.withContinuation(new NotContinuation(state.continuation)));
}
- 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(state, node.right, this);
+ return eval(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(state, node.right, this);
+ return eval(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, this);
+ return eval(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, this);
+ return eval(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 ExpressionConfiguration(
+ new StringValue(node.value), state.continuation);
+ }
+
+ Configuration visitIntLiteral(IntLiteral node, state) {
+ return new ExpressionConfiguration(
+ new IntValue(node.value), state.continuation);
+ }
+
+ Configuration visitDoubleLiteral(DoubleLiteral node, state) {
+ return new ExpressionConfiguration(
+ new DoubleValue(node.value), state.continuation);
+ }
+
+ Configuration visitBoolLiteral(BoolLiteral node, state) {
+ Value value = node.value ? Value.trueInstance : Value.falseInstance;
+ return new ExpressionConfiguration(value, state.continuation);
+ }
+
+ Configuration visitNullLiteral(NullLiteral node, state) {
+ return new ExpressionConfiguration(Value.nullInstance, state.continuation);
+ }
- 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 visitLet(Let node, state) {
+ var value = eval(node.variable.initializer, state);
+ var letState = state.withEnvironment(new Environment(state.environment));
+ letState.environment.expand(node.variable, value);
+ return eval(node.body, letState);
}
}
-/// 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 Configuration configuration;
- State(this.environment, this.labels, this.continuation);
- State.initial() : this(new Environment.empty(), null, null);
+ final ExpressionContinuation expressionContinuation;
+
+ State(this.environment, this.labels, this.configuration,
+ this.expressionContinuation);
+ State.initial() : this(new Environment.empty(), null, null, null);
State withEnvironment(Environment env) {
- return new State(env, labels, continuation);
+ return new State(env, labels, configuration, expressionContinuation);
}
State withBreak(Statement stmt) {
+ Label breakLabels = new Label(stmt, configuration, labels);
return new State(
- environment, new Label(stmt, continuation, labels), continuation);
+ environment, breakLabels, configuration, expressionContinuation);
}
- State withContinuation(Continuation cont) {
- return new State(environment, labels, cont);
+ State withConfiguration(Configuration cont) {
Dmitry Stefantsov 2017/04/10 14:05:53 Maybe "cont" ==> "configuration"? We may use forms
zhivkag 2017/04/11 11:37:38 Done.
+ return new State(environment, labels, cont, expressionContinuation);
+ }
+
+ State withExpressionContinuation(ExpressionContinuation cont) {
+ return new State(environment, labels, configuration, cont);
}
Label lookupLabel(LabeledStatement s) {
@@ -244,19 +248,36 @@ 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 {
+ /// Enclosing statement state.
+ final State statementState;
+
+ /// Environment in which the expression is evaluated.
+ final Environment environment;
+
+ /// Next continuation to be evaluated.
+ final ExpressionContinuation continuation;
+
+ ExpressionState(this.statementState, this.environment, this.continuation);
- Continuation(this.statement, this.state);
+ ExpressionState.withStatementState(State state)
Dmitry Stefantsov 2017/04/10 14:05:53 Maybe rename it to "fromStatementState", because "
zhivkag 2017/04/11 11:37:38 Done.
+ : this(state, state.environment, state.expressionContinuation);
+
+ ExpressionState withEnvironment(Environment env) {
+ return new ExpressionState(statementState, env, continuation);
+ }
+
+ ExpressionState withContinuation(ExpressionContinuation cont) {
+ return new ExpressionState(statementState, environment, cont);
+ }
}
/// Represents a labeled statement, the corresponding continuation and the
/// enclosing label.
class Label {
final LabeledStatement statement;
- final Continuation continuation;
+ final StatementConfiguration continuation;
Dmitry Stefantsov 2017/04/10 14:05:53 "continuation" ==> "configuration"
zhivkag 2017/04/11 11:37:38 Done.
final Label enclosingLabel;
Label(this.statement, this.continuation, this.enclosingLabel);
@@ -268,6 +289,264 @@ 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);
+}
+
+/// Represents the configuration for applying an Expression continuation.
+class ExpressionConfiguration extends Configuration {
+ final Value value;
+ final ExpressionContinuation continuation;
+
+ ExpressionConfiguration(this.value, this.continuation);
+
+ Configuration step(StatementExecuter executer) => continuation(value);
+}
+
+/// Represents an expression continuation.
+abstract class ExpressionContinuation {
+ Configuration call(Value v);
+}
+
+class PrintContinuation extends ExpressionContinuation {
+ final State state;
Dmitry Stefantsov 2017/04/10 14:05:53 I think it's better to have ExpressionState rather
zhivkag 2017/04/11 11:37:39 Done.
+
+ PrintContinuation(this.state);
+
+ Configuration call(Value v) {
+ print(v.value);
+ return state.configuration;
+ }
+}
+
+class PropertyGetContinuation extends ExpressionContinuation {
+ final Name name;
+ final ExpressionState state;
+
+ PropertyGetContinuation(this.name, this.state);
+
+ Configuration call(Value value) {
+ Value propertyValue = value.class_.lookupGetter(name)(value);
+ return new ExpressionConfiguration(propertyValue, state.continuation);
+ }
+}
+
+class PropertySetContinuation extends ExpressionContinuation {
+ final Expression value;
+ final Name setterName;
+ final ExpressionState state;
+ final Evaluator evaluator;
Dmitry Stefantsov 2017/04/10 14:05:53 I don't think we want to have an Evaluator in a fi
zhivkag 2017/04/11 11:37:39 As we discussed offline, we couldn't see an obviou
+
+ PropertySetContinuation(
+ this.value, this.setterName, this.state, this.evaluator);
+
+ Configuration call(Value receiver) {
+ Setter setter = receiver.class_.lookupSetter(setterName);
+ var cont = new SetterContinuation(setter, receiver, state);
+ return evaluator.eval(value, state.withContinuation(cont));
+ }
+}
+
+class SetterContinuation extends ExpressionContinuation {
+ final Setter setter;
+ final Value receiver;
+ final ExpressionState state;
+
+ SetterContinuation(this.setter, this.receiver, this.state);
+
+ Configuration call(Value value) {
+ setter(receiver, value);
+ if (state.continuation != null) {
Dmitry Stefantsov 2017/04/10 14:05:53 I think we may write lines 371-374 as a method "Co
zhivkag 2017/04/11 11:37:38 Done.
+ return new ExpressionConfiguration(value, state.continuation);
+ }
+ return state.statementState.configuration;
+ }
+}
+
+class StaticInvocationContinuation extends ExpressionContinuation {
Dmitry Stefantsov 2017/04/10 14:05:53 Shouldn't this class have a reference to the metho
zhivkag 2017/04/11 11:37:38 With the current implementation we only support ca
+ final ExpressionState state;
+
+ StaticInvocationContinuation(this.state);
+
+ Configuration call(Value value) {
+ if (state.continuation != null) {
+ return new ExpressionConfiguration(value, state.continuation);
+ }
+ return state.statementState.configuration;
+ }
+}
+
+class MethodInvocationContinuation extends ExpressionContinuation {
+ final Arguments arguments;
+ final Name methodName;
+ final ExpressionState state;
+ final Evaluator evaluator;
+
+ MethodInvocationContinuation(
+ this.arguments, this.methodName, this.state, this.evaluator);
+
+ Configuration call(Value value) {
+ if (arguments.positional.isEmpty) {
Dmitry Stefantsov 2017/04/10 14:05:53 I think we may turn this if-statement into a case
zhivkag 2017/04/11 11:37:38 Acknowledged.
+ Value returnValue = value.invokeMethod(methodName);
+ return new ExpressionConfiguration(returnValue, state.continuation);
+ }
+ var cont = new ArgumentsContinuation(value, methodName, state);
+ return evaluator.eval(
+ arguments.positional.first, state.withContinuation(cont));
+ }
+}
+
+// Currently evaluates only one argument, for simple method invocations with 1
+// argument.
+class ArgumentsContinuation extends ExpressionContinuation {
+ final Value receiver;
+ final Name methodName;
+ final ExpressionState state;
+ //final Evaluator evaluator;
+
+ ArgumentsContinuation(this.receiver, this.methodName, this.state);
+
+ Configuration call(Value value) {
+ Value returnValue = receiver.invokeMethod(methodName, value);
+ return new ExpressionConfiguration(returnValue, state.continuation);
+ }
+}
+
+class VariableDeclarationContinuation extends ExpressionContinuation {
Dmitry Stefantsov 2017/04/10 14:05:53 I think variable declaration is not an expression,
zhivkag 2017/04/11 11:37:38 Done.
+ final VariableDeclaration variable;
+ final State state;
+
+ VariableDeclarationContinuation(this.variable, this.state);
+
+ Configuration call(Value value) {
+ state.environment.expand(variable, value);
+ return state.configuration;
+ }
+}
+
+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 ExpressionConfiguration(value, state.continuation);
+ }
+}
+
+class NotContinuation extends ExpressionContinuation {
+ final ExpressionContinuation continuation;
+
+ NotContinuation(this.continuation);
+
+ Configuration call(Value value) {
+ Value notValue = identical(Value.trueInstance, value)
+ ? Value.falseInstance
+ : Value.trueInstance;
+ return new ExpressionConfiguration(notValue, continuation);
+ }
+}
+
+class OrContinuation extends ExpressionContinuation {
+ final ExpressionState state;
+ final Expression right;
+ final Evaluator evaluator;
+
+ OrContinuation(this.state, this.right, this.evaluator);
+
+ Configuration call(Value left) {
+ return identical(Value.trueInstance, left)
+ ? new ExpressionConfiguration(Value.trueInstance, state.continuation)
+ : evaluator.eval(right, state);
+ }
+}
+
+class AndContinuation extends ExpressionContinuation {
+ final ExpressionState state;
+ final Expression right;
+ final Evaluator evaluator; // wth??
+
+ AndContinuation(this.state, this.right, this.evaluator);
+
+ Configuration call(Value left) {
+ return identical(Value.falseInstance, left)
+ ? new ExpressionConfiguration(Value.falseInstance, state.continuation)
+ : evaluator.eval(right, state);
+ }
+}
+
+class ConditionalContinuation extends ExpressionContinuation {
+ final Expression then;
+ final Expression otherwise;
+ final ExpressionState state;
+ final Evaluator evaluator;
+
+ ConditionalContinuation(
+ this.then, this.otherwise, this.state, this.evaluator);
+
+ Configuration call(Value value) {
+ return identical(Value.trueInstance, value)
+ ? evaluator.eval(then, state)
+ : evaluator.eval(otherwise, state);
+ }
+}
+
+class StringConcatenationContinuation extends ExpressionContinuation {
+ final List<Expression> expressions;
+ final ExpressionState state;
+ final Evaluator evaluator;
+
+ int _currentPosition = 0;
+ final List<Value> _values = <Value>[];
+
+ StringConcatenationContinuation(this.expressions, this.state, this.evaluator);
+
+ 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 ExpressionConfiguration(value, state.continuation);
+ }
+ return evaluator.eval(
+ expressions[++_currentPosition], state.withContinuation(this));
+ }
+}
+
+class LetContinuation extends ExpressionContinuation {
+ final VariableDeclaration variable;
+ final Expression letBody;
+ final ExpressionState state;
+ final Evaluator evaluator;
+
+ LetContinuation(this.variable, this.letBody, this.state, this.evaluator);
+
+ Configuration call(Value value) {
+ var letState = state.withEnvironment(new Environment(state.environment));
+ letState.environment.expand(variable, value);
+ return evaluator.eval(letBody, letState);
+ }
+}
+
/// Executes statements.
///
/// Execution of a statement completes in one of the following ways:
@@ -277,95 +556,112 @@ 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) {
+ void trampolinedExecution(Configuration continuation) {
Dmitry Stefantsov 2017/04/10 14:05:53 "continuation" ==> "configuration"
zhivkag 2017/04/11 11:37:38 Done.
while (continuation != null) {
- continuation = exec(continuation.statement, continuation.state);
+ continuation = continuation.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 eval(node.expression, new ExpressionState.withStatementState(state));
}
- Continuation visitBlock(Block node, state) {
+ Configuration visitBlock(Block node, state) {
if (node.statements.isEmpty) {
- return state.continuation;
+ return state.configuration;
}
State blockState =
state.withEnvironment(new Environment(state.environment));
- Continuation cont = state.continuation;
+ StatementConfiguration cont = state.configuration;
Dmitry Stefantsov 2017/04/10 14:05:53 "cont" ==> "configuration"
zhivkag 2017/04/11 11:37:39 Done.
for (Statement s in node.statements.reversed) {
- cont = new Continuation(s, blockState.withContinuation(cont));
+ cont = new StatementConfiguration(s, blockState.withConfiguration(cont));
}
return cont;
}
- Continuation visitEmptyStatement(EmptyStatement node, state) {
- return state.continuation;
+ Configuration visitEmptyStatement(EmptyStatement node, state) {
+ return state.configuration;
}
- Continuation visitIfStatement(IfStatement node, state) {
- Value cond = eval(node.condition, state.environment).toBoolean();
- if (identical(Value.trueInstance, cond)) {
- return new Continuation(node.then, state);
+ Configuration visitIfStatement(IfStatement node, state) {
+ // shortcutting
+ ExpressionConfiguration cont = eval(node.condition, state);
Dmitry Stefantsov 2017/04/10 14:05:53 The variable "state" here is most likely a State,
Dmitry Stefantsov 2017/04/10 14:05:53 "cont" ==> "configuration"
zhivkag 2017/04/11 11:37:38 Here and below are some calls to eval that I misse
zhivkag 2017/04/11 11:37:39 Done.
+ if (identical(Value.trueInstance, cont.value)) {
+ return new StatementConfiguration(node.then, state);
} else if (node.otherwise != null) {
- return new Continuation(node.otherwise, state);
+ return new StatementConfiguration(node.otherwise, state);
}
- return state.continuation;
+ return state.configuration;
}
- 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)) {
+ Configuration visitWhileStatement(WhileStatement node, state) {
+ // shortcutting
+ ExpressionConfiguration cont = eval(node.condition, state.environment);
Dmitry Stefantsov 2017/04/10 14:05:53 Does "eval" accepts an Environment as the second a
Dmitry Stefantsov 2017/04/10 14:05:53 "cont" ==> "configuration"
zhivkag 2017/04/11 11:37:38 eval takes an Expression and an ExpressionState, i
zhivkag 2017/04/11 11:37:38 Done.
+ if (identical(Value.trueInstance, cont.value)) {
// Add continuation for the While statement to the linked list.
- Continuation cont = new Continuation(node, state);
+ StatementConfiguration cont = new StatementConfiguration(node, state);
// Continuation for the body of the loop.
- return new Continuation(node.body, state.withContinuation(cont));
+ return new StatementConfiguration(
+ node.body, state.withConfiguration(cont));
}
- return state.continuation;
+ return state.configuration;
}
- 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 cont =
+ new StatementConfiguration(whileStatement, state);
+ return new StatementConfiguration(node.body, state.withConfiguration(cont));
+ }
+
+ Configuration visitReturnStatement(ReturnStatement node, state) {
+ assert(state.expressionContinuation != null);
+ var expState = new ExpressionState.withStatementState(state);
+ return eval(node.expression, expState);
}
- 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 visitVariableDeclaration(VariableDeclaration node, state) {
+ if (node.initializer != null) {
+ var cont = new VariableDeclarationContinuation(node, state);
Dmitry Stefantsov 2017/04/10 14:05:53 I don't think we should have "VariableDeclarationC
zhivkag 2017/04/11 11:37:38 Done.
+ return eval(node.initializer,
+ new ExpressionState.withStatementState(state).withContinuation(cont));
+ } else {
+ state.environment.expand(node, Value.nullInstance);
+ return state.configuration;
+ }
}
}
+// ------------------------------------------------------------------------
+// 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