Chromium Code Reviews| Index: pkg/kernel/lib/interpreter/interpreter.dart |
| diff --git a/pkg/kernel/lib/interpreter/interpreter.dart b/pkg/kernel/lib/interpreter/interpreter.dart |
| index 6d88dd25abc92be2a0b161ffcc51b96aa29f8bf9..4426df27b9732172f44dddbd6a3d8685a517238e 100644 |
| --- a/pkg/kernel/lib/interpreter/interpreter.dart |
| +++ b/pkg/kernel/lib/interpreter/interpreter.dart |
| @@ -43,6 +43,13 @@ class Location { |
| Location(this.value); |
| } |
| +class EnvironmentLocation { |
| + Environment environment; |
| + |
| + EnvironmentLocation.empty(); |
| + EnvironmentLocation(this.environment); |
| +} |
| + |
| class Binding { |
| final VariableDeclaration variable; |
| final Location location; |
| @@ -263,6 +270,13 @@ 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, new EnvironmentLocation(config.environment)); |
| + return new ValuePassingConfiguration(config.continuation, val); |
| + } |
| + |
| // Evaluation of BasicLiterals. |
| Configuration visitStringLiteral( |
| StringLiteral node, EvalConfiguration config) { |
| @@ -842,6 +856,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.location.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 |
| // ------------------------------------------------------------------------ |
| @@ -952,6 +984,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); |
| @@ -1072,8 +1114,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); |
| } |
| @@ -1546,6 +1587,14 @@ class StatementExecuter |
| return new ForwardConfiguration(conf.state.continuation, |
| conf.environment.extend(node, Value.nullInstance)); |
| } |
| + |
| + Configuration visitFunctionDeclaration( |
| + FunctionDeclaration node, ExecConfiguration conf) { |
| + var fun = new FunctionValue(node.function, new EnvironmentLocation.empty()); |
| + var newEnv = conf.environment.extend(node.variable, fun); |
| + fun.location.environment = newEnv; |
| + return new ForwardConfiguration(conf.state.continuation, newEnv); |
| + } |
| } |
| // ------------------------------------------------------------------------ |
| @@ -1681,6 +1730,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 EnvironmentLocation location; |
|
Dmitry Stefantsov
2017/08/16 07:57:54
Why do we need an [EnvironmentLocation] here? As
zhivkag
2017/08/16 08:16:29
The specification is updated w.r.t. the discussion
Dmitry Stefantsov
2017/08/16 08:32:33
Yes, I remember the discussion. However, I may ha
zhivkag
2017/08/16 09:33:13
Thanks for the suggestion, I like this approach be
|
| + |
| + FunctionValue(this.function, this.location); |
| +} |
| + |
| abstract class LiteralValue extends Value { |
| Class get class_ => |
| notImplemented(m: "Loading class for literal is not implemented."); |