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)); |
} |
} |