| Index: pkg/kernel/lib/interpreter/interpreter.dart
|
| diff --git a/pkg/kernel/lib/interpreter/interpreter.dart b/pkg/kernel/lib/interpreter/interpreter.dart
|
| index 2c03f2512c2bf68f0684509e931872d7175d606d..65e6c52c781649f630b79a74677b165bbaf00661 100644
|
| --- a/pkg/kernel/lib/interpreter/interpreter.dart
|
| +++ b/pkg/kernel/lib/interpreter/interpreter.dart
|
| @@ -263,6 +263,12 @@ class Evaluator extends ExpressionVisitor1<Configuration, EvalConfiguration> {
|
| node.expression, config.environment, config.exceptionComponents, cont);
|
| }
|
|
|
| + Configuration visitFunctionExpression(
|
| + FunctionExpression node, EvalConfiguration config) {
|
| + var val = new FunctionValue(node.function, config.environment);
|
| + return new ValuePassingConfiguration(config.continuation, val);
|
| + }
|
| +
|
| // Evaluation of BasicLiterals.
|
| Configuration visitStringLiteral(
|
| StringLiteral node, EvalConfiguration config) {
|
| @@ -892,6 +898,24 @@ class InstanceFieldsA extends ApplicationContinuation {
|
| return new EvalConfiguration(expr, environment, exceptionComponents, cont);
|
| }
|
| }
|
| +
|
| +class FunctionValueA extends ApplicationContinuation {
|
| + final FunctionValue receiver;
|
| + final ExceptionComponents exceptionComponents;
|
| + final ExpressionContinuation returnContinuation;
|
| +
|
| + FunctionValueA(
|
| + this.receiver, this.exceptionComponents, this.returnContinuation);
|
| +
|
| + Configuration call(List<InterpreterValue> vs) {
|
| + Environment env = ApplicationContinuation.createEnvironment(
|
| + receiver.function, vs, receiver.environment);
|
| + var scont = new ExitSK(returnContinuation, Value.nullInstance);
|
| + var state = new State(null, exceptionComponents, returnContinuation, scont);
|
| + return new ExecConfiguration(receiver.function.body, env, state);
|
| + }
|
| +}
|
| +
|
| // ------------------------------------------------------------------------
|
| // Expression Continuations
|
| // ------------------------------------------------------------------------
|
| @@ -1002,6 +1026,16 @@ class MethodInvocationEK extends ExpressionContinuation {
|
| this.exceptionComponents, this.continuation);
|
|
|
| Configuration call(Value receiver) {
|
| + if (receiver is FunctionValue) {
|
| + // TODO(zhivkag): use method lookup instead.
|
| + assert(methodName.toString() == 'call');
|
| + var args = _getArgumentExpressions(arguments, receiver.function);
|
| + var acont =
|
| + new FunctionValueA(receiver, exceptionComponents, continuation);
|
| + return new EvalListConfiguration(
|
| + args, environment, exceptionComponents, acont);
|
| + }
|
| +
|
| if (arguments.positional.isEmpty) {
|
| Value returnValue = receiver.invokeMethod(methodName);
|
| return new ValuePassingConfiguration(continuation, returnValue);
|
| @@ -1122,8 +1156,7 @@ class LetEK extends ExpressionContinuation {
|
| this.continuation);
|
|
|
| Configuration call(Value value) {
|
| - var letEnv = new Environment(environment);
|
| - letEnv.extend(variable, value);
|
| + var letEnv = environment.extend(variable, value);
|
| return new EvalConfiguration(
|
| letBody, letEnv, exceptionComponents, continuation);
|
| }
|
| @@ -1599,6 +1632,14 @@ class StatementExecuter
|
| return new ForwardConfiguration(conf.state.continuation,
|
| conf.environment.extend(node, Value.nullInstance));
|
| }
|
| +
|
| + Configuration visitFunctionDeclaration(
|
| + FunctionDeclaration node, ExecConfiguration conf) {
|
| + var newEnv = conf.environment.extend(node.variable, Value.nullInstance);
|
| + var fun = new FunctionValue(node.function, newEnv);
|
| + newEnv.assign(node.variable, fun);
|
| + return new ForwardConfiguration(conf.state.continuation, newEnv);
|
| + }
|
| }
|
|
|
| // ------------------------------------------------------------------------
|
| @@ -1734,6 +1775,18 @@ class ObjectValue extends Value {
|
| }
|
| }
|
|
|
| +class FunctionValue extends Value {
|
| + Class get class_ => throw 'Class for FunctionValue is not defined';
|
| + List<Location> get fields => throw 'FunctionValue has no fields.';
|
| +
|
| + FunctionValue get value => this;
|
| +
|
| + final FunctionNode function;
|
| + final Environment environment;
|
| +
|
| + FunctionValue(this.function, this.environment);
|
| +}
|
| +
|
| abstract class LiteralValue extends Value {
|
| Class get class_ =>
|
| notImplemented(m: "Loading class for literal is not implemented.");
|
|
|