OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |