| 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'; |
| 11 | 11 |
| 12 class NotImplemented { | 12 class NotImplemented { |
| 13 String message; | 13 String message; |
| 14 | 14 |
| 15 NotImplemented(this.message); | 15 NotImplemented(this.message); |
| 16 | 16 |
| 17 String toString() => message; | 17 String toString() => message; |
| 18 } | 18 } |
| 19 | 19 |
| 20 class Interpreter { | 20 class Interpreter { |
| 21 Program program; | 21 Program program; |
| 22 StatementExecuter visitor = new StatementExecuter(); | 22 StatementExecuter visitor = new StatementExecuter(); |
| 23 | 23 |
| 24 // The execution of the program starts with empty main environment. |
| 25 static MainEnvironment mainEnvironment = |
| 26 new MainEnvironment(<Member, Location>{}); |
| 27 |
| 24 Interpreter(this.program); | 28 Interpreter(this.program); |
| 25 | 29 |
| 26 void run() { | 30 void run() { |
| 27 assert(program.libraries.isEmpty); | 31 assert(program.libraries.isEmpty); |
| 28 Procedure mainMethod = program.mainMethod; | 32 Procedure mainMethod = program.mainMethod; |
| 29 | 33 |
| 30 if (mainMethod == null) return; | 34 if (mainMethod == null) return; |
| 31 | 35 |
| 32 Statement statementBlock = mainMethod.function.body; | 36 Statement statementBlock = mainMethod.function.body; |
| 33 ExecConfiguration configuration = new ExecConfiguration( | 37 ExecConfiguration configuration = new ExecConfiguration( |
| 34 statementBlock, new Environment.empty(), new State.initial()); | 38 statementBlock, new Environment.empty(), new State.initial()); |
| 35 visitor.trampolinedExecution(configuration); | 39 visitor.trampolinedExecution(configuration); |
| 36 } | 40 } |
| 37 } | 41 } |
| 38 | 42 |
| 39 class Location { | 43 class Location { |
| 40 Value value; | 44 Value value; |
| 41 | 45 |
| 42 Location.empty(); | 46 Location.empty(); |
| 43 Location(this.value); | 47 Location(this.value); |
| 44 } | 48 } |
| 45 | 49 |
| 46 class Binding { | 50 class Binding { |
| 47 final VariableDeclaration variable; | 51 final VariableDeclaration variable; |
| 48 final Location location; | 52 final Location location; |
| 49 | 53 |
| 50 Binding(this.variable, this.location); | 54 Binding(this.variable, this.location); |
| 51 } | 55 } |
| 52 | 56 |
| 57 /// Represents the top level environment that binds previously accessed or set |
| 58 /// static fields to the location that stores their value. |
| 59 class MainEnvironment { |
| 60 final Map<Member, Location> _staticFields; |
| 61 |
| 62 MainEnvironment(this._staticFields); |
| 63 |
| 64 bool contains(Member member) => _staticFields[member] != null; |
| 65 |
| 66 Value lookup(Member member) { |
| 67 assert(contains(member)); |
| 68 return _staticFields[member].value; |
| 69 } |
| 70 |
| 71 void updateStore(Member member, Value value) { |
| 72 assert(contains(member)); |
| 73 _staticFields[member].value = value; |
| 74 } |
| 75 |
| 76 MainEnvironment extend(Member member, Value value) { |
| 77 var newMap = new Map<Member, Location>.from(_staticFields); |
| 78 newMap[member] = new Location(value); |
| 79 return new MainEnvironment(newMap); |
| 80 } |
| 81 } |
| 82 |
| 53 class Environment { | 83 class Environment { |
| 54 final List<Binding> bindings = <Binding>[]; | 84 final List<Binding> bindings = <Binding>[]; |
| 55 final Environment parent; | 85 final Environment parent; |
| 56 | 86 |
| 57 Value get thisInstance { | 87 Value get thisInstance { |
| 58 return containsThis() | 88 return containsThis() |
| 59 ? lookupThis().value | 89 ? lookupThis().value |
| 60 : throw "Invalid reference to 'this' expression"; | 90 : throw "Invalid reference to 'this' expression"; |
| 61 } | 91 } |
| 62 | 92 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 90 for (Binding b in bindings) { | 120 for (Binding b in bindings) { |
| 91 if (identical(b.variable.name, 'this')) return b.location; | 121 if (identical(b.variable.name, 'this')) return b.location; |
| 92 } | 122 } |
| 93 return parent.lookupThis(); | 123 return parent.lookupThis(); |
| 94 } | 124 } |
| 95 | 125 |
| 96 Value lookup(VariableDeclaration variable) { | 126 Value lookup(VariableDeclaration variable) { |
| 97 return lookupBinding(variable).location.value; | 127 return lookupBinding(variable).location.value; |
| 98 } | 128 } |
| 99 | 129 |
| 100 void assign(VariableDeclaration variable, Value value) { | 130 void updateStore(VariableDeclaration variable, Value value) { |
| 101 assert(contains(variable)); | 131 assert(contains(variable)); |
| 102 lookupBinding(variable).location.value = value; | 132 lookupBinding(variable).location.value = value; |
| 103 } | 133 } |
| 104 | 134 |
| 105 Environment extend(VariableDeclaration variable, Value value) { | 135 Environment extend(VariableDeclaration variable, Value value) { |
| 106 assert(!contains(variable)); | 136 assert(!contains(variable)); |
| 107 return new Environment(this) | 137 return new Environment(this) |
| 108 ..bindings.add(new Binding(variable, new Location(value))); | 138 ..bindings.add(new Binding(variable, new Location(value))); |
| 109 } | 139 } |
| 110 | 140 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 160 node.receiver, config.environment, config.exceptionComponents, cont); | 190 node.receiver, config.environment, config.exceptionComponents, cont); |
| 161 } | 191 } |
| 162 | 192 |
| 163 Configuration visitPropertySet(PropertySet node, EvalConfiguration config) { | 193 Configuration visitPropertySet(PropertySet node, EvalConfiguration config) { |
| 164 var cont = new PropertySetEK(node.value, node.name, config.environment, | 194 var cont = new PropertySetEK(node.value, node.name, config.environment, |
| 165 config.exceptionComponents, config.continuation); | 195 config.exceptionComponents, config.continuation); |
| 166 return new EvalConfiguration( | 196 return new EvalConfiguration( |
| 167 node.receiver, config.environment, config.exceptionComponents, cont); | 197 node.receiver, config.environment, config.exceptionComponents, cont); |
| 168 } | 198 } |
| 169 | 199 |
| 170 Configuration visitStaticGet(StaticGet node, EvalConfiguration config) => | 200 Configuration visitStaticGet(StaticGet node, EvalConfiguration config) { |
| 171 defaultExpression(node, config); | 201 Member member = node.target; |
| 172 Configuration visitStaticSet(StaticSet node, EvalConfiguration config) => | 202 |
| 173 defaultExpression(node, config); | 203 if (member is Procedure && !member.isAccessor) { |
| 204 // Create a closure for the method tear off. |
| 205 var v = new FunctionValue(member.function, new Environment.empty()); |
| 206 return new ValuePassingConfiguration(config.continuation, v); |
| 207 } |
| 208 |
| 209 if (member is Procedure && member.isGetter) { |
| 210 // Execute the body of the getter. |
| 211 var state = new State.initial() |
| 212 .withReturnContinuation(config.continuation) |
| 213 .withContinuation(new ExitSK(config.continuation, Value.nullInstance)) |
| 214 .withException(config.exceptionComponents); |
| 215 return new ExecConfiguration( |
| 216 member.function.body, new Environment.empty(), state); |
| 217 } |
| 218 |
| 219 assert(member is Field); |
| 220 if (Interpreter.mainEnvironment.contains(member)) { |
| 221 // Read the value for the member in the main environment. |
| 222 return new ValuePassingConfiguration( |
| 223 config.continuation, Interpreter.mainEnvironment.lookup(member)); |
| 224 } |
| 225 |
| 226 // Otherwise, the static field is accessed for the first time. |
| 227 // We extend the main environment with a new binding. |
| 228 Interpreter.mainEnvironment = |
| 229 Interpreter.mainEnvironment.extend(member, Value.nullInstance); |
| 230 |
| 231 if ((member as Field).initializer == null) { |
| 232 return new ValuePassingConfiguration( |
| 233 config.continuation, Value.nullInstance); |
| 234 } |
| 235 |
| 236 // The initializer expression is evaluated otherwise. |
| 237 var cont = new StaticSetEK(member, config.continuation); |
| 238 return new EvalConfiguration((member as Field).initializer, |
| 239 new Environment.empty(), config.exceptionComponents, cont); |
| 240 } |
| 241 |
| 242 Configuration visitStaticSet(StaticSet node, EvalConfiguration config) { |
| 243 Member member = node.target; |
| 244 ExpressionContinuation cont; |
| 245 |
| 246 if (member is Procedure) { |
| 247 assert(member.isSetter); |
| 248 cont = new StaticSetterEK( |
| 249 member.function, config.exceptionComponents, config.continuation); |
| 250 } else { |
| 251 assert(member is Field); |
| 252 cont = new StaticSetEK(member, config.continuation); |
| 253 } |
| 254 |
| 255 return new EvalConfiguration( |
| 256 node.value, config.environment, config.exceptionComponents, cont); |
| 257 } |
| 174 | 258 |
| 175 Configuration visitStaticInvocation( | 259 Configuration visitStaticInvocation( |
| 176 StaticInvocation node, EvalConfiguration config) { | 260 StaticInvocation node, EvalConfiguration config) { |
| 177 if ('print' == node.name.toString()) { | 261 if ('print' == node.name.toString()) { |
| 178 var cont = new PrintEK(config.continuation); | 262 var cont = new PrintEK(config.continuation); |
| 179 return new EvalConfiguration(node.arguments.positional.first, | 263 return new EvalConfiguration(node.arguments.positional.first, |
| 180 config.environment, config.exceptionComponents, cont); | 264 config.environment, config.exceptionComponents, cont); |
| 181 } else { | 265 } else { |
| 182 log.info('static-invocation-${node.target.name.toString()}\n'); | 266 log.info('static-invocation-${node.target.name.toString()}\n'); |
| 183 | 267 |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 256 config.continuation, config.environment.thisInstance); | 340 config.continuation, config.environment.thisInstance); |
| 257 } | 341 } |
| 258 | 342 |
| 259 Configuration visitThrow(Throw node, EvalConfiguration config) { | 343 Configuration visitThrow(Throw node, EvalConfiguration config) { |
| 260 var cont = new ThrowEK(config.exceptionComponents); | 344 var cont = new ThrowEK(config.exceptionComponents); |
| 261 | 345 |
| 262 return new EvalConfiguration( | 346 return new EvalConfiguration( |
| 263 node.expression, config.environment, config.exceptionComponents, cont); | 347 node.expression, config.environment, config.exceptionComponents, cont); |
| 264 } | 348 } |
| 265 | 349 |
| 350 Configuration visitFunctionExpression( |
| 351 FunctionExpression node, EvalConfiguration config) { |
| 352 var val = new FunctionValue(node.function, config.environment); |
| 353 return new ValuePassingConfiguration(config.continuation, val); |
| 354 } |
| 355 |
| 266 // Evaluation of BasicLiterals. | 356 // Evaluation of BasicLiterals. |
| 267 Configuration visitStringLiteral( | 357 Configuration visitStringLiteral( |
| 268 StringLiteral node, EvalConfiguration config) { | 358 StringLiteral node, EvalConfiguration config) { |
| 269 return new ValuePassingConfiguration( | 359 return new ValuePassingConfiguration( |
| 270 config.continuation, new StringValue(node.value)); | 360 config.continuation, new StringValue(node.value)); |
| 271 } | 361 } |
| 272 | 362 |
| 273 Configuration visitIntLiteral(IntLiteral node, EvalConfiguration config) { | 363 Configuration visitIntLiteral(IntLiteral node, EvalConfiguration config) { |
| 274 return new ValuePassingConfiguration( | 364 return new ValuePassingConfiguration( |
| 275 config.continuation, new IntValue(node.value)); | 365 config.continuation, new IntValue(node.value)); |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 408 } | 498 } |
| 409 | 499 |
| 410 /// Configuration for execution of a [Statement]. | 500 /// Configuration for execution of a [Statement]. |
| 411 class ExecConfiguration extends Configuration { | 501 class ExecConfiguration extends Configuration { |
| 412 final Statement currentStatement; | 502 final Statement currentStatement; |
| 413 final Environment environment; | 503 final Environment environment; |
| 414 final State state; | 504 final State state; |
| 415 | 505 |
| 416 ExecConfiguration(this.currentStatement, this.environment, this.state); | 506 ExecConfiguration(this.currentStatement, this.environment, this.state); |
| 417 | 507 |
| 418 Configuration step(StatementExecuter executer) => | 508 Configuration step(StatementExecuter executer) { |
| 419 executer.exec(currentStatement, this); | 509 return executer.exec(currentStatement, this); |
| 510 } |
| 420 } | 511 } |
| 421 | 512 |
| 422 /// Configuration for applying a [StatementContinuation] to an [Environment]. | 513 /// Configuration for applying a [StatementContinuation] to an [Environment]. |
| 423 class ForwardConfiguration extends Configuration { | 514 class ForwardConfiguration extends Configuration { |
| 424 final StatementContinuation continuation; | 515 final StatementContinuation continuation; |
| 425 final Environment environment; | 516 final Environment environment; |
| 426 | 517 |
| 427 ForwardConfiguration(this.continuation, this.environment); | 518 ForwardConfiguration(this.continuation, this.environment); |
| 428 | 519 |
| 429 Configuration step(StatementExecuter _) => continuation?.call(environment); | 520 Configuration step(StatementExecuter _) => continuation?.call(environment); |
| (...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 885 ? initializer.value | 976 ? initializer.value |
| 886 : (initializer as LocalInitializer).variable.initializer; | 977 : (initializer as LocalInitializer).variable.initializer; |
| 887 | 978 |
| 888 // We start with index = 0 since we are evaluating the expression for the | 979 // We start with index = 0 since we are evaluating the expression for the |
| 889 // first initializer in the initializer list. | 980 // first initializer in the initializer list. |
| 890 var cont = new InitializerListEK(constructor, 0, location, environment, | 981 var cont = new InitializerListEK(constructor, 0, location, environment, |
| 891 exceptionComponents, continuation); | 982 exceptionComponents, continuation); |
| 892 return new EvalConfiguration(expr, environment, exceptionComponents, cont); | 983 return new EvalConfiguration(expr, environment, exceptionComponents, cont); |
| 893 } | 984 } |
| 894 } | 985 } |
| 986 |
| 987 class FunctionValueA extends ApplicationContinuation { |
| 988 final FunctionValue receiver; |
| 989 final ExceptionComponents exceptionComponents; |
| 990 final ExpressionContinuation returnContinuation; |
| 991 |
| 992 FunctionValueA( |
| 993 this.receiver, this.exceptionComponents, this.returnContinuation); |
| 994 |
| 995 Configuration call(List<InterpreterValue> vs) { |
| 996 Environment env = ApplicationContinuation.createEnvironment( |
| 997 receiver.function, vs, receiver.environment); |
| 998 var scont = new ExitSK(returnContinuation, Value.nullInstance); |
| 999 var state = new State(null, exceptionComponents, returnContinuation, scont); |
| 1000 return new ExecConfiguration(receiver.function.body, env, state); |
| 1001 } |
| 1002 } |
| 1003 |
| 895 // ------------------------------------------------------------------------ | 1004 // ------------------------------------------------------------------------ |
| 896 // Expression Continuations | 1005 // Expression Continuations |
| 897 // ------------------------------------------------------------------------ | 1006 // ------------------------------------------------------------------------ |
| 898 | 1007 |
| 899 /// Represents an expression continuation. | 1008 /// Represents an expression continuation. |
| 900 /// | 1009 /// |
| 901 /// There are various kinds of [ExpressionContinuation]s and their names are | 1010 /// There are various kinds of [ExpressionContinuation]s and their names are |
| 902 /// suffixed with "EK". | 1011 /// suffixed with "EK". |
| 903 abstract class ExpressionContinuation extends Continuation { | 1012 abstract class ExpressionContinuation extends Continuation { |
| 904 Configuration call(Value v); | 1013 Configuration call(Value v); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 964 | 1073 |
| 965 SetterEK(this.receiver, this.name, this.continuation); | 1074 SetterEK(this.receiver, this.name, this.continuation); |
| 966 | 1075 |
| 967 Configuration call(Value v) { | 1076 Configuration call(Value v) { |
| 968 Setter setter = receiver.class_.lookupImplicitSetter(name); | 1077 Setter setter = receiver.class_.lookupImplicitSetter(name); |
| 969 setter(receiver, v); | 1078 setter(receiver, v); |
| 970 return new ValuePassingConfiguration(continuation, v); | 1079 return new ValuePassingConfiguration(continuation, v); |
| 971 } | 1080 } |
| 972 } | 1081 } |
| 973 | 1082 |
| 1083 class StaticSetEK extends ExpressionContinuation { |
| 1084 final Member member; |
| 1085 final ExpressionContinuation continuation; |
| 1086 |
| 1087 StaticSetEK(this.member, this.continuation); |
| 1088 |
| 1089 Configuration call(Value v) { |
| 1090 if (Interpreter.mainEnvironment.contains(member)) { |
| 1091 Interpreter.mainEnvironment.updateStore(member, v); |
| 1092 } else { |
| 1093 Interpreter.mainEnvironment = |
| 1094 Interpreter.mainEnvironment.extend(member, v); |
| 1095 } |
| 1096 return new ValuePassingConfiguration(continuation, v); |
| 1097 } |
| 1098 } |
| 1099 |
| 1100 class StaticSetterEK extends ExpressionContinuation { |
| 1101 final FunctionNode setter; |
| 1102 final ExceptionComponents exceptionComponents; |
| 1103 final ExpressionContinuation expressionContinuation; |
| 1104 |
| 1105 StaticSetterEK( |
| 1106 this.setter, this.exceptionComponents, this.expressionContinuation); |
| 1107 |
| 1108 Configuration call(Value v) { |
| 1109 VariableDeclaration arg = setter.positionalParameters.first; |
| 1110 var env = new Environment.empty().extend(arg, v); |
| 1111 var state = new State.initial() |
| 1112 .withException(exceptionComponents) |
| 1113 .withReturnContinuation(expressionContinuation) |
| 1114 .withContinuation( |
| 1115 new ExitSK(expressionContinuation, Value.nullInstance)); |
| 1116 |
| 1117 return new ExecConfiguration(setter.body, env, state); |
| 1118 } |
| 1119 } |
| 1120 |
| 974 /// Represents a continuation to be called after the evaluation of an actual | 1121 /// Represents a continuation to be called after the evaluation of an actual |
| 975 /// argument for function invocation. | 1122 /// argument for function invocation. |
| 976 class ExpressionListEK extends ExpressionContinuation { | 1123 class ExpressionListEK extends ExpressionContinuation { |
| 977 final InterpreterExpression currentExpression; | 1124 final InterpreterExpression currentExpression; |
| 978 final List<InterpreterExpression> expressions; | 1125 final List<InterpreterExpression> expressions; |
| 979 final Environment environment; | 1126 final Environment environment; |
| 980 final ExceptionComponents exceptionComponents; | 1127 final ExceptionComponents exceptionComponents; |
| 981 final ApplicationContinuation applicationContinuation; | 1128 final ApplicationContinuation applicationContinuation; |
| 982 | 1129 |
| 983 ExpressionListEK(this.currentExpression, this.expressions, this.environment, | 1130 ExpressionListEK(this.currentExpression, this.expressions, this.environment, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 995 final Arguments arguments; | 1142 final Arguments arguments; |
| 996 final Name methodName; | 1143 final Name methodName; |
| 997 final Environment environment; | 1144 final Environment environment; |
| 998 final ExceptionComponents exceptionComponents; | 1145 final ExceptionComponents exceptionComponents; |
| 999 final ExpressionContinuation continuation; | 1146 final ExpressionContinuation continuation; |
| 1000 | 1147 |
| 1001 MethodInvocationEK(this.arguments, this.methodName, this.environment, | 1148 MethodInvocationEK(this.arguments, this.methodName, this.environment, |
| 1002 this.exceptionComponents, this.continuation); | 1149 this.exceptionComponents, this.continuation); |
| 1003 | 1150 |
| 1004 Configuration call(Value receiver) { | 1151 Configuration call(Value receiver) { |
| 1152 if (receiver is FunctionValue) { |
| 1153 // TODO(zhivkag): use method lookup instead. |
| 1154 assert(methodName.toString() == 'call'); |
| 1155 var args = _getArgumentExpressions(arguments, receiver.function); |
| 1156 var acont = |
| 1157 new FunctionValueA(receiver, exceptionComponents, continuation); |
| 1158 return new EvalListConfiguration( |
| 1159 args, environment, exceptionComponents, acont); |
| 1160 } |
| 1161 |
| 1005 if (arguments.positional.isEmpty) { | 1162 if (arguments.positional.isEmpty) { |
| 1006 Value returnValue = receiver.invokeMethod(methodName); | 1163 Value returnValue = receiver.invokeMethod(methodName); |
| 1007 return new ValuePassingConfiguration(continuation, returnValue); | 1164 return new ValuePassingConfiguration(continuation, returnValue); |
| 1008 } | 1165 } |
| 1009 var cont = new ArgumentsEK( | 1166 var cont = new ArgumentsEK( |
| 1010 receiver, methodName, arguments, environment, continuation); | 1167 receiver, methodName, arguments, environment, continuation); |
| 1011 | 1168 |
| 1012 return new EvalConfiguration( | 1169 return new EvalConfiguration( |
| 1013 arguments.positional.first, environment, exceptionComponents, cont); | 1170 arguments.positional.first, environment, exceptionComponents, cont); |
| 1014 } | 1171 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1033 } | 1190 } |
| 1034 | 1191 |
| 1035 class VariableSetEK extends ExpressionContinuation { | 1192 class VariableSetEK extends ExpressionContinuation { |
| 1036 final VariableDeclaration variable; | 1193 final VariableDeclaration variable; |
| 1037 final Environment environment; | 1194 final Environment environment; |
| 1038 final ExpressionContinuation continuation; | 1195 final ExpressionContinuation continuation; |
| 1039 | 1196 |
| 1040 VariableSetEK(this.variable, this.environment, this.continuation); | 1197 VariableSetEK(this.variable, this.environment, this.continuation); |
| 1041 | 1198 |
| 1042 Configuration call(Value value) { | 1199 Configuration call(Value value) { |
| 1043 environment.assign(variable, value); | 1200 environment.updateStore(variable, value); |
| 1044 return new ValuePassingConfiguration(continuation, value); | 1201 return new ValuePassingConfiguration(continuation, value); |
| 1045 } | 1202 } |
| 1046 } | 1203 } |
| 1047 | 1204 |
| 1048 class NotEK extends ExpressionContinuation { | 1205 class NotEK extends ExpressionContinuation { |
| 1049 final ExpressionContinuation continuation; | 1206 final ExpressionContinuation continuation; |
| 1050 | 1207 |
| 1051 NotEK(this.continuation); | 1208 NotEK(this.continuation); |
| 1052 | 1209 |
| 1053 Configuration call(Value value) { | 1210 Configuration call(Value value) { |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1115 final VariableDeclaration variable; | 1272 final VariableDeclaration variable; |
| 1116 final Expression letBody; | 1273 final Expression letBody; |
| 1117 final Environment environment; | 1274 final Environment environment; |
| 1118 final ExceptionComponents exceptionComponents; | 1275 final ExceptionComponents exceptionComponents; |
| 1119 final ExpressionContinuation continuation; | 1276 final ExpressionContinuation continuation; |
| 1120 | 1277 |
| 1121 LetEK(this.variable, this.letBody, this.environment, this.exceptionComponents, | 1278 LetEK(this.variable, this.letBody, this.environment, this.exceptionComponents, |
| 1122 this.continuation); | 1279 this.continuation); |
| 1123 | 1280 |
| 1124 Configuration call(Value value) { | 1281 Configuration call(Value value) { |
| 1125 var letEnv = new Environment(environment); | 1282 var letEnv = environment.extend(variable, value); |
| 1126 letEnv.extend(variable, value); | |
| 1127 return new EvalConfiguration( | 1283 return new EvalConfiguration( |
| 1128 letBody, letEnv, exceptionComponents, continuation); | 1284 letBody, letEnv, exceptionComponents, continuation); |
| 1129 } | 1285 } |
| 1130 } | 1286 } |
| 1131 | 1287 |
| 1132 /// Represents the continuation for the condition expression in [WhileStatement]
. | 1288 /// Represents the continuation for the condition expression in [WhileStatement]
. |
| 1133 class WhileConditionEK extends ExpressionContinuation { | 1289 class WhileConditionEK extends ExpressionContinuation { |
| 1134 final Expression condition; | 1290 final Expression condition; |
| 1135 final Statement body; | 1291 final Statement body; |
| 1136 final Environment enclosingEnv; | 1292 final Environment enclosingEnv; |
| (...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1493 return new EvalConfiguration(node.expression, conf.environment, | 1649 return new EvalConfiguration(node.expression, conf.environment, |
| 1494 conf.state.exceptionComponents, cont); | 1650 conf.state.exceptionComponents, cont); |
| 1495 } | 1651 } |
| 1496 | 1652 |
| 1497 Configuration visitBlock(Block node, ExecConfiguration conf) { | 1653 Configuration visitBlock(Block node, ExecConfiguration conf) { |
| 1498 if (node.statements.isEmpty) { | 1654 if (node.statements.isEmpty) { |
| 1499 return new ForwardConfiguration( | 1655 return new ForwardConfiguration( |
| 1500 conf.state.continuation, conf.environment); | 1656 conf.state.continuation, conf.environment); |
| 1501 } | 1657 } |
| 1502 | 1658 |
| 1503 var env = new Environment(conf.environment); | |
| 1504 var cont = new BlockSK.fromConfig(node.statements.skip(1).toList(), conf); | 1659 var cont = new BlockSK.fromConfig(node.statements.skip(1).toList(), conf); |
| 1505 return new ExecConfiguration( | 1660 return new ExecConfiguration(node.statements.first, conf.environment, |
| 1506 node.statements.first, env, conf.state.withContinuation(cont)); | 1661 conf.state.withContinuation(cont)); |
| 1507 } | 1662 } |
| 1508 | 1663 |
| 1509 Configuration visitEmptyStatement( | 1664 Configuration visitEmptyStatement( |
| 1510 EmptyStatement node, ExecConfiguration conf) { | 1665 EmptyStatement node, ExecConfiguration conf) { |
| 1511 return new ForwardConfiguration(conf.state.continuation, conf.environment); | 1666 return new ForwardConfiguration(conf.state.continuation, conf.environment); |
| 1512 } | 1667 } |
| 1513 | 1668 |
| 1514 Configuration visitIfStatement(IfStatement node, ExecConfiguration conf) { | 1669 Configuration visitIfStatement(IfStatement node, ExecConfiguration conf) { |
| 1515 var cont = new IfConditionEK( | 1670 var cont = new IfConditionEK( |
| 1516 node.then, node.otherwise, conf.environment, conf.state); | 1671 node.then, node.otherwise, conf.environment, conf.state); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1592 VariableDeclaration node, ExecConfiguration conf) { | 1747 VariableDeclaration node, ExecConfiguration conf) { |
| 1593 if (node.initializer != null) { | 1748 if (node.initializer != null) { |
| 1594 var cont = new VariableInitializerEK( | 1749 var cont = new VariableInitializerEK( |
| 1595 node, conf.environment, conf.state.continuation); | 1750 node, conf.environment, conf.state.continuation); |
| 1596 return new EvalConfiguration(node.initializer, conf.environment, | 1751 return new EvalConfiguration(node.initializer, conf.environment, |
| 1597 conf.state.exceptionComponents, cont); | 1752 conf.state.exceptionComponents, cont); |
| 1598 } | 1753 } |
| 1599 return new ForwardConfiguration(conf.state.continuation, | 1754 return new ForwardConfiguration(conf.state.continuation, |
| 1600 conf.environment.extend(node, Value.nullInstance)); | 1755 conf.environment.extend(node, Value.nullInstance)); |
| 1601 } | 1756 } |
| 1757 |
| 1758 Configuration visitFunctionDeclaration( |
| 1759 FunctionDeclaration node, ExecConfiguration conf) { |
| 1760 var newEnv = conf.environment.extend(node.variable, Value.nullInstance); |
| 1761 var fun = new FunctionValue(node.function, newEnv); |
| 1762 newEnv.updateStore(node.variable, fun); |
| 1763 return new ForwardConfiguration(conf.state.continuation, newEnv); |
| 1764 } |
| 1602 } | 1765 } |
| 1603 | 1766 |
| 1604 // ------------------------------------------------------------------------ | 1767 // ------------------------------------------------------------------------ |
| 1605 // VALUES | 1768 // VALUES |
| 1606 // ------------------------------------------------------------------------ | 1769 // ------------------------------------------------------------------------ |
| 1607 | 1770 |
| 1608 typedef Value Getter(Value receiver); | 1771 typedef Value Getter(Value receiver); |
| 1609 typedef void Setter(Value receiver, Value value); | 1772 typedef void Setter(Value receiver, Value value); |
| 1610 | 1773 |
| 1611 class Class { | 1774 class Class { |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1727 Object get value => this; | 1890 Object get value => this; |
| 1728 | 1891 |
| 1729 ObjectValue(this.class_) : fields = new List<Location>(class_.instanceSize) { | 1892 ObjectValue(this.class_) : fields = new List<Location>(class_.instanceSize) { |
| 1730 for (int i = 0; i < fields.length; i++) { | 1893 for (int i = 0; i < fields.length; i++) { |
| 1731 // Create fresh locations for each field. | 1894 // Create fresh locations for each field. |
| 1732 fields[i] = new Location.empty(); | 1895 fields[i] = new Location.empty(); |
| 1733 } | 1896 } |
| 1734 } | 1897 } |
| 1735 } | 1898 } |
| 1736 | 1899 |
| 1900 class FunctionValue extends Value { |
| 1901 Class get class_ => throw 'Class for FunctionValue is not defined'; |
| 1902 List<Location> get fields => throw 'FunctionValue has no fields.'; |
| 1903 |
| 1904 FunctionValue get value => this; |
| 1905 |
| 1906 final FunctionNode function; |
| 1907 final Environment environment; |
| 1908 |
| 1909 FunctionValue(this.function, this.environment); |
| 1910 } |
| 1911 |
| 1737 abstract class LiteralValue extends Value { | 1912 abstract class LiteralValue extends Value { |
| 1738 Class get class_ => | 1913 Class get class_ => |
| 1739 notImplemented(m: "Loading class for literal is not implemented."); | 1914 notImplemented(m: "Loading class for literal is not implemented."); |
| 1740 List<Location> get fields => | 1915 List<Location> get fields => |
| 1741 notImplemented(m: "Literal value does not have fields"); | 1916 notImplemented(m: "Literal value does not have fields"); |
| 1742 | 1917 |
| 1743 const LiteralValue(); | 1918 const LiteralValue(); |
| 1744 } | 1919 } |
| 1745 | 1920 |
| 1746 class StringValue extends LiteralValue { | 1921 class StringValue extends LiteralValue { |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1893 /// Initializes all non initialized fields from the provided class to | 2068 /// Initializes all non initialized fields from the provided class to |
| 1894 /// `Value.nullInstance` in the provided value. | 2069 /// `Value.nullInstance` in the provided value. |
| 1895 void _initializeNullFields(Class class_, Value value) { | 2070 void _initializeNullFields(Class class_, Value value) { |
| 1896 int startIndex = class_.superclass?.instanceSize ?? 0; | 2071 int startIndex = class_.superclass?.instanceSize ?? 0; |
| 1897 for (int i = startIndex; i < class_.instanceSize; i++) { | 2072 for (int i = startIndex; i < class_.instanceSize; i++) { |
| 1898 if (value.fields[i].value == null) { | 2073 if (value.fields[i].value == null) { |
| 1899 value.fields[i].value = Value.nullInstance; | 2074 value.fields[i].value = Value.nullInstance; |
| 1900 } | 2075 } |
| 1901 } | 2076 } |
| 1902 } | 2077 } |
| OLD | NEW |