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

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

Issue 2980733002: Refactor the interpeter according the specification for Kernel semantics (Closed)
Patch Set: 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 a232e75363f8a0475e3376401452a88448a6651a..3c03c70da76346a5d873306d833a19365bbc8033 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,9 +53,11 @@ class Environment {
final List<Binding> bindings = <Binding>[];
final Environment parent;
- Value get thisInstance => (parent != null)
- ? parent.thisInstance
- : throw "Invalid reference to 'this' expression";
+ Value get thisInstance {
+ return containsThis()
+ ? lookupThis().value
+ : throw "Invalid reference to 'this' expression";
+ }
Environment.empty() : parent = null;
Environment(this.parent);
@@ -67,6 +69,13 @@ class Environment {
return parent?.contains(variable) ?? false;
}
+ bool containsThis() {
+ for (Binding b in bindings.reversed) {
+ if (identical(b.variable.name, 'this')) return true;
+ }
+ return parent?.containsThis() ?? false;
+ }
+
Binding lookupBinding(VariableDeclaration variable) {
assert(contains(variable));
for (Binding b in bindings) {
@@ -75,6 +84,14 @@ class Environment {
return parent.lookupBinding(variable);
}
+ Location lookupThis() {
+ assert(containsThis());
+ for (Binding b in bindings) {
+ if (identical(b.variable.name, 'this')) return b.location;
+ }
+ return parent.lookupThis();
+ }
+
Value lookup(VariableDeclaration variable) {
return lookupBinding(variable).location.value;
}
@@ -84,17 +101,16 @@ 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);
+ Environment extendWithThis(ObjectValue v) {
+ assert(!containsThis());
+ return extend(new VariableDeclaration('this'), v);
+ }
}
/// Evaluate expressions.
@@ -106,7 +122,7 @@ class Evaluator extends ExpressionVisitor1<Configuration, EvalConfiguration> {
ApplicationContinuation cont) {
if (list.isNotEmpty) {
return new EvalConfiguration(list.first.expression, env,
- new ExpressionListContinuation(list.first, list.skip(1), env, cont));
+ new ExpressionListEK(list.first, list.skip(1), env, cont));
}
return new ApplicationConfiguration(cont, <InterpreterValue>[]);
}
@@ -127,18 +143,18 @@ class Evaluator extends ExpressionVisitor1<Configuration, EvalConfiguration> {
}
Configuration visitVariableSet(VariableSet node, EvalConfiguration config) {
- var cont = new VariableSetContinuation(
+ var cont = new VariableSetEK(
node.variable, config.environment, config.continuation);
return new EvalConfiguration(node.value, config.environment, cont);
}
Configuration visitPropertyGet(PropertyGet node, EvalConfiguration config) {
- var cont = new PropertyGetContinuation(node.name, config.continuation);
+ var cont = new PropertyGetEK(node.name, config.continuation);
return new EvalConfiguration(node.receiver, config.environment, cont);
}
Configuration visitPropertySet(PropertySet node, EvalConfiguration config) {
- var cont = new PropertySetContinuation(
+ var cont = new PropertySetEK(
node.value, node.name, config.environment, config.continuation);
return new EvalConfiguration(node.receiver, config.environment, cont);
}
@@ -151,7 +167,7 @@ class Evaluator extends ExpressionVisitor1<Configuration, EvalConfiguration> {
Configuration visitStaticInvocation(
StaticInvocation node, EvalConfiguration config) {
if ('print' == node.name.toString()) {
- var cont = new PrintContinuation(config.continuation);
+ var cont = new PrintEK(config.continuation);
return new EvalConfiguration(
node.arguments.positional.first, config.environment, cont);
} else {
@@ -159,8 +175,8 @@ class Evaluator extends ExpressionVisitor1<Configuration, EvalConfiguration> {
List<InterpreterExpression> args =
_createArgumentExpressionList(node.arguments, node.target.function);
- ApplicationContinuation cont = new StaticInvocationApplication(
- node.target.function, config.continuation);
+ ApplicationContinuation cont =
+ new StaticInvocationA(node.target.function, config.continuation);
return new EvalListConfiguration(args, config.environment, cont);
}
}
@@ -169,51 +185,43 @@ class Evaluator extends ExpressionVisitor1<Configuration, EvalConfiguration> {
MethodInvocation node, EvalConfiguration config) {
// Currently supports only method invocation with <2 arguments and is used
// to evaluate implemented operators for int, double and String values.
- var cont = new MethodInvocationContinuation(
+ var cont = new MethodInvocationEK(
node.arguments, node.name, config.environment, config.continuation);
return new EvalConfiguration(node.receiver, config.environment, cont);
}
Configuration visitConstructorInvocation(
- ConstructorInvocation node, EvalConfiguration config) {
- ApplicationContinuation cont =
- new ConstructorInvocationApplication(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(node.operand, config.environment,
- new NotContinuation(config.continuation));
+ return new EvalConfiguration(
+ node.operand, config.environment, new NotEK(config.continuation));
}
Configuration visitLogicalExpression(
LogicalExpression node, EvalConfiguration config) {
if ('||' == node.operator) {
- var cont = new OrContinuation(
- node.right, config.environment, config.continuation);
+ var cont = new OrEK(node.right, config.environment, config.continuation);
return new EvalConfiguration(node.left, config.environment, cont);
} else {
assert('&&' == node.operator);
- var cont = new AndContinuation(
- node.right, config.environment, config.continuation);
+ var cont = new AndEK(node.right, config.environment, config.continuation);
return new EvalConfiguration(node.left, config.environment, cont);
}
}
Configuration visitConditionalExpression(
ConditionalExpression node, EvalConfiguration config) {
- var cont = new ConditionalContinuation(
+ var cont = new ConditionalEK(
node.then, node.otherwise, config.environment, config.continuation);
return new EvalConfiguration(node.condition, config.environment, cont);
}
Configuration visitStringConcatenation(
StringConcatenation node, EvalConfiguration config) {
- var cont = new StringConcatenationContinuation(config.continuation);
+ var cont = new StringConcatenationA(config.continuation);
var expressions = node.expressions
.map((Expression e) => new PositionalExpression(e))
.toList();
@@ -255,7 +263,7 @@ class Evaluator extends ExpressionVisitor1<Configuration, EvalConfiguration> {
}
Configuration visitLet(Let node, EvalConfiguration config) {
- var letCont = new LetContinuation(
+ var letCont = new LetEK(
node.variable, node.body, config.environment, config.continuation);
return new EvalConfiguration(
node.variable.initializer, config.environment, letCont);
@@ -264,33 +272,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(this.labels, this.returnContinuation, this.continuation);
- State.initial() : this(new Environment.empty(), null, null, null);
-
- 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 +308,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;
@@ -315,45 +322,66 @@ class Label {
}
}
+// ------------------------------------------------------------------------
+// Configurations
+// ------------------------------------------------------------------------
+
abstract class Configuration {
/// Executes the current and returns the next configuration.
Configuration step(StatementExecuter executer);
}
-/// Represents the configuration for execution of statement.
-class ExecConfiguration extends Configuration {
- final Statement statement;
- final State state;
+/// Configuration for evaluating an [Expression].
+class EvalConfiguration extends Configuration {
+ final Expression expression;
+
+ /// Environment in which the expression is evaluated.
+ final Environment environment;
+
+ /// Next continuation to be applied.
+ final Continuation continuation;
- ExecConfiguration(this.statement, this.state);
+ EvalConfiguration(this.expression, this.environment, this.continuation);
Configuration step(StatementExecuter executer) =>
- executer.exec(statement, state);
+ executer.eval(expression, this);
}
-class ExitConfiguration extends ExecConfiguration {
- final ExpressionContinuation returnContinuation;
+/// Configuration for evaluating a [List<InterpreterExpression>].
+class EvalListConfiguration extends Configuration {
+ final List<InterpreterExpression> expressions;
+ final Environment environment;
+ final ApplicationContinuation continuation;
- ExitConfiguration(this.returnContinuation) : super(null, null);
+ EvalListConfiguration(this.expressions, this.environment, this.continuation);
- Configuration step(StatementExecuter _) {
- return returnContinuation(Value.nullInstance);
- }
+ Configuration step(StatementExecuter executer) =>
+ executer.evalList(expressions, environment, continuation);
}
-class NewInstanceConfiguration extends ExecConfiguration {
- final ExpressionContinuation continuation;
- final ObjectValue newObject;
+/// Configuration for execution of a [Statement].
+class ExecConfiguration extends Configuration {
+ final Statement currentStatement;
+ final Environment environment;
+ final State state;
- NewInstanceConfiguration(this.continuation, this.newObject)
- : super(null, new State.initial());
+ ExecConfiguration(this.currentStatement, this.environment, this.state);
- Configuration step(StatementExecuter _) {
- return continuation(newObject);
- }
+ Configuration step(StatementExecuter executer) =>
+ executer.exec(currentStatement, this);
+}
+
+/// Configuration for applying a [StatementContinuation] to an [Environment].
+class ForwardConfiguration extends Configuration {
+ final StatementContinuation continuation;
+ final Environment environment;
+
+ ForwardConfiguration(this.continuation, this.environment);
+
+ 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;
@@ -363,7 +391,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;
@@ -373,33 +402,9 @@ class ApplicationConfiguration extends Configuration {
Configuration step(StatementExecuter _) => continuation(values);
}
-/// Represents the configuration for evaluating an [Expression].
-class EvalConfiguration extends Configuration {
- final Expression expression;
-
- /// Environment in which the expression is evaluated.
- final Environment environment;
-
- /// Next continuation to be applied.
- final Continuation continuation;
-
- EvalConfiguration(this.expression, this.environment, this.continuation);
-
- Configuration step(StatementExecuter executer) =>
- executer.eval(expression, this);
-}
-
-/// Represents the configuration for evaluating a list of expressions.
-class EvalListConfiguration extends Configuration {
- final List<InterpreterExpression> expressions;
- final Environment environment;
- final Continuation continuation;
-
- EvalListConfiguration(this.expressions, this.environment, this.continuation);
-
- Configuration step(StatementExecuter executer) =>
- executer.evalList(expressions, environment, continuation);
-}
+// ------------------------------------------------------------------------
+// Interpreter Expressions and Values
+// ------------------------------------------------------------------------
abstract class InterpreterExpression {
Expression get expression;
@@ -423,17 +428,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;
@@ -460,13 +454,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;
@@ -476,8 +463,89 @@ 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.
+///
+/// There are various kinds of [ApplicationContinuation] and their names are
+/// suffixed with "A".
abstract class ApplicationContinuation extends Continuation {
Configuration call(List<InterpreterValue> values);
@@ -487,14 +555,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(
@@ -504,314 +574,88 @@ 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 for static invocation.
-class StaticInvocationApplication extends ApplicationContinuation {
- final FunctionNode function;
- final ExpressionContinuation continuation;
-
- StaticInvocationApplication(this.function, this.continuation);
+/// 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;
- Configuration call(List<InterpreterValue> argValues) {
- Environment functionEnv =
- ApplicationContinuation.createEnvironment(function, argValues);
+ ValueA(this.value, this.applicationContinuation);
- State bodyState = new State.initial()
- .withExpressionContinuation(continuation)
- .withConfiguration(new ExitConfiguration(continuation))
- .withEnvironment(functionEnv);
- return new ExecConfiguration(function.body, bodyState);
+ Configuration call(List<InterpreterValue> args) {
+ args.add(value);
+ return new ApplicationConfiguration(applicationContinuation, args);
}
}
-/// Represents the application continuation for constructor invocation applied
-/// on the list of evaluated arguments.
-class ConstructorInvocationApplication extends ApplicationContinuation {
- final Constructor constructor;
+class StringConcatenationA extends ApplicationContinuation {
final ExpressionContinuation continuation;
- ConstructorInvocationApplication(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 RedirectingConstructorApplication extends ApplicationContinuation {
- final Constructor constructor;
- final Environment environment;
- final ExecConfiguration configuration;
-
- RedirectingConstructorApplication(
- this.constructor, this.environment, this.configuration);
+ StringConcatenationA(this.continuation);
- 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 SuperConstructorApplication extends ApplicationContinuation {
- final Constructor constructor;
- final Environment environment;
- final ExecConfiguration configuration;
-
- SuperConstructorApplication(
- 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 RedirectingConstructorApplication(
- 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 InitializerContinuation(
- 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 InstanceFieldsApplication(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 InstanceFieldsApplication extends ApplicationContinuation {
- final Constructor constructor;
- final Environment environment;
- final ExecConfiguration configuration;
-
- final Class _currentClass;
- final ObjectValue _newObject;
-
- InstanceFieldsApplication(
- 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 SuperConstructorApplication(
- current.target, environment, configuration);
- _initializeNullFields(_currentClass, _newObject);
- return new EvalListConfiguration(args, environment, superApp);
+ Configuration call(List<InterpreterValue> values) {
+ StringBuffer result = new StringBuffer();
+ for (InterpreterValue v in values.reversed) {
+ result.write(v.value.value);
}
-
- Class class_ = new Class(constructor.enclosingClass.reference);
- Environment initEnv = new Environment(environment);
-
- var cont = new InitializerContinuation(
- class_, initEnv, constructor.initializers, configuration);
- return new EvalConfiguration(
- _getExpression(constructor.initializers.first), initEnv, cont);
+ return new ValuePassingConfiguration(
+ continuation, new StringValue(result.toString()));
}
}
-/// Represents the expression continuation applied on the list of evaluated
-/// initializer expressions preceding a super call in the list.
-class InitializerContinuation extends ExpressionContinuation {
- final Class currentClass;
- final Environment initializerEnvironment;
- final List<Initializer> initializers;
- final ExecConfiguration configuration;
-
- InitializerContinuation(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];
+/// Represents the application continuation for static invocation.
+class StaticInvocationA extends ApplicationContinuation {
+ final FunctionNode function;
+ final ExpressionContinuation continuation;
- if (next is RedirectingInitializer) {
- // RedirectingInitializer appears last in the initializer list.
- assert(initializers.length == 2);
- var app = new RedirectingConstructorApplication(
- next.target, initializerEnvironment, configuration);
- var args =
- _createArgumentExpressionList(next.arguments, next.target.function);
- return new EvalListConfiguration(args, initializerEnvironment, app);
- }
+ StaticInvocationA(this.function, this.continuation);
- 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 SuperConstructorApplication(
- next.target, initializerEnvironment, configuration);
- _initializeNullFields(currentClass, newObject);
- return new EvalListConfiguration(args, initializerEnvironment, superApp);
- }
+ Configuration call(List<InterpreterValue> argValues) {
+ Environment functionEnv =
+ ApplicationContinuation.createEnvironment(function, argValues);
+ State bodyState = new State(
+ null, continuation, new ExitSK(continuation, Value.nullInstance));
- var cont = new InitializerContinuation(currentClass, initializerEnvironment,
- initializers.skip(1).toList(), configuration);
- return new EvalConfiguration(
- _getExpression(next), initializerEnvironment, cont);
+ return new ExecConfiguration(function.body, functionEnv, bodyState);
}
}
-/// Represents the application continuation called after the evaluation of all
-/// argument expressions for an invocation.
-class ValueApplication extends ApplicationContinuation {
- final InterpreterValue value;
- final ApplicationContinuation applicationContinuation;
-
- ValueApplication(this.value, this.applicationContinuation);
-
- Configuration call(List<InterpreterValue> args) {
- args.add(value);
- return new ApplicationConfiguration(applicationContinuation, args);
- }
-}
+// ------------------------------------------------------------------------
+// Expression Continuations
+// ------------------------------------------------------------------------
/// Represents an expression continuation.
+///
+/// There are various kinds of [ExpressionContinuation]s and their names are
+/// suffixed with "EK".
abstract class ExpressionContinuation extends Continuation {
Configuration call(Value v);
}
/// Represents a continuation that returns the next [ExecConfiguration]
/// to be executed.
-class ExpressionStatementContinuation extends ExpressionContinuation {
- final ExecConfiguration configuration;
+class ExpressionSK extends ExpressionContinuation {
+ final StatementContinuation continuation;
+ final Environment environment;
- ExpressionStatementContinuation(this.configuration);
+ ExpressionSK(this.continuation, this.environment);
Configuration call(Value _) {
- return configuration;
+ return new ForwardConfiguration(continuation, environment);
}
}
-class PrintContinuation extends ExpressionContinuation {
+class PrintEK extends ExpressionContinuation {
final ExpressionContinuation continuation;
- PrintContinuation(this.continuation);
+ PrintEK(this.continuation);
Configuration call(Value v) {
log.info('print(${v.value.runtimeType}: ${v.value})\n');
@@ -820,11 +664,11 @@ class PrintContinuation extends ExpressionContinuation {
}
}
-class PropertyGetContinuation extends ExpressionContinuation {
+class PropertyGetEK extends ExpressionContinuation {
final Name name;
final ExpressionContinuation continuation;
- PropertyGetContinuation(this.name, this.continuation);
+ PropertyGetEK(this.name, this.continuation);
Configuration call(Value receiver) {
// TODO: CPS the invocation of the getter.
@@ -833,27 +677,27 @@ class PropertyGetContinuation extends ExpressionContinuation {
}
}
-class PropertySetContinuation extends ExpressionContinuation {
+class PropertySetEK extends ExpressionContinuation {
final Expression value;
final Name setterName;
final Environment environment;
final ExpressionContinuation continuation;
- PropertySetContinuation(
+ PropertySetEK(
this.value, this.setterName, this.environment, this.continuation);
Configuration call(Value receiver) {
- var cont = new SetterContinuation(receiver, setterName, continuation);
+ var cont = new SetterEK(receiver, setterName, continuation);
return new EvalConfiguration(value, environment, cont);
}
}
-class SetterContinuation extends ExpressionContinuation {
+class SetterEK extends ExpressionContinuation {
final Value receiver;
final Name name;
final ExpressionContinuation continuation;
- SetterContinuation(this.receiver, this.name, this.continuation);
+ SetterEK(this.receiver, this.name, this.continuation);
Configuration call(Value v) {
Setter setter = receiver.class_.lookupSetter(name);
@@ -864,29 +708,29 @@ class SetterContinuation extends ExpressionContinuation {
/// Represents a continuation to be called after the evaluation of an actual
/// argument for function invocation.
-class ExpressionListContinuation extends ExpressionContinuation {
+class ExpressionListEK extends ExpressionContinuation {
final InterpreterExpression currentExpression;
final List<InterpreterExpression> expressions;
final Environment environment;
final ApplicationContinuation applicationContinuation;
- ExpressionListContinuation(this.currentExpression, this.expressions,
- this.environment, this.applicationContinuation);
+ ExpressionListEK(this.currentExpression, this.expressions, this.environment,
+ this.applicationContinuation);
Configuration call(Value v) {
- ValueApplication app = new ValueApplication(
- currentExpression.assignValue(v), applicationContinuation);
+ ValueA app =
+ new ValueA(currentExpression.assignValue(v), applicationContinuation);
return new EvalListConfiguration(expressions, environment, app);
}
}
-class MethodInvocationContinuation extends ExpressionContinuation {
+class MethodInvocationEK extends ExpressionContinuation {
final Arguments arguments;
final Name methodName;
final Environment environment;
final ExpressionContinuation continuation;
- MethodInvocationContinuation(
+ MethodInvocationEK(
this.arguments, this.methodName, this.environment, this.continuation);
Configuration call(Value receiver) {
@@ -894,22 +738,22 @@ class MethodInvocationContinuation extends ExpressionContinuation {
Value returnValue = receiver.invokeMethod(methodName);
return new ValuePassingConfiguration(continuation, returnValue);
}
- var cont = new ArgumentsContinuation(
+ var cont = new ArgumentsEK(
receiver, methodName, arguments, environment, continuation);
return new EvalConfiguration(arguments.positional.first, environment, cont);
}
}
-class ArgumentsContinuation extends ExpressionContinuation {
+class ArgumentsEK extends ExpressionContinuation {
final Value receiver;
final Name methodName;
final Arguments arguments;
final Environment environment;
final ExpressionContinuation continuation;
- ArgumentsContinuation(this.receiver, this.methodName, this.arguments,
- this.environment, this.continuation);
+ ArgumentsEK(this.receiver, this.methodName, this.arguments, this.environment,
+ this.continuation);
Configuration call(Value value) {
// Currently evaluates only one argument, for simple method invocations
@@ -919,12 +763,12 @@ class ArgumentsContinuation extends ExpressionContinuation {
}
}
-class VariableSetContinuation extends ExpressionContinuation {
+class VariableSetEK extends ExpressionContinuation {
final VariableDeclaration variable;
final Environment environment;
final ExpressionContinuation continuation;
- VariableSetContinuation(this.variable, this.environment, this.continuation);
+ VariableSetEK(this.variable, this.environment, this.continuation);
Configuration call(Value value) {
environment.assign(variable, value);
@@ -932,10 +776,10 @@ class VariableSetContinuation extends ExpressionContinuation {
}
}
-class NotContinuation extends ExpressionContinuation {
+class NotEK extends ExpressionContinuation {
final ExpressionContinuation continuation;
- NotContinuation(this.continuation);
+ NotEK(this.continuation);
Configuration call(Value value) {
Value notValue = identical(Value.trueInstance, value)
@@ -945,12 +789,12 @@ class NotContinuation extends ExpressionContinuation {
}
}
-class OrContinuation extends ExpressionContinuation {
+class OrEK extends ExpressionContinuation {
final Expression right;
final Environment environment;
final ExpressionContinuation continuation;
- OrContinuation(this.right, this.environment, this.continuation);
+ OrEK(this.right, this.environment, this.continuation);
Configuration call(Value left) {
return identical(Value.trueInstance, left)
@@ -959,12 +803,12 @@ class OrContinuation extends ExpressionContinuation {
}
}
-class AndContinuation extends ExpressionContinuation {
+class AndEK extends ExpressionContinuation {
final Expression right;
final Environment environment;
final ExpressionContinuation continuation;
- AndContinuation(this.right, this.environment, this.continuation);
+ AndEK(this.right, this.environment, this.continuation);
Configuration call(Value left) {
return identical(Value.falseInstance, left)
@@ -973,14 +817,13 @@ class AndContinuation extends ExpressionContinuation {
}
}
-class ConditionalContinuation extends ExpressionContinuation {
+class ConditionalEK extends ExpressionContinuation {
final Expression then;
final Expression otherwise;
final Environment environment;
final ExpressionContinuation continuation;
- ConditionalContinuation(
- this.then, this.otherwise, this.environment, this.continuation);
+ ConditionalEK(this.then, this.otherwise, this.environment, this.continuation);
Configuration call(Value value) {
return identical(Value.trueInstance, value)
@@ -989,89 +832,73 @@ class ConditionalContinuation extends ExpressionContinuation {
}
}
-class StringConcatenationContinuation extends ApplicationContinuation {
- final ExpressionContinuation continuation;
-
- StringConcatenationContinuation(this.continuation);
-
- Configuration call(List<InterpreterValue> values) {
- StringBuffer result = new StringBuffer();
- for (InterpreterValue v in values.reversed) {
- result.write(v.value.value);
- }
- return new ValuePassingConfiguration(
- continuation, new StringValue(result.toString()));
- }
-}
-
-class LetContinuation extends ExpressionContinuation {
+class LetEK extends ExpressionContinuation {
final VariableDeclaration variable;
final Expression letBody;
final Environment environment;
final ExpressionContinuation continuation;
- LetContinuation(
- this.variable, this.letBody, this.environment, this.continuation);
+ LetEK(this.variable, this.letBody, this.environment, this.continuation);
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 WhileConditionContinuation extends ExpressionContinuation {
- final WhileStatement node;
+class WhileConditionEK extends ExpressionContinuation {
+ final Expression condition;
+ final Statement body;
+ final Environment enclosingEnv;
final State state;
- WhileConditionContinuation(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));
}
}
/// Represents the continuation for the condition expression in [IfStatement].
-class IfConditionContinuation extends ExpressionContinuation {
+class IfConditionEK extends ExpressionContinuation {
final Statement then;
final Statement otherwise;
+ final Environment environment;
final State state;
- IfConditionContinuation(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);
}
}
/// Represents the continuation for the initializer expression in
/// [VariableDeclaration].
-class VariableInitializerContinuation extends ExpressionContinuation {
+class VariableInitializerEK extends ExpressionContinuation {
final VariableDeclaration variable;
final Environment environment;
- final ExecConfiguration nextConfiguration;
+ final StatementContinuation continuation;
- VariableInitializerContinuation(
- 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));
}
}
@@ -1084,108 +911,117 @@ class VariableInitializerContinuation extends ExpressionContinuation {
/// returned and applied
/// - it returns with or without value, TBD
/// - it throws, TBD
-class StatementExecuter extends StatementVisitor1<Configuration, State> {
+class StatementExecuter
+ extends StatementVisitor1<Configuration, ExecConfiguration> {
Evaluator evaluator = new Evaluator();
void trampolinedExecution(Configuration configuration) {
while (configuration != null) {
configuration = configuration.step(this);
}
+ ;
}
- 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 ExpressionStatementContinuation(state.statementConfiguration);
- return new EvalConfiguration(node.expression, state.environment, cont);
+ ExpressionStatement node, ExecConfiguration conf) {
+ var cont = new ExpressionSK(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;
+ return new ForwardConfiguration(
+ conf.state.continuation, conf.environment);
}
- 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 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,
+ new State(conf.state.labels, conf.state.returnContinuation, 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 IfConditionContinuation(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) {
+ var l = new Label(
+ node, conf.environment, conf.state.continuation, conf.state.labels);
+ return new ExecConfiguration(node.body, conf.environment,
+ new State(l, conf.state.returnContinuation, conf.state.continuation));
}
- 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 WhileConditionContinuation(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));
+ return new ExecConfiguration(node.body, conf.environment,
+ new State(conf.state.labels, conf.state.returnContinuation, 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 VariableInitializerContinuation(
- node, state.environment, state.statementConfiguration);
- return new EvalConfiguration(node.initializer, state.environment, cont);
+ var cont = new VariableInitializerEK(
+ 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