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

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

Issue 2975173002: Introduce statement continuations following the specification (Closed)
Patch Set: Apply review comments Created 3 years, 5 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 | pkg/kernel/test/interpreter/interpreter.status » ('j') | 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 31442017fb54cd4f6ad5f2eded0f1db6f6ccefea..7fd29341987282a983252dda249ade90241775a4 100644
--- a/pkg/kernel/lib/interpreter/interpreter.dart
+++ b/pkg/kernel/lib/interpreter/interpreter.dart
@@ -30,8 +30,8 @@ class Interpreter {
if (mainMethod == null) return;
Statement statementBlock = mainMethod.function.body;
- ExecConfiguration configuration =
- new ExecConfiguration(statementBlock, new State.initial());
+ ExecConfiguration configuration = new ExecConfiguration(
+ statementBlock, new Environment.empty(), const State.initial());
visitor.trampolinedExecution(configuration);
}
}
@@ -53,10 +53,6 @@ class Environment {
final List<Binding> bindings = <Binding>[];
final Environment parent;
- Value get thisInstance => (parent != null)
- ? parent.thisInstance
- : throw "Invalid reference to 'this' expression";
-
Environment.empty() : parent = null;
Environment(this.parent);
@@ -84,19 +80,13 @@ class Environment {
lookupBinding(variable).location.value = value;
}
- void expand(VariableDeclaration variable, Value value) {
+ Environment extend(VariableDeclaration variable, Value value) {
assert(!contains(variable));
- bindings.add(new Binding(variable, new Location(value)));
+ return new Environment(this)
+ ..bindings.add(new Binding(variable, new Location(value)));
}
}
-class InstanceEnvironment extends Environment {
- final ObjectValue _thisInstance;
- Value get thisInstance => _thisInstance;
-
- InstanceEnvironment(this._thisInstance, Environment env) : super(env);
-}
-
/// Evaluate expressions.
class Evaluator extends ExpressionVisitor1<Configuration, EvalConfiguration> {
Configuration eval(Expression expr, EvalConfiguration config) =>
@@ -152,7 +142,6 @@ class Evaluator extends ExpressionVisitor1<Configuration, EvalConfiguration> {
StaticInvocation node, EvalConfiguration config) {
if ('print' == node.name.toString()) {
var cont = new PrintEK(config.continuation);
-
return new EvalConfiguration(
node.arguments.positional.first, config.environment, cont);
} else {
@@ -162,7 +151,6 @@ class Evaluator extends ExpressionVisitor1<Configuration, EvalConfiguration> {
_createArgumentExpressionList(node.arguments, node.target.function);
ApplicationContinuation cont =
new StaticInvocationA(node.target.function, config.continuation);
-
return new EvalListConfiguration(args, config.environment, cont);
}
}
@@ -178,14 +166,8 @@ class Evaluator extends ExpressionVisitor1<Configuration, EvalConfiguration> {
}
Configuration visitConstructorInvocation(
- ConstructorInvocation node, EvalConfiguration config) {
- ApplicationContinuation cont =
- new ConstructorInvocationA(node.target, config.continuation);
- var args =
- _createArgumentExpressionList(node.arguments, node.target.function);
-
- return new EvalListConfiguration(args, config.environment, cont);
- }
+ ConstructorInvocation node, EvalConfiguration config) =>
+ defaultExpression(node, config);
Configuration visitNot(Not node, EvalConfiguration config) {
return new EvalConfiguration(
@@ -221,10 +203,8 @@ class Evaluator extends ExpressionVisitor1<Configuration, EvalConfiguration> {
}
Configuration visitThisExpression(
- ThisExpression node, EvalConfiguration config) {
- return new ValuePassingConfiguration(
- config.continuation, config.environment.thisInstance);
- }
+ ThisExpression node, EvalConfiguration config) =>
+ defaultExpression(node, config);
// Evaluation of BasicLiterals.
Configuration visitStringLiteral(
@@ -264,33 +244,30 @@ class Evaluator extends ExpressionVisitor1<Configuration, EvalConfiguration> {
/// Represents a state for statement execution.
class State {
- final Environment environment;
final Label labels;
- final ExecConfiguration statementConfiguration;
-
+ // TODO: Add switch labels.
+ // TODO: Add component for exception support.
final ExpressionContinuation returnContinuation;
+ final StatementContinuation continuation;
- State(this.environment, this.labels, this.statementConfiguration,
- this.returnContinuation);
-
- State.initial() : this(new Environment.empty(), null, null, null);
+ State(this.labels, this.returnContinuation, this.continuation);
- State withEnvironment(Environment env) {
- return new State(env, labels, statementConfiguration, returnContinuation);
- }
+ const State.initial()
+ : labels = null,
+ returnContinuation = null,
+ continuation = null;
- State withBreak(Statement stmt) {
- Label breakLabels = new Label(stmt, statementConfiguration, labels);
- return new State(
- environment, breakLabels, statementConfiguration, returnContinuation);
+ State withBreak(Statement stmt, Environment env) {
+ Label breakLabels = new Label(stmt, env, continuation, labels);
+ return new State(breakLabels, returnContinuation, continuation);
}
- State withConfiguration(Configuration config) {
- return new State(environment, labels, config, returnContinuation);
+ State withReturnContinuation(ExpressionContinuation returnCont) {
+ return new State(labels, returnCont, continuation);
}
- State withExpressionContinuation(ExpressionContinuation cont) {
- return new State(environment, labels, statementConfiguration, cont);
+ State withContinuation(StatementContinuation cont) {
+ return new State(labels, returnContinuation, cont);
}
Label lookupLabel(LabeledStatement s) {
@@ -303,10 +280,12 @@ class State {
/// enclosing label.
class Label {
final LabeledStatement statement;
- final ExecConfiguration configuration;
+ final Environment environment;
+ final StatementContinuation continuation;
final Label enclosingLabel;
- Label(this.statement, this.configuration, this.enclosingLabel);
+ Label(
+ this.statement, this.environment, this.continuation, this.enclosingLabel);
Label lookupLabel(LabeledStatement s) {
if (identical(s, statement)) return this;
@@ -324,7 +303,7 @@ abstract class Configuration {
Configuration step(StatementExecuter executer);
}
-/// Represents the configuration for evaluating an [Expression].
+/// Configuration for evaluating an [Expression].
class EvalConfiguration extends Configuration {
final Expression expression;
@@ -340,11 +319,11 @@ class EvalConfiguration extends Configuration {
executer.eval(expression, this);
}
-/// Represents the configuration for evaluating a list of expressions.
+/// Configuration for evaluating a `List<InterpreterExpression>`.
class EvalListConfiguration extends Configuration {
final List<InterpreterExpression> expressions;
final Environment environment;
- final Continuation continuation;
+ final ApplicationContinuation continuation;
EvalListConfiguration(this.expressions, this.environment, this.continuation);
@@ -352,40 +331,29 @@ class EvalListConfiguration extends Configuration {
executer.evalList(expressions, environment, continuation);
}
-/// Represents the configuration for execution of statement.
+/// Configuration for execution of a [Statement].
class ExecConfiguration extends Configuration {
- final Statement statement;
+ final Statement currentStatement;
+ final Environment environment;
final State state;
- ExecConfiguration(this.statement, this.state);
+ ExecConfiguration(this.currentStatement, this.environment, this.state);
Configuration step(StatementExecuter executer) =>
- executer.exec(statement, state);
+ executer.exec(currentStatement, this);
}
-class ExitConfiguration extends ExecConfiguration {
- final ExpressionContinuation returnContinuation;
-
- ExitConfiguration(this.returnContinuation) : super(null, null);
-
- Configuration step(StatementExecuter _) {
- return returnContinuation(Value.nullInstance);
- }
-}
-
-class NewInstanceConfiguration extends ExecConfiguration {
- final ExpressionContinuation continuation;
- final ObjectValue newObject;
+/// Configuration for applying a [StatementContinuation] to an [Environment].
+class ForwardConfiguration extends Configuration {
+ final StatementContinuation continuation;
+ final Environment environment;
- NewInstanceConfiguration(this.continuation, this.newObject)
- : super(null, new State.initial());
+ ForwardConfiguration(this.continuation, this.environment);
- Configuration step(StatementExecuter _) {
- return continuation(newObject);
- }
+ Configuration step(StatementExecuter _) => continuation?.call(environment);
}
-/// Represents the configuration for applying an [ExpressionContinuation].
+/// Configuration for applying [ExpressionContinuation] to a [Value].
class ValuePassingConfiguration extends Configuration {
final ExpressionContinuation continuation;
final Value value;
@@ -395,7 +363,8 @@ class ValuePassingConfiguration extends Configuration {
Configuration step(StatementExecuter _) => continuation(value);
}
-/// Represents the configuration for applying an [ApplicationContinuation].
+/// Configuration for applying an [ApplicationContinuation] to a
+/// `List<InterpreterValue>`.
class ApplicationConfiguration extends Configuration {
final ApplicationContinuation continuation;
final List<InterpreterValue> values;
@@ -408,6 +377,7 @@ class ApplicationConfiguration extends Configuration {
// ------------------------------------------------------------------------
// Interpreter Expressions and Values
// ------------------------------------------------------------------------
+
abstract class InterpreterExpression {
Expression get expression;
@@ -430,17 +400,6 @@ class NamedExpression extends InterpreterExpression {
InterpreterValue assignValue(Value v) => new NamedValue(name, v);
}
-class LocalInitializerExpression extends InterpreterExpression {
- final VariableDeclaration variable;
-
- Expression get expression => variable.initializer;
-
- LocalInitializerExpression(this.variable);
-
- InterpreterValue assignValue(Value v) =>
- new LocalInitializerValue(variable, v);
-}
-
class FieldInitializerExpression extends InterpreterExpression {
final Field field;
final Expression expression;
@@ -467,13 +426,6 @@ class NamedValue extends InterpreterValue {
NamedValue(this.name, this.value);
}
-class LocalInitializerValue extends InterpreterValue {
- final VariableDeclaration variable;
- final Value value;
-
- LocalInitializerValue(this.variable, this.value);
-}
-
class FieldInitializerValue extends InterpreterValue {
final Field field;
final Value value;
@@ -483,6 +435,84 @@ class FieldInitializerValue extends InterpreterValue {
abstract class Continuation {}
+// ------------------------------------------------------------------------
+// Statement Continuations
+// ------------------------------------------------------------------------
+
+/// Represents a the continuation for the execution of the next statement of
+/// the program.
+///
+/// There are various kinds of [StatementContinuation]s and their names are
+/// suffixed with "SK".
+abstract class StatementContinuation extends Continuation {
+ Configuration call(Environment env);
+}
+
+/// Applies the expression continuation to the provided value.
+class ExitSK extends StatementContinuation {
+ final ExpressionContinuation continuation;
+ final Value value;
+
+ ExitSK(this.continuation, this.value);
+
+ Configuration call(Environment _) =>
+ new ValuePassingConfiguration(continuation, value);
+}
+
+/// Executes the next statement from a block with the corresponding environment
+/// or proceeds with next statement continuation.
+class BlockSK extends StatementContinuation {
+ final List<Statement> statements;
+ final Environment enclosingEnv;
+ final State state;
+
+ BlockSK(this.statements, this.enclosingEnv, this.state);
+
+ BlockSK.fromConfig(this.statements, ExecConfiguration conf)
+ : enclosingEnv = conf.environment,
+ state = conf.state;
+
+ Configuration call(Environment env) {
+ if (statements.isEmpty) {
+ return new ForwardConfiguration(state.continuation, enclosingEnv);
+ }
+ // Proceed with the execution statement when there are some remaining to
+ // be executed.
+ var cont = new BlockSK(statements.skip(1).toList(), enclosingEnv, state);
+ return new ExecConfiguration(
+ statements.first, env, state.withContinuation(cont));
+ }
+}
+
+class NewSK extends StatementContinuation {
+ final ExpressionContinuation continuation;
+ final Location location;
+
+ NewSK(this.continuation, this.location);
+
+ Configuration call(Environment _) =>
+ new ValuePassingConfiguration(continuation, location.value);
+}
+
+class WhileConditionSK extends StatementContinuation {
+ final Expression condition;
+ final Statement body;
+ final Environment enclosingEnv;
+ final State state;
+
+ WhileConditionSK(this.condition, this.body, this.enclosingEnv, this.state);
+
+ Configuration call(Environment _) {
+ // Evaluate the condition for the while loop execution.
+ var cont = new WhileConditionEK(condition, body, enclosingEnv, state);
+ return new EvalConfiguration(condition, enclosingEnv, cont);
+ }
+}
+
+// ------------------------------------------------------------------------
+// Application Continuations
+// ------------------------------------------------------------------------
+
/// Represents the continuation called after the evaluation of argument
/// expressions.
///
@@ -497,14 +527,16 @@ abstract class ApplicationContinuation extends Continuation {
static Environment createEnvironment(
FunctionNode function, List<InterpreterValue> args,
[Environment parentEnv]) {
- Environment newEnv = new Environment(parentEnv);
+ Environment newEnv = new Environment(parentEnv ?? new Environment.empty());
+
List<PositionalValue> positional = args.reversed
.where((InterpreterValue av) => av is PositionalValue)
.toList();
// Add positional parameters.
for (int i = 0; i < positional.length; ++i) {
- newEnv.expand(function.positionalParameters[i], positional[i].value);
+ newEnv =
+ newEnv.extend(function.positionalParameters[i], positional[i].value);
}
Map<String, Value> named = new Map.fromIterable(
@@ -514,13 +546,27 @@ abstract class ApplicationContinuation extends Continuation {
// Add named parameters.
for (VariableDeclaration v in function.namedParameters) {
- newEnv.expand(v, named[v.name.toString()]);
+ newEnv = newEnv.extend(v, named[v.name.toString()]);
}
return newEnv;
}
}
+/// Represents the application continuation called after the evaluation of all
+/// argument expressions for an invocation.
+class ValueA extends ApplicationContinuation {
+ final InterpreterValue value;
+ final ApplicationContinuation applicationContinuation;
+
+ ValueA(this.value, this.applicationContinuation);
+
+ Configuration call(List<InterpreterValue> args) {
+ args.add(value);
+ return new ApplicationConfiguration(applicationContinuation, args);
+ }
+}
+
class StringConcatenationA extends ApplicationContinuation {
final ExpressionContinuation continuation;
@@ -546,276 +592,17 @@ class StaticInvocationA extends ApplicationContinuation {
Configuration call(List<InterpreterValue> argValues) {
Environment functionEnv =
ApplicationContinuation.createEnvironment(function, argValues);
+ State bodyState = new State(
+ null, continuation, new ExitSK(continuation, Value.nullInstance));
- State bodyState = new State.initial()
- .withExpressionContinuation(continuation)
- .withConfiguration(new ExitConfiguration(continuation))
- .withEnvironment(functionEnv);
- return new ExecConfiguration(function.body, bodyState);
- }
-}
-
-/// Represents the application continuation for constructor invocation applied
-/// on the list of evaluated arguments.
-class ConstructorInvocationA extends ApplicationContinuation {
- final Constructor constructor;
- final ExpressionContinuation continuation;
-
- ConstructorInvocationA(this.constructor, this.continuation);
-
- Configuration call(List<InterpreterValue> argValues) {
- Environment ctrEnv = ApplicationContinuation.createEnvironment(
- constructor.function, argValues);
-
- var class_ = new Class(constructor.enclosingClass.reference);
- var newObject =
- new ObjectValue(class_, new List<Value>(class_.instanceSize));
-
- return new ObjectInitializationConfiguration(
- constructor,
- new InstanceEnvironment(newObject, ctrEnv),
- new NewInstanceConfiguration(continuation, newObject));
- }
-}
-
-/// Represents the application continuation for redirecting constructor
-/// invocation applied on the list of evaluated arguments.
-class RedirectingConstructorA extends ApplicationContinuation {
- final Constructor constructor;
- final Environment environment;
- final ExecConfiguration configuration;
-
- RedirectingConstructorA(
- this.constructor, this.environment, this.configuration);
-
- Configuration call(List<InterpreterValue> argValues) {
- Value object = environment.thisInstance;
- Environment ctrEnv = ApplicationContinuation.createEnvironment(
- constructor.function,
- argValues,
- new InstanceEnvironment(object, new Environment.empty()));
-
- return new ObjectInitializationConfiguration(
- constructor, ctrEnv, configuration);
- }
-}
-
-/// Represents the application continuation for super constructor
-/// invocation applied on the list of evaluated arguments.
-class SuperConstructorA extends ApplicationContinuation {
- final Constructor constructor;
- final Environment environment;
- final ExecConfiguration configuration;
-
- SuperConstructorA(this.constructor, this.environment, this.configuration);
-
- Configuration call(List<InterpreterValue> argValues) {
- Value object = environment.thisInstance;
-
- Environment superEnv = ApplicationContinuation.createEnvironment(
- constructor.function,
- argValues,
- new InstanceEnvironment(object, new Environment.empty()));
-
- return new ObjectInitializationConfiguration(
- constructor, superEnv, configuration);
- }
-}
-
-/// Represents the configuration for execution of initializer and
-/// constructor body statements for initialization of a newly allocated object.
-class ObjectInitializationConfiguration extends Configuration {
- final Constructor constructor;
- final Environment environment;
- final ExecConfiguration configuration;
-
- ObjectInitializationConfiguration(
- this.constructor, this.environment, this.configuration);
-
- Configuration step(StatementExecuter _) {
- if (constructor.initializers.isNotEmpty &&
- constructor.initializers.last is RedirectingInitializer) {
- // Constructor is redirecting.
- Initializer initializer = constructor.initializers.first;
- if (initializer is RedirectingInitializer) {
- var app = new RedirectingConstructorA(
- initializer.target, environment, configuration);
- var args = _createArgumentExpressionList(
- initializer.arguments, initializer.target.function);
-
- return new EvalListConfiguration(args, environment, app);
- }
- // Redirecting initializer is not the only initializer.
- for (Initializer i in constructor.initializers.reversed.skip(1)) {
- assert(i is LocalInitializer);
- }
- var class_ = new Class(constructor.enclosingClass.reference);
- var initEnv = new Environment(environment);
- var cont = new InitializerEK(
- class_, initEnv, constructor.initializers, configuration);
- return new EvalConfiguration(
- (initializer as LocalInitializer).variable.initializer,
- initEnv,
- cont);
- }
-
- // Set head of configurations to be executed to configuration for current
- // constructor body.
- var state = new State.initial()
- .withEnvironment(environment)
- .withConfiguration(configuration);
- var bodyConfig = new ExecConfiguration(constructor.function.body, state);
-
- // Initialize fields in immediately enclosing class.
- var cont = new InstanceFieldsA(constructor, environment, bodyConfig);
- var fieldExpressions = _createInstanceInitializers(constructor);
-
- return new EvalListConfiguration(
- fieldExpressions, new Environment.empty(), cont);
- }
-
- /// Creates a list of expressions for instance field initializers in
- /// immediately enclosing class.
- static List<InterpreterExpression> _createInstanceInitializers(
- Constructor ctr) {
- Class currentClass = new Class(ctr.enclosingClass.reference);
- List<InterpreterExpression> es = <InterpreterExpression>[];
-
- for (int i = currentClass.superclass?.instanceSize ?? 0;
- i < currentClass.instanceSize;
- i++) {
- Field current = currentClass.instanceFields[i];
- if (current.initializer != null) {
- es.add(new FieldInitializerExpression(current, current.initializer));
- }
- }
-
- return es;
- }
-}
-
-/// Represents the application continuation applied on the list of evaluated
-/// field initializer expressions.
-class InstanceFieldsA extends ApplicationContinuation {
- final Constructor constructor;
- final Environment environment;
- final ExecConfiguration configuration;
-
- final Class _currentClass;
- final ObjectValue _newObject;
-
- InstanceFieldsA(this.constructor, this.environment, this.configuration)
- : _currentClass = new Class(constructor.enclosingClass.reference),
- _newObject = environment.thisInstance;
-
- Configuration call(List<InterpreterValue> fieldValues) {
- for (FieldInitializerValue current in fieldValues.reversed) {
- _currentClass.setProperty(_newObject, current.field, current.value);
- }
-
- if (constructor.initializers.isEmpty) {
- _initializeNullFields(_currentClass, _newObject);
- return configuration;
- }
-
- // Produce next configuration.
- if (constructor.initializers.first is SuperInitializer) {
- // SuperInitializer appears last in the initializer list.
- assert(constructor.initializers.length == 1);
- SuperInitializer current = constructor.initializers.first;
- var args = _createArgumentExpressionList(
- current.arguments, current.target.function);
-
- var superApp =
- new SuperConstructorA(current.target, environment, configuration);
- _initializeNullFields(_currentClass, _newObject);
- return new EvalListConfiguration(args, environment, superApp);
- }
-
- Class class_ = new Class(constructor.enclosingClass.reference);
- Environment initEnv = new Environment(environment);
-
- var cont = new InitializerEK(
- class_, initEnv, constructor.initializers, configuration);
- return new EvalConfiguration(
- _getExpression(constructor.initializers.first), initEnv, cont);
- }
-}
-
-/// Represents the expression continuation applied on the list of evaluated
-/// initializer expressions preceding a super call in the list.
-class InitializerEK extends ExpressionContinuation {
- final Class currentClass;
- final Environment initializerEnvironment;
- final List<Initializer> initializers;
- final ExecConfiguration configuration;
-
- InitializerEK(this.currentClass, this.initializerEnvironment,
- this.initializers, this.configuration);
-
- Configuration call(Value v) {
- ObjectValue newObject = initializerEnvironment.thisInstance;
- Initializer current = initializers.first;
- if (current is FieldInitializer) {
- currentClass.setProperty(newObject, current.field, v);
- } else if (current is LocalInitializer) {
- initializerEnvironment.expand(current.variable, v);
- } else {
- throw 'Assigning value $v to ${current.runtimeType}';
- }
-
- if (initializers.length <= 1) {
- _initializeNullFields(currentClass, newObject);
- return configuration;
- }
-
- Initializer next = initializers[1];
-
- if (next is RedirectingInitializer) {
- // RedirectingInitializer appears last in the initializer list.
- assert(initializers.length == 2);
- var app = new RedirectingConstructorA(
- next.target, initializerEnvironment, configuration);
- var args =
- _createArgumentExpressionList(next.arguments, next.target.function);
- return new EvalListConfiguration(args, initializerEnvironment, app);
- }
-
- if (next is SuperInitializer) {
- // SuperInitializer appears last in the initializer list.
- assert(initializers.length == 2);
- var args =
- _createArgumentExpressionList(next.arguments, next.target.function);
- var superApp = new SuperConstructorA(
- next.target, initializerEnvironment, configuration);
- _initializeNullFields(currentClass, newObject);
- return new EvalListConfiguration(args, initializerEnvironment, superApp);
- }
-
- var cont = new InitializerEK(currentClass, initializerEnvironment,
- initializers.skip(1).toList(), configuration);
- return new EvalConfiguration(
- _getExpression(next), initializerEnvironment, cont);
- }
-}
-
-/// Represents the application continuation called after the evaluation of all
-/// argument expressions for an invocation.
-class ValueA extends ApplicationContinuation {
- final InterpreterValue value;
- final ApplicationContinuation applicationContinuation;
-
- ValueA(this.value, this.applicationContinuation);
-
- Configuration call(List<InterpreterValue> args) {
- args.add(value);
- return new ApplicationConfiguration(applicationContinuation, args);
+ return new ExecConfiguration(function.body, functionEnv, bodyState);
}
}
// ------------------------------------------------------------------------
// Expression Continuations
// ------------------------------------------------------------------------
+
/// Represents an expression continuation.
///
/// There are various kinds of [ExpressionContinuation]s and their names are
@@ -827,12 +614,13 @@ abstract class ExpressionContinuation extends Continuation {
/// Represents a continuation that returns the next [ExecConfiguration]
/// to be executed.
class ExpressionEK extends ExpressionContinuation {
- final ExecConfiguration configuration;
+ final StatementContinuation continuation;
+ final Environment environment;
- ExpressionEK(this.configuration);
+ ExpressionEK(this.continuation, this.environment);
Configuration call(Value _) {
- return configuration;
+ return new ForwardConfiguration(continuation, environment);
}
}
@@ -1026,27 +814,27 @@ class LetEK extends ExpressionContinuation {
Configuration call(Value value) {
var letEnv = new Environment(environment);
- letEnv.expand(variable, value);
+ letEnv.extend(variable, value);
return new EvalConfiguration(letBody, letEnv, continuation);
}
}
/// Represents the continuation for the condition expression in [WhileStatement].
class WhileConditionEK extends ExpressionContinuation {
- final WhileStatement node;
+ final Expression condition;
+ final Statement body;
+ final Environment enclosingEnv;
final State state;
- WhileConditionEK(this.node, this.state);
+ WhileConditionEK(this.condition, this.body, this.enclosingEnv, this.state);
- ExecConfiguration call(Value v) {
- if (identical(v, Value.trueInstance)) {
- // Add configuration for the While statement to the linked list.
- ExecConfiguration config = new ExecConfiguration(node, state);
- // Configuration for the body of the loop.
- return new ExecConfiguration(node.body, state.withConfiguration(config));
+ Configuration call(Value v) {
+ if (identical(v, Value.falseInstance)) {
+ return new ForwardConfiguration(state.continuation, enclosingEnv);
}
-
- return state.statementConfiguration;
+ var cont = new WhileConditionSK(condition, body, enclosingEnv, state);
+ return new ExecConfiguration(
+ body, enclosingEnv, state.withContinuation(cont));
}
}
@@ -1054,19 +842,20 @@ class WhileConditionEK extends ExpressionContinuation {
class IfConditionEK extends ExpressionContinuation {
final Statement then;
final Statement otherwise;
+ final Environment environment;
final State state;
- IfConditionEK(this.then, this.otherwise, this.state);
+ IfConditionEK(this.then, this.otherwise, this.environment, this.state);
- ExecConfiguration call(Value v) {
+ Configuration call(Value v) {
if (identical(v, Value.trueInstance)) {
log.info("if-then\n");
- return new ExecConfiguration(then, state);
+ return new ExecConfiguration(then, environment, state);
} else if (otherwise != null) {
log.info("if-otherwise\n");
- return new ExecConfiguration(otherwise, state);
+ return new ExecConfiguration(otherwise, environment, state);
}
- return state.statementConfiguration;
+ return new ForwardConfiguration(state.continuation, environment);
}
}
@@ -1075,27 +864,28 @@ class IfConditionEK extends ExpressionContinuation {
class VariableInitializerEK extends ExpressionContinuation {
final VariableDeclaration variable;
final Environment environment;
- final ExecConfiguration nextConfiguration;
+ final StatementContinuation continuation;
- VariableInitializerEK(
- this.variable, this.environment, this.nextConfiguration);
+ VariableInitializerEK(this.variable, this.environment, this.continuation);
- ExecConfiguration call(Value v) {
- environment.expand(variable, v);
- return nextConfiguration;
+ Configuration call(Value v) {
+ return new ForwardConfiguration(
+ continuation, environment.extend(variable, v));
}
}
/// Executes statements.
///
/// Execution of a statement completes in one of the following ways:
-/// - it completes normally, in which case the execution proceeds to applying
-/// the next continuation
-/// - it breaks with a label, in which case the corresponding continuation is
-/// returned and applied
-/// - it returns with or without value, TBD
-/// - it throws, TBD
-class StatementExecuter extends StatementVisitor1<Configuration, State> {
+/// - It completes normally, in which case the execution proceeds to applying
+/// the next continuation.
+/// - It breaks with a label, in which case the corresponding continuation is
+/// returned and applied.
+/// - It returns with or without value, in which case the return continuation is
+/// returned and applied accordingly.
+/// - It throws, in which case the handler is returned and applied accordingly.
+class StatementExecuter
+ extends StatementVisitor1<Configuration, ExecConfiguration> {
Evaluator evaluator = new Evaluator();
void trampolinedExecution(Configuration configuration) {
@@ -1104,98 +894,104 @@ class StatementExecuter extends StatementVisitor1<Configuration, State> {
}
}
- Configuration exec(Statement statement, State state) =>
- statement.accept1(this, state);
+ Configuration exec(Statement statement, ExecConfiguration conf) =>
+ statement.accept1(this, conf);
Configuration eval(Expression expression, EvalConfiguration config) =>
evaluator.eval(expression, config);
Configuration evalList(
List<InterpreterExpression> es, Environment env, Continuation cont) =>
evaluator.evalList(es, env, cont);
- Configuration defaultStatement(Statement node, State state) {
+ Configuration defaultStatement(Statement node, ExecConfiguration conf) {
throw notImplemented(
m: "Execution is not implemented for statement:\n$node ");
}
- Configuration visitInvalidStatement(InvalidStatement node, State state) {
+ Configuration visitInvalidStatement(
+ InvalidStatement node, ExecConfiguration conf) {
throw "Invalid statement at ${node.location}";
}
Configuration visitExpressionStatement(
- ExpressionStatement node, State state) {
- var cont = new ExpressionEK(state.statementConfiguration);
- return new EvalConfiguration(node.expression, state.environment, cont);
+ ExpressionStatement node, ExecConfiguration conf) {
+ var cont = new ExpressionEK(conf.state.continuation, conf.environment);
+ return new EvalConfiguration(node.expression, conf.environment, cont);
}
- Configuration visitBlock(Block node, State state) {
+ Configuration visitBlock(Block node, ExecConfiguration conf) {
if (node.statements.isEmpty) {
- return state.statementConfiguration;
- }
- State blockState =
- state.withEnvironment(new Environment(state.environment));
- ExecConfiguration configuration = state.statementConfiguration;
- for (Statement s in node.statements.reversed) {
- configuration =
- new ExecConfiguration(s, blockState.withConfiguration(configuration));
+ return new ForwardConfiguration(
+ conf.state.continuation, conf.environment);
}
- return configuration;
+
+ var env = new Environment(conf.environment);
+ var cont = new BlockSK.fromConfig(node.statements.skip(1).toList(), conf);
+ return new ExecConfiguration(
+ node.statements.first, env, conf.state.withContinuation(cont));
}
- Configuration visitEmptyStatement(EmptyStatement node, State state) {
- return state.statementConfiguration;
+ Configuration visitEmptyStatement(
+ EmptyStatement node, ExecConfiguration conf) {
+ return new ForwardConfiguration(conf.state.continuation, conf.environment);
}
- Configuration visitIfStatement(IfStatement node, State state) {
- var cont = new IfConditionEK(node.then, node.otherwise, state);
+ Configuration visitIfStatement(IfStatement node, ExecConfiguration conf) {
+ var cont = new IfConditionEK(
+ node.then, node.otherwise, conf.environment, conf.state);
- return new EvalConfiguration(node.condition, state.environment, cont);
+ return new EvalConfiguration(node.condition, conf.environment, cont);
}
- Configuration visitLabeledStatement(LabeledStatement node, State state) {
- return new ExecConfiguration(node.body, state.withBreak(node));
+ Configuration visitLabeledStatement(
+ LabeledStatement node, ExecConfiguration conf) {
+ return new ExecConfiguration(node.body, conf.environment,
+ conf.state.withBreak(node, conf.environment));
}
- Configuration visitBreakStatement(BreakStatement node, State state) {
- return state.lookupLabel(node.target).configuration;
+ Configuration visitBreakStatement(
+ BreakStatement node, ExecConfiguration conf) {
+ Label l = conf.state.lookupLabel(node.target);
+ return new ForwardConfiguration(l.continuation, l.environment);
}
- Configuration visitWhileStatement(WhileStatement node, State state) {
- var cont = new WhileConditionEK(node, state);
+ Configuration visitWhileStatement(
+ WhileStatement node, ExecConfiguration conf) {
+ var cont = new WhileConditionEK(
+ node.condition, node.body, conf.environment, conf.state);
- return new EvalConfiguration(node.condition, state.environment, cont);
+ return new EvalConfiguration(node.condition, conf.environment, cont);
}
- Configuration visitDoStatement(DoStatement node, State state) {
- WhileStatement whileStatement =
- new WhileStatement(node.condition, node.body);
- ExecConfiguration configuration =
- new ExecConfiguration(whileStatement, state);
+ Configuration visitDoStatement(DoStatement node, ExecConfiguration conf) {
+ var cont = new WhileConditionSK(
+ node.condition, node.body, conf.environment, conf.state);
return new ExecConfiguration(
- node.body, state.withConfiguration(configuration));
+ node.body, conf.environment, conf.state.withContinuation(cont));
}
- Configuration visitReturnStatement(ReturnStatement node, State state) {
- assert(state.returnContinuation != null);
+ Configuration visitReturnStatement(
+ ReturnStatement node, ExecConfiguration conf) {
+ assert(conf.state.returnContinuation != null);
log.info('return\n');
if (node.expression == null) {
return new ValuePassingConfiguration(
- state.returnContinuation, Value.nullInstance);
+ conf.state.returnContinuation, Value.nullInstance);
}
return new EvalConfiguration(
- node.expression, state.environment, state.returnContinuation);
+ node.expression, conf.environment, conf.state.returnContinuation);
}
Configuration visitVariableDeclaration(
- VariableDeclaration node, State state) {
+ VariableDeclaration node, ExecConfiguration conf) {
if (node.initializer != null) {
var cont = new VariableInitializerEK(
- node, state.environment, state.statementConfiguration);
- return new EvalConfiguration(node.initializer, state.environment, cont);
+ node, conf.environment, conf.state.continuation);
+ return new EvalConfiguration(node.initializer, conf.environment, cont);
}
- state.environment.expand(node, Value.nullInstance);
- return state.statementConfiguration;
+ return new ForwardConfiguration(conf.state.continuation,
+ conf.environment.extend(node, Value.nullInstance));
}
}
« no previous file with comments | « no previous file | pkg/kernel/test/interpreter/interpreter.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698