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

Side by Side Diff: pkg/kernel/lib/interpreter/interpreter.dart

Issue 2997443002: Add support for function declarations and function expressions (Closed)
Patch Set: Fix env creation in let Created 3 years, 4 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 unified diff | Download patch
« no previous file with comments | « no previous file | pkg/kernel/testcases/interpreter/function_expressions_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 library kernel.interpreter; 4 library kernel.interpreter;
5 5
6 import '../ast.dart'; 6 import '../ast.dart';
7 import '../ast.dart' as ast show Class; 7 import '../ast.dart' as ast show Class;
8 8
9 import '../log.dart'; 9 import '../log.dart';
10 export '../log.dart'; 10 export '../log.dart';
(...skipping 25 matching lines...) Expand all
36 } 36 }
37 } 37 }
38 38
39 class Location { 39 class Location {
40 Value value; 40 Value value;
41 41
42 Location.empty(); 42 Location.empty();
43 Location(this.value); 43 Location(this.value);
44 } 44 }
45 45
46 class EnvironmentLocation {
47 Environment environment;
48
49 EnvironmentLocation.empty();
50 EnvironmentLocation(this.environment);
51 }
52
46 class Binding { 53 class Binding {
47 final VariableDeclaration variable; 54 final VariableDeclaration variable;
48 final Location location; 55 final Location location;
49 56
50 Binding(this.variable, this.location); 57 Binding(this.variable, this.location);
51 } 58 }
52 59
53 class Environment { 60 class Environment {
54 final List<Binding> bindings = <Binding>[]; 61 final List<Binding> bindings = <Binding>[];
55 final Environment parent; 62 final Environment parent;
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 config.continuation, config.environment.thisInstance); 263 config.continuation, config.environment.thisInstance);
257 } 264 }
258 265
259 Configuration visitThrow(Throw node, EvalConfiguration config) { 266 Configuration visitThrow(Throw node, EvalConfiguration config) {
260 var cont = new ThrowEK(config.exceptionComponents); 267 var cont = new ThrowEK(config.exceptionComponents);
261 268
262 return new EvalConfiguration( 269 return new EvalConfiguration(
263 node.expression, config.environment, config.exceptionComponents, cont); 270 node.expression, config.environment, config.exceptionComponents, cont);
264 } 271 }
265 272
273 Configuration visitFunctionExpression(
274 FunctionExpression node, EvalConfiguration config) {
275 var val = new FunctionValue(
276 node.function, new EnvironmentLocation(config.environment));
277 return new ValuePassingConfiguration(config.continuation, val);
278 }
279
266 // Evaluation of BasicLiterals. 280 // Evaluation of BasicLiterals.
267 Configuration visitStringLiteral( 281 Configuration visitStringLiteral(
268 StringLiteral node, EvalConfiguration config) { 282 StringLiteral node, EvalConfiguration config) {
269 return new ValuePassingConfiguration( 283 return new ValuePassingConfiguration(
270 config.continuation, new StringValue(node.value)); 284 config.continuation, new StringValue(node.value));
271 } 285 }
272 286
273 Configuration visitIntLiteral(IntLiteral node, EvalConfiguration config) { 287 Configuration visitIntLiteral(IntLiteral node, EvalConfiguration config) {
274 return new ValuePassingConfiguration( 288 return new ValuePassingConfiguration(
275 config.continuation, new IntValue(node.value)); 289 config.continuation, new IntValue(node.value));
(...skipping 559 matching lines...) Expand 10 before | Expand all | Expand 10 after
835 ? initializer.value 849 ? initializer.value
836 : (initializer as LocalInitializer).variable.initializer; 850 : (initializer as LocalInitializer).variable.initializer;
837 851
838 // We start with index = 0 since we are evaluating the expression for the 852 // We start with index = 0 since we are evaluating the expression for the
839 // first initializer in the initializer list. 853 // first initializer in the initializer list.
840 var cont = new InitializerListEK(constructor, 0, location, environment, 854 var cont = new InitializerListEK(constructor, 0, location, environment,
841 exceptionComponents, continuation); 855 exceptionComponents, continuation);
842 return new EvalConfiguration(expr, environment, exceptionComponents, cont); 856 return new EvalConfiguration(expr, environment, exceptionComponents, cont);
843 } 857 }
844 } 858 }
859
860 class FunctionValueA extends ApplicationContinuation {
861 final FunctionValue receiver;
862 final ExceptionComponents exceptionComponents;
863 final ExpressionContinuation returnContinuation;
864
865 FunctionValueA(
866 this.receiver, this.exceptionComponents, this.returnContinuation);
867
868 Configuration call(List<InterpreterValue> vs) {
869 Environment env = ApplicationContinuation.createEnvironment(
870 receiver.function, vs, receiver.location.environment);
871 var scont = new ExitSK(returnContinuation, Value.nullInstance);
872 var state = new State(null, exceptionComponents, returnContinuation, scont);
873 return new ExecConfiguration(receiver.function.body, env, state);
874 }
875 }
876
845 // ------------------------------------------------------------------------ 877 // ------------------------------------------------------------------------
846 // Expression Continuations 878 // Expression Continuations
847 // ------------------------------------------------------------------------ 879 // ------------------------------------------------------------------------
848 880
849 /// Represents an expression continuation. 881 /// Represents an expression continuation.
850 /// 882 ///
851 /// There are various kinds of [ExpressionContinuation]s and their names are 883 /// There are various kinds of [ExpressionContinuation]s and their names are
852 /// suffixed with "EK". 884 /// suffixed with "EK".
853 abstract class ExpressionContinuation extends Continuation { 885 abstract class ExpressionContinuation extends Continuation {
854 Configuration call(Value v); 886 Configuration call(Value v);
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
945 final Arguments arguments; 977 final Arguments arguments;
946 final Name methodName; 978 final Name methodName;
947 final Environment environment; 979 final Environment environment;
948 final ExceptionComponents exceptionComponents; 980 final ExceptionComponents exceptionComponents;
949 final ExpressionContinuation continuation; 981 final ExpressionContinuation continuation;
950 982
951 MethodInvocationEK(this.arguments, this.methodName, this.environment, 983 MethodInvocationEK(this.arguments, this.methodName, this.environment,
952 this.exceptionComponents, this.continuation); 984 this.exceptionComponents, this.continuation);
953 985
954 Configuration call(Value receiver) { 986 Configuration call(Value receiver) {
987 if (receiver is FunctionValue) {
988 // TODO(zhivkag): use method lookup instead.
989 assert(methodName.toString() == 'call');
990 var args = _getArgumentExpressions(arguments, receiver.function);
991 var acont =
992 new FunctionValueA(receiver, exceptionComponents, continuation);
993 return new EvalListConfiguration(
994 args, environment, exceptionComponents, acont);
995 }
996
955 if (arguments.positional.isEmpty) { 997 if (arguments.positional.isEmpty) {
956 Value returnValue = receiver.invokeMethod(methodName); 998 Value returnValue = receiver.invokeMethod(methodName);
957 return new ValuePassingConfiguration(continuation, returnValue); 999 return new ValuePassingConfiguration(continuation, returnValue);
958 } 1000 }
959 var cont = new ArgumentsEK( 1001 var cont = new ArgumentsEK(
960 receiver, methodName, arguments, environment, continuation); 1002 receiver, methodName, arguments, environment, continuation);
961 1003
962 return new EvalConfiguration( 1004 return new EvalConfiguration(
963 arguments.positional.first, environment, exceptionComponents, cont); 1005 arguments.positional.first, environment, exceptionComponents, cont);
964 } 1006 }
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1065 final VariableDeclaration variable; 1107 final VariableDeclaration variable;
1066 final Expression letBody; 1108 final Expression letBody;
1067 final Environment environment; 1109 final Environment environment;
1068 final ExceptionComponents exceptionComponents; 1110 final ExceptionComponents exceptionComponents;
1069 final ExpressionContinuation continuation; 1111 final ExpressionContinuation continuation;
1070 1112
1071 LetEK(this.variable, this.letBody, this.environment, this.exceptionComponents, 1113 LetEK(this.variable, this.letBody, this.environment, this.exceptionComponents,
1072 this.continuation); 1114 this.continuation);
1073 1115
1074 Configuration call(Value value) { 1116 Configuration call(Value value) {
1075 var letEnv = new Environment(environment); 1117 var letEnv = environment.extend(variable, value);
1076 letEnv.extend(variable, value);
1077 return new EvalConfiguration( 1118 return new EvalConfiguration(
1078 letBody, letEnv, exceptionComponents, continuation); 1119 letBody, letEnv, exceptionComponents, continuation);
1079 } 1120 }
1080 } 1121 }
1081 1122
1082 /// Represents the continuation for the condition expression in [WhileStatement] . 1123 /// Represents the continuation for the condition expression in [WhileStatement] .
1083 class WhileConditionEK extends ExpressionContinuation { 1124 class WhileConditionEK extends ExpressionContinuation {
1084 final Expression condition; 1125 final Expression condition;
1085 final Statement body; 1126 final Statement body;
1086 final Environment enclosingEnv; 1127 final Environment enclosingEnv;
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after
1539 VariableDeclaration node, ExecConfiguration conf) { 1580 VariableDeclaration node, ExecConfiguration conf) {
1540 if (node.initializer != null) { 1581 if (node.initializer != null) {
1541 var cont = new VariableInitializerEK( 1582 var cont = new VariableInitializerEK(
1542 node, conf.environment, conf.state.continuation); 1583 node, conf.environment, conf.state.continuation);
1543 return new EvalConfiguration(node.initializer, conf.environment, 1584 return new EvalConfiguration(node.initializer, conf.environment,
1544 conf.state.exceptionComponents, cont); 1585 conf.state.exceptionComponents, cont);
1545 } 1586 }
1546 return new ForwardConfiguration(conf.state.continuation, 1587 return new ForwardConfiguration(conf.state.continuation,
1547 conf.environment.extend(node, Value.nullInstance)); 1588 conf.environment.extend(node, Value.nullInstance));
1548 } 1589 }
1590
1591 Configuration visitFunctionDeclaration(
1592 FunctionDeclaration node, ExecConfiguration conf) {
1593 var fun = new FunctionValue(node.function, new EnvironmentLocation.empty());
1594 var newEnv = conf.environment.extend(node.variable, fun);
1595 fun.location.environment = newEnv;
1596 return new ForwardConfiguration(conf.state.continuation, newEnv);
1597 }
1549 } 1598 }
1550 1599
1551 // ------------------------------------------------------------------------ 1600 // ------------------------------------------------------------------------
1552 // VALUES 1601 // VALUES
1553 // ------------------------------------------------------------------------ 1602 // ------------------------------------------------------------------------
1554 1603
1555 typedef Value Getter(Value receiver); 1604 typedef Value Getter(Value receiver);
1556 typedef void Setter(Value receiver, Value value); 1605 typedef void Setter(Value receiver, Value value);
1557 1606
1558 class Class { 1607 class Class {
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
1674 Object get value => this; 1723 Object get value => this;
1675 1724
1676 ObjectValue(this.class_) : fields = new List<Location>(class_.instanceSize) { 1725 ObjectValue(this.class_) : fields = new List<Location>(class_.instanceSize) {
1677 for (int i = 0; i < fields.length; i++) { 1726 for (int i = 0; i < fields.length; i++) {
1678 // Create fresh locations for each field. 1727 // Create fresh locations for each field.
1679 fields[i] = new Location.empty(); 1728 fields[i] = new Location.empty();
1680 } 1729 }
1681 } 1730 }
1682 } 1731 }
1683 1732
1733 class FunctionValue extends Value {
1734 Class get class_ => throw 'Class for FunctionValue is not defined';
1735 List<Location> get fields => throw 'FunctionValue has no fields.';
1736
1737 FunctionValue get value => this;
1738
1739 final FunctionNode function;
1740 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
1741
1742 FunctionValue(this.function, this.location);
1743 }
1744
1684 abstract class LiteralValue extends Value { 1745 abstract class LiteralValue extends Value {
1685 Class get class_ => 1746 Class get class_ =>
1686 notImplemented(m: "Loading class for literal is not implemented."); 1747 notImplemented(m: "Loading class for literal is not implemented.");
1687 List<Location> get fields => 1748 List<Location> get fields =>
1688 notImplemented(m: "Literal value does not have fields"); 1749 notImplemented(m: "Literal value does not have fields");
1689 1750
1690 const LiteralValue(); 1751 const LiteralValue();
1691 } 1752 }
1692 1753
1693 class StringValue extends LiteralValue { 1754 class StringValue extends LiteralValue {
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
1840 /// Initializes all non initialized fields from the provided class to 1901 /// Initializes all non initialized fields from the provided class to
1841 /// `Value.nullInstance` in the provided value. 1902 /// `Value.nullInstance` in the provided value.
1842 void _initializeNullFields(Class class_, Value value) { 1903 void _initializeNullFields(Class class_, Value value) {
1843 int startIndex = class_.superclass?.instanceSize ?? 0; 1904 int startIndex = class_.superclass?.instanceSize ?? 0;
1844 for (int i = startIndex; i < class_.instanceSize; i++) { 1905 for (int i = startIndex; i < class_.instanceSize; i++) {
1845 if (value.fields[i].value == null) { 1906 if (value.fields[i].value == null) {
1846 value.fields[i].value = Value.nullInstance; 1907 value.fields[i].value = Value.nullInstance;
1847 } 1908 }
1848 } 1909 }
1849 } 1910 }
OLDNEW
« no previous file with comments | « no previous file | pkg/kernel/testcases/interpreter/function_expressions_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698