| 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 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 99 | 99 |
| 100 /// Evaluate expressions. | 100 /// Evaluate expressions. |
| 101 class Evaluator extends ExpressionVisitor1<Configuration, EvalConfiguration> { | 101 class Evaluator extends ExpressionVisitor1<Configuration, EvalConfiguration> { |
| 102 Configuration eval(Expression expr, EvalConfiguration config) => | 102 Configuration eval(Expression expr, EvalConfiguration config) => |
| 103 expr.accept1(this, config); | 103 expr.accept1(this, config); |
| 104 | 104 |
| 105 Configuration evalList(List<InterpreterExpression> list, Environment env, | 105 Configuration evalList(List<InterpreterExpression> list, Environment env, |
| 106 ApplicationContinuation cont) { | 106 ApplicationContinuation cont) { |
| 107 if (list.isNotEmpty) { | 107 if (list.isNotEmpty) { |
| 108 return new EvalConfiguration(list.first.expression, env, | 108 return new EvalConfiguration(list.first.expression, env, |
| 109 new ExpressionListContinuation(list.first, list.skip(1), env, cont)); | 109 new ExpressionListEK(list.first, list.skip(1), env, cont)); |
| 110 } | 110 } |
| 111 return new ApplicationConfiguration(cont, <InterpreterValue>[]); | 111 return new ApplicationConfiguration(cont, <InterpreterValue>[]); |
| 112 } | 112 } |
| 113 | 113 |
| 114 Configuration defaultExpression(Expression node, EvalConfiguration config) { | 114 Configuration defaultExpression(Expression node, EvalConfiguration config) { |
| 115 throw new NotImplemented('Evaluation for expressions of type ' | 115 throw new NotImplemented('Evaluation for expressions of type ' |
| 116 '${node.runtimeType} is not implemented.'); | 116 '${node.runtimeType} is not implemented.'); |
| 117 } | 117 } |
| 118 | 118 |
| 119 Configuration visitInvalidExpression1( | 119 Configuration visitInvalidExpression1( |
| 120 InvalidExpression node, EvalConfiguration config) { | 120 InvalidExpression node, EvalConfiguration config) { |
| 121 throw 'Invalid expression at ${node.location.toString()}'; | 121 throw 'Invalid expression at ${node.location.toString()}'; |
| 122 } | 122 } |
| 123 | 123 |
| 124 Configuration visitVariableGet(VariableGet node, EvalConfiguration config) { | 124 Configuration visitVariableGet(VariableGet node, EvalConfiguration config) { |
| 125 Value value = config.environment.lookup(node.variable); | 125 Value value = config.environment.lookup(node.variable); |
| 126 return new ValuePassingConfiguration(config.continuation, value); | 126 return new ValuePassingConfiguration(config.continuation, value); |
| 127 } | 127 } |
| 128 | 128 |
| 129 Configuration visitVariableSet(VariableSet node, EvalConfiguration config) { | 129 Configuration visitVariableSet(VariableSet node, EvalConfiguration config) { |
| 130 var cont = new VariableSetContinuation( | 130 var cont = new VariableSetEK( |
| 131 node.variable, config.environment, config.continuation); | 131 node.variable, config.environment, config.continuation); |
| 132 return new EvalConfiguration(node.value, config.environment, cont); | 132 return new EvalConfiguration(node.value, config.environment, cont); |
| 133 } | 133 } |
| 134 | 134 |
| 135 Configuration visitPropertyGet(PropertyGet node, EvalConfiguration config) { | 135 Configuration visitPropertyGet(PropertyGet node, EvalConfiguration config) { |
| 136 var cont = new PropertyGetContinuation(node.name, config.continuation); | 136 var cont = new PropertyGetEK(node.name, config.continuation); |
| 137 return new EvalConfiguration(node.receiver, config.environment, cont); | 137 return new EvalConfiguration(node.receiver, config.environment, cont); |
| 138 } | 138 } |
| 139 | 139 |
| 140 Configuration visitPropertySet(PropertySet node, EvalConfiguration config) { | 140 Configuration visitPropertySet(PropertySet node, EvalConfiguration config) { |
| 141 var cont = new PropertySetContinuation( | 141 var cont = new PropertySetEK( |
| 142 node.value, node.name, config.environment, config.continuation); | 142 node.value, node.name, config.environment, config.continuation); |
| 143 return new EvalConfiguration(node.receiver, config.environment, cont); | 143 return new EvalConfiguration(node.receiver, config.environment, cont); |
| 144 } | 144 } |
| 145 | 145 |
| 146 Configuration visitStaticGet(StaticGet node, EvalConfiguration config) => | 146 Configuration visitStaticGet(StaticGet node, EvalConfiguration config) => |
| 147 defaultExpression(node, config); | 147 defaultExpression(node, config); |
| 148 Configuration visitStaticSet(StaticSet node, EvalConfiguration config) => | 148 Configuration visitStaticSet(StaticSet node, EvalConfiguration config) => |
| 149 defaultExpression(node, config); | 149 defaultExpression(node, config); |
| 150 | 150 |
| 151 Configuration visitStaticInvocation( | 151 Configuration visitStaticInvocation( |
| 152 StaticInvocation node, EvalConfiguration config) { | 152 StaticInvocation node, EvalConfiguration config) { |
| 153 if ('print' == node.name.toString()) { | 153 if ('print' == node.name.toString()) { |
| 154 var cont = new PrintContinuation(config.continuation); | 154 var cont = new PrintEK(config.continuation); |
| 155 return new EvalConfiguration( | 155 return new EvalConfiguration( |
| 156 node.arguments.positional.first, config.environment, cont); | 156 node.arguments.positional.first, config.environment, cont); |
| 157 } else { | 157 } else { |
| 158 log.info('static-invocation-${node.target.name.toString()}\n'); | 158 log.info('static-invocation-${node.target.name.toString()}\n'); |
| 159 | 159 |
| 160 List<InterpreterExpression> args = | 160 List<InterpreterExpression> args = |
| 161 _createArgumentExpressionList(node.arguments, node.target.function); | 161 _createArgumentExpressionList(node.arguments, node.target.function); |
| 162 ApplicationContinuation cont = new StaticInvocationApplication( | 162 ApplicationContinuation cont = |
| 163 node.target.function, config.continuation); | 163 new StaticInvocationA(node.target.function, config.continuation); |
| 164 return new EvalListConfiguration(args, config.environment, cont); | 164 return new EvalListConfiguration(args, config.environment, cont); |
| 165 } | 165 } |
| 166 } | 166 } |
| 167 | 167 |
| 168 Configuration visitMethodInvocation( | 168 Configuration visitMethodInvocation( |
| 169 MethodInvocation node, EvalConfiguration config) { | 169 MethodInvocation node, EvalConfiguration config) { |
| 170 // Currently supports only method invocation with <2 arguments and is used | 170 // Currently supports only method invocation with <2 arguments and is used |
| 171 // to evaluate implemented operators for int, double and String values. | 171 // to evaluate implemented operators for int, double and String values. |
| 172 var cont = new MethodInvocationContinuation( | 172 var cont = new MethodInvocationEK( |
| 173 node.arguments, node.name, config.environment, config.continuation); | 173 node.arguments, node.name, config.environment, config.continuation); |
| 174 | 174 |
| 175 return new EvalConfiguration(node.receiver, config.environment, cont); | 175 return new EvalConfiguration(node.receiver, config.environment, cont); |
| 176 } | 176 } |
| 177 | 177 |
| 178 Configuration visitConstructorInvocation( | 178 Configuration visitConstructorInvocation( |
| 179 ConstructorInvocation node, EvalConfiguration config) { | 179 ConstructorInvocation node, EvalConfiguration config) { |
| 180 ApplicationContinuation cont = | 180 ApplicationContinuation cont = |
| 181 new ConstructorInvocationApplication(node.target, config.continuation); | 181 new ConstructorInvocationA(node.target, config.continuation); |
| 182 var args = | 182 var args = |
| 183 _createArgumentExpressionList(node.arguments, node.target.function); | 183 _createArgumentExpressionList(node.arguments, node.target.function); |
| 184 | 184 |
| 185 return new EvalListConfiguration(args, config.environment, cont); | 185 return new EvalListConfiguration(args, config.environment, cont); |
| 186 } | 186 } |
| 187 | 187 |
| 188 Configuration visitNot(Not node, EvalConfiguration config) { | 188 Configuration visitNot(Not node, EvalConfiguration config) { |
| 189 return new EvalConfiguration(node.operand, config.environment, | 189 return new EvalConfiguration( |
| 190 new NotContinuation(config.continuation)); | 190 node.operand, config.environment, new NotEK(config.continuation)); |
| 191 } | 191 } |
| 192 | 192 |
| 193 Configuration visitLogicalExpression( | 193 Configuration visitLogicalExpression( |
| 194 LogicalExpression node, EvalConfiguration config) { | 194 LogicalExpression node, EvalConfiguration config) { |
| 195 if ('||' == node.operator) { | 195 if ('||' == node.operator) { |
| 196 var cont = new OrContinuation( | 196 var cont = new OrEK(node.right, config.environment, config.continuation); |
| 197 node.right, config.environment, config.continuation); | |
| 198 return new EvalConfiguration(node.left, config.environment, cont); | 197 return new EvalConfiguration(node.left, config.environment, cont); |
| 199 } else { | 198 } else { |
| 200 assert('&&' == node.operator); | 199 assert('&&' == node.operator); |
| 201 var cont = new AndContinuation( | 200 var cont = new AndEK(node.right, config.environment, config.continuation); |
| 202 node.right, config.environment, config.continuation); | |
| 203 return new EvalConfiguration(node.left, config.environment, cont); | 201 return new EvalConfiguration(node.left, config.environment, cont); |
| 204 } | 202 } |
| 205 } | 203 } |
| 206 | 204 |
| 207 Configuration visitConditionalExpression( | 205 Configuration visitConditionalExpression( |
| 208 ConditionalExpression node, EvalConfiguration config) { | 206 ConditionalExpression node, EvalConfiguration config) { |
| 209 var cont = new ConditionalContinuation( | 207 var cont = new ConditionalEK( |
| 210 node.then, node.otherwise, config.environment, config.continuation); | 208 node.then, node.otherwise, config.environment, config.continuation); |
| 211 return new EvalConfiguration(node.condition, config.environment, cont); | 209 return new EvalConfiguration(node.condition, config.environment, cont); |
| 212 } | 210 } |
| 213 | 211 |
| 214 Configuration visitStringConcatenation( | 212 Configuration visitStringConcatenation( |
| 215 StringConcatenation node, EvalConfiguration config) { | 213 StringConcatenation node, EvalConfiguration config) { |
| 216 var cont = new StringConcatenationContinuation(config.continuation); | 214 var cont = new StringConcatenationA(config.continuation); |
| 217 var expressions = node.expressions | 215 var expressions = node.expressions |
| 218 .map((Expression e) => new PositionalExpression(e)) | 216 .map((Expression e) => new PositionalExpression(e)) |
| 219 .toList(); | 217 .toList(); |
| 220 return new EvalListConfiguration(expressions, config.environment, cont); | 218 return new EvalListConfiguration(expressions, config.environment, cont); |
| 221 } | 219 } |
| 222 | 220 |
| 223 Configuration visitThisExpression( | 221 Configuration visitThisExpression( |
| 224 ThisExpression node, EvalConfiguration config) { | 222 ThisExpression node, EvalConfiguration config) { |
| 225 return new ValuePassingConfiguration( | 223 return new ValuePassingConfiguration( |
| 226 config.continuation, config.environment.thisInstance); | 224 config.continuation, config.environment.thisInstance); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 248 Value value = node.value ? Value.trueInstance : Value.falseInstance; | 246 Value value = node.value ? Value.trueInstance : Value.falseInstance; |
| 249 return new ValuePassingConfiguration(config.continuation, value); | 247 return new ValuePassingConfiguration(config.continuation, value); |
| 250 } | 248 } |
| 251 | 249 |
| 252 Configuration visitNullLiteral(NullLiteral node, EvalConfiguration config) { | 250 Configuration visitNullLiteral(NullLiteral node, EvalConfiguration config) { |
| 253 return new ValuePassingConfiguration( | 251 return new ValuePassingConfiguration( |
| 254 config.continuation, Value.nullInstance); | 252 config.continuation, Value.nullInstance); |
| 255 } | 253 } |
| 256 | 254 |
| 257 Configuration visitLet(Let node, EvalConfiguration config) { | 255 Configuration visitLet(Let node, EvalConfiguration config) { |
| 258 var letCont = new LetContinuation( | 256 var letCont = new LetEK( |
| 259 node.variable, node.body, config.environment, config.continuation); | 257 node.variable, node.body, config.environment, config.continuation); |
| 260 return new EvalConfiguration( | 258 return new EvalConfiguration( |
| 261 node.variable.initializer, config.environment, letCont); | 259 node.variable.initializer, config.environment, letCont); |
| 262 } | 260 } |
| 263 } | 261 } |
| 264 | 262 |
| 265 /// Represents a state for statement execution. | 263 /// Represents a state for statement execution. |
| 266 class State { | 264 class State { |
| 267 final Environment environment; | 265 final Environment environment; |
| 268 final Label labels; | 266 final Label labels; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 308 | 306 |
| 309 Label(this.statement, this.configuration, this.enclosingLabel); | 307 Label(this.statement, this.configuration, this.enclosingLabel); |
| 310 | 308 |
| 311 Label lookupLabel(LabeledStatement s) { | 309 Label lookupLabel(LabeledStatement s) { |
| 312 if (identical(s, statement)) return this; | 310 if (identical(s, statement)) return this; |
| 313 assert(enclosingLabel != null); | 311 assert(enclosingLabel != null); |
| 314 return enclosingLabel.lookupLabel(s); | 312 return enclosingLabel.lookupLabel(s); |
| 315 } | 313 } |
| 316 } | 314 } |
| 317 | 315 |
| 316 // ------------------------------------------------------------------------ |
| 317 // Configurations |
| 318 // ------------------------------------------------------------------------ |
| 319 |
| 318 abstract class Configuration { | 320 abstract class Configuration { |
| 319 /// Executes the current and returns the next configuration. | 321 /// Executes the current and returns the next configuration. |
| 320 Configuration step(StatementExecuter executer); | 322 Configuration step(StatementExecuter executer); |
| 321 } | 323 } |
| 322 | 324 |
| 325 /// Represents the configuration for evaluating an [Expression]. |
| 326 class EvalConfiguration extends Configuration { |
| 327 final Expression expression; |
| 328 |
| 329 /// Environment in which the expression is evaluated. |
| 330 final Environment environment; |
| 331 |
| 332 /// Next continuation to be applied. |
| 333 final Continuation continuation; |
| 334 |
| 335 EvalConfiguration(this.expression, this.environment, this.continuation); |
| 336 |
| 337 Configuration step(StatementExecuter executer) => |
| 338 executer.eval(expression, this); |
| 339 } |
| 340 |
| 341 /// Represents the configuration for evaluating a list of expressions. |
| 342 class EvalListConfiguration extends Configuration { |
| 343 final List<InterpreterExpression> expressions; |
| 344 final Environment environment; |
| 345 final Continuation continuation; |
| 346 |
| 347 EvalListConfiguration(this.expressions, this.environment, this.continuation); |
| 348 |
| 349 Configuration step(StatementExecuter executer) => |
| 350 executer.evalList(expressions, environment, continuation); |
| 351 } |
| 352 |
| 323 /// Represents the configuration for execution of statement. | 353 /// Represents the configuration for execution of statement. |
| 324 class ExecConfiguration extends Configuration { | 354 class ExecConfiguration extends Configuration { |
| 325 final Statement statement; | 355 final Statement statement; |
| 326 final State state; | 356 final State state; |
| 327 | 357 |
| 328 ExecConfiguration(this.statement, this.state); | 358 ExecConfiguration(this.statement, this.state); |
| 329 | 359 |
| 330 Configuration step(StatementExecuter executer) => | 360 Configuration step(StatementExecuter executer) => |
| 331 executer.exec(statement, state); | 361 executer.exec(statement, state); |
| 332 } | 362 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 366 /// Represents the configuration for applying an [ApplicationContinuation]. | 396 /// Represents the configuration for applying an [ApplicationContinuation]. |
| 367 class ApplicationConfiguration extends Configuration { | 397 class ApplicationConfiguration extends Configuration { |
| 368 final ApplicationContinuation continuation; | 398 final ApplicationContinuation continuation; |
| 369 final List<InterpreterValue> values; | 399 final List<InterpreterValue> values; |
| 370 | 400 |
| 371 ApplicationConfiguration(this.continuation, this.values); | 401 ApplicationConfiguration(this.continuation, this.values); |
| 372 | 402 |
| 373 Configuration step(StatementExecuter _) => continuation(values); | 403 Configuration step(StatementExecuter _) => continuation(values); |
| 374 } | 404 } |
| 375 | 405 |
| 376 /// Represents the configuration for evaluating an [Expression]. | 406 // ------------------------------------------------------------------------ |
| 377 class EvalConfiguration extends Configuration { | 407 // Interpreter Expressions and Values |
| 378 final Expression expression; | 408 // ------------------------------------------------------------------------ |
| 379 | |
| 380 /// Environment in which the expression is evaluated. | |
| 381 final Environment environment; | |
| 382 | |
| 383 /// Next continuation to be applied. | |
| 384 final Continuation continuation; | |
| 385 | |
| 386 EvalConfiguration(this.expression, this.environment, this.continuation); | |
| 387 | |
| 388 Configuration step(StatementExecuter executer) => | |
| 389 executer.eval(expression, this); | |
| 390 } | |
| 391 | |
| 392 /// Represents the configuration for evaluating a list of expressions. | |
| 393 class EvalListConfiguration extends Configuration { | |
| 394 final List<InterpreterExpression> expressions; | |
| 395 final Environment environment; | |
| 396 final Continuation continuation; | |
| 397 | |
| 398 EvalListConfiguration(this.expressions, this.environment, this.continuation); | |
| 399 | |
| 400 Configuration step(StatementExecuter executer) => | |
| 401 executer.evalList(expressions, environment, continuation); | |
| 402 } | |
| 403 | |
| 404 abstract class InterpreterExpression { | 409 abstract class InterpreterExpression { |
| 405 Expression get expression; | 410 Expression get expression; |
| 406 | 411 |
| 407 InterpreterValue assignValue(Value v); | 412 InterpreterValue assignValue(Value v); |
| 408 } | 413 } |
| 409 | 414 |
| 410 class PositionalExpression extends InterpreterExpression { | 415 class PositionalExpression extends InterpreterExpression { |
| 411 final Expression expression; | 416 final Expression expression; |
| 412 | 417 |
| 413 PositionalExpression(this.expression); | 418 PositionalExpression(this.expression); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 471 final Field field; | 476 final Field field; |
| 472 final Value value; | 477 final Value value; |
| 473 | 478 |
| 474 FieldInitializerValue(this.field, this.value); | 479 FieldInitializerValue(this.field, this.value); |
| 475 } | 480 } |
| 476 | 481 |
| 477 abstract class Continuation {} | 482 abstract class Continuation {} |
| 478 | 483 |
| 479 /// Represents the continuation called after the evaluation of argument | 484 /// Represents the continuation called after the evaluation of argument |
| 480 /// expressions. | 485 /// expressions. |
| 486 /// |
| 487 /// There are various kinds of [ApplicationContinuation] and their names are |
| 488 /// suffixed with "A". |
| 481 abstract class ApplicationContinuation extends Continuation { | 489 abstract class ApplicationContinuation extends Continuation { |
| 482 Configuration call(List<InterpreterValue> values); | 490 Configuration call(List<InterpreterValue> values); |
| 483 | 491 |
| 484 /// Binds actual argument values to formal parameters of the function in a | 492 /// Binds actual argument values to formal parameters of the function in a |
| 485 /// new environment or in the provided initial environment. | 493 /// new environment or in the provided initial environment. |
| 486 /// TODO: Add checks for validation of arguments according to spec. | 494 /// TODO: Add checks for validation of arguments according to spec. |
| 487 static Environment createEnvironment( | 495 static Environment createEnvironment( |
| 488 FunctionNode function, List<InterpreterValue> args, | 496 FunctionNode function, List<InterpreterValue> args, |
| 489 [Environment parentEnv]) { | 497 [Environment parentEnv]) { |
| 490 Environment newEnv = new Environment(parentEnv); | 498 Environment newEnv = new Environment(parentEnv); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 504 | 512 |
| 505 // Add named parameters. | 513 // Add named parameters. |
| 506 for (VariableDeclaration v in function.namedParameters) { | 514 for (VariableDeclaration v in function.namedParameters) { |
| 507 newEnv.expand(v, named[v.name.toString()]); | 515 newEnv.expand(v, named[v.name.toString()]); |
| 508 } | 516 } |
| 509 | 517 |
| 510 return newEnv; | 518 return newEnv; |
| 511 } | 519 } |
| 512 } | 520 } |
| 513 | 521 |
| 522 class StringConcatenationA extends ApplicationContinuation { |
| 523 final ExpressionContinuation continuation; |
| 524 |
| 525 StringConcatenationA(this.continuation); |
| 526 |
| 527 Configuration call(List<InterpreterValue> values) { |
| 528 StringBuffer result = new StringBuffer(); |
| 529 for (InterpreterValue v in values.reversed) { |
| 530 result.write(v.value.value); |
| 531 } |
| 532 return new ValuePassingConfiguration( |
| 533 continuation, new StringValue(result.toString())); |
| 534 } |
| 535 } |
| 536 |
| 514 /// Represents the application continuation for static invocation. | 537 /// Represents the application continuation for static invocation. |
| 515 class StaticInvocationApplication extends ApplicationContinuation { | 538 class StaticInvocationA extends ApplicationContinuation { |
| 516 final FunctionNode function; | 539 final FunctionNode function; |
| 517 final ExpressionContinuation continuation; | 540 final ExpressionContinuation continuation; |
| 518 | 541 |
| 519 StaticInvocationApplication(this.function, this.continuation); | 542 StaticInvocationA(this.function, this.continuation); |
| 520 | 543 |
| 521 Configuration call(List<InterpreterValue> argValues) { | 544 Configuration call(List<InterpreterValue> argValues) { |
| 522 Environment functionEnv = | 545 Environment functionEnv = |
| 523 ApplicationContinuation.createEnvironment(function, argValues); | 546 ApplicationContinuation.createEnvironment(function, argValues); |
| 524 | 547 |
| 525 State bodyState = new State.initial() | 548 State bodyState = new State.initial() |
| 526 .withExpressionContinuation(continuation) | 549 .withExpressionContinuation(continuation) |
| 527 .withConfiguration(new ExitConfiguration(continuation)) | 550 .withConfiguration(new ExitConfiguration(continuation)) |
| 528 .withEnvironment(functionEnv); | 551 .withEnvironment(functionEnv); |
| 529 return new ExecConfiguration(function.body, bodyState); | 552 return new ExecConfiguration(function.body, bodyState); |
| 530 } | 553 } |
| 531 } | 554 } |
| 532 | 555 |
| 533 /// Represents the application continuation for constructor invocation applied | 556 /// Represents the application continuation for constructor invocation applied |
| 534 /// on the list of evaluated arguments. | 557 /// on the list of evaluated arguments. |
| 535 class ConstructorInvocationApplication extends ApplicationContinuation { | 558 class ConstructorInvocationA extends ApplicationContinuation { |
| 536 final Constructor constructor; | 559 final Constructor constructor; |
| 537 final ExpressionContinuation continuation; | 560 final ExpressionContinuation continuation; |
| 538 | 561 |
| 539 ConstructorInvocationApplication(this.constructor, this.continuation); | 562 ConstructorInvocationA(this.constructor, this.continuation); |
| 540 | 563 |
| 541 Configuration call(List<InterpreterValue> argValues) { | 564 Configuration call(List<InterpreterValue> argValues) { |
| 542 Environment ctrEnv = ApplicationContinuation.createEnvironment( | 565 Environment ctrEnv = ApplicationContinuation.createEnvironment( |
| 543 constructor.function, argValues); | 566 constructor.function, argValues); |
| 544 | 567 |
| 545 var class_ = new Class(constructor.enclosingClass.reference); | 568 var class_ = new Class(constructor.enclosingClass.reference); |
| 546 var newObject = | 569 var newObject = |
| 547 new ObjectValue(class_, new List<Value>(class_.instanceSize)); | 570 new ObjectValue(class_, new List<Value>(class_.instanceSize)); |
| 548 | 571 |
| 549 return new ObjectInitializationConfiguration( | 572 return new ObjectInitializationConfiguration( |
| 550 constructor, | 573 constructor, |
| 551 new InstanceEnvironment(newObject, ctrEnv), | 574 new InstanceEnvironment(newObject, ctrEnv), |
| 552 new NewInstanceConfiguration(continuation, newObject)); | 575 new NewInstanceConfiguration(continuation, newObject)); |
| 553 } | 576 } |
| 554 } | 577 } |
| 555 | 578 |
| 556 /// Represents the application continuation for redirecting constructor | 579 /// Represents the application continuation for redirecting constructor |
| 557 /// invocation applied on the list of evaluated arguments. | 580 /// invocation applied on the list of evaluated arguments. |
| 558 class RedirectingConstructorApplication extends ApplicationContinuation { | 581 class RedirectingConstructorA extends ApplicationContinuation { |
| 559 final Constructor constructor; | 582 final Constructor constructor; |
| 560 final Environment environment; | 583 final Environment environment; |
| 561 final ExecConfiguration configuration; | 584 final ExecConfiguration configuration; |
| 562 | 585 |
| 563 RedirectingConstructorApplication( | 586 RedirectingConstructorA( |
| 564 this.constructor, this.environment, this.configuration); | 587 this.constructor, this.environment, this.configuration); |
| 565 | 588 |
| 566 Configuration call(List<InterpreterValue> argValues) { | 589 Configuration call(List<InterpreterValue> argValues) { |
| 567 Value object = environment.thisInstance; | 590 Value object = environment.thisInstance; |
| 568 Environment ctrEnv = ApplicationContinuation.createEnvironment( | 591 Environment ctrEnv = ApplicationContinuation.createEnvironment( |
| 569 constructor.function, | 592 constructor.function, |
| 570 argValues, | 593 argValues, |
| 571 new InstanceEnvironment(object, new Environment.empty())); | 594 new InstanceEnvironment(object, new Environment.empty())); |
| 572 | 595 |
| 573 return new ObjectInitializationConfiguration( | 596 return new ObjectInitializationConfiguration( |
| 574 constructor, ctrEnv, configuration); | 597 constructor, ctrEnv, configuration); |
| 575 } | 598 } |
| 576 } | 599 } |
| 577 | 600 |
| 578 /// Represents the application continuation for super constructor | 601 /// Represents the application continuation for super constructor |
| 579 /// invocation applied on the list of evaluated arguments. | 602 /// invocation applied on the list of evaluated arguments. |
| 580 class SuperConstructorApplication extends ApplicationContinuation { | 603 class SuperConstructorA extends ApplicationContinuation { |
| 581 final Constructor constructor; | 604 final Constructor constructor; |
| 582 final Environment environment; | 605 final Environment environment; |
| 583 final ExecConfiguration configuration; | 606 final ExecConfiguration configuration; |
| 584 | 607 |
| 585 SuperConstructorApplication( | 608 SuperConstructorA(this.constructor, this.environment, this.configuration); |
| 586 this.constructor, this.environment, this.configuration); | |
| 587 | 609 |
| 588 Configuration call(List<InterpreterValue> argValues) { | 610 Configuration call(List<InterpreterValue> argValues) { |
| 589 Value object = environment.thisInstance; | 611 Value object = environment.thisInstance; |
| 590 | 612 |
| 591 Environment superEnv = ApplicationContinuation.createEnvironment( | 613 Environment superEnv = ApplicationContinuation.createEnvironment( |
| 592 constructor.function, | 614 constructor.function, |
| 593 argValues, | 615 argValues, |
| 594 new InstanceEnvironment(object, new Environment.empty())); | 616 new InstanceEnvironment(object, new Environment.empty())); |
| 595 | 617 |
| 596 return new ObjectInitializationConfiguration( | 618 return new ObjectInitializationConfiguration( |
| (...skipping 10 matching lines...) Expand all Loading... |
| 607 | 629 |
| 608 ObjectInitializationConfiguration( | 630 ObjectInitializationConfiguration( |
| 609 this.constructor, this.environment, this.configuration); | 631 this.constructor, this.environment, this.configuration); |
| 610 | 632 |
| 611 Configuration step(StatementExecuter _) { | 633 Configuration step(StatementExecuter _) { |
| 612 if (constructor.initializers.isNotEmpty && | 634 if (constructor.initializers.isNotEmpty && |
| 613 constructor.initializers.last is RedirectingInitializer) { | 635 constructor.initializers.last is RedirectingInitializer) { |
| 614 // Constructor is redirecting. | 636 // Constructor is redirecting. |
| 615 Initializer initializer = constructor.initializers.first; | 637 Initializer initializer = constructor.initializers.first; |
| 616 if (initializer is RedirectingInitializer) { | 638 if (initializer is RedirectingInitializer) { |
| 617 var app = new RedirectingConstructorApplication( | 639 var app = new RedirectingConstructorA( |
| 618 initializer.target, environment, configuration); | 640 initializer.target, environment, configuration); |
| 619 var args = _createArgumentExpressionList( | 641 var args = _createArgumentExpressionList( |
| 620 initializer.arguments, initializer.target.function); | 642 initializer.arguments, initializer.target.function); |
| 621 | 643 |
| 622 return new EvalListConfiguration(args, environment, app); | 644 return new EvalListConfiguration(args, environment, app); |
| 623 } | 645 } |
| 624 // Redirecting initializer is not the only initializer. | 646 // Redirecting initializer is not the only initializer. |
| 625 for (Initializer i in constructor.initializers.reversed.skip(1)) { | 647 for (Initializer i in constructor.initializers.reversed.skip(1)) { |
| 626 assert(i is LocalInitializer); | 648 assert(i is LocalInitializer); |
| 627 } | 649 } |
| 628 var class_ = new Class(constructor.enclosingClass.reference); | 650 var class_ = new Class(constructor.enclosingClass.reference); |
| 629 var initEnv = new Environment(environment); | 651 var initEnv = new Environment(environment); |
| 630 var cont = new InitializerContinuation( | 652 var cont = new InitializerEK( |
| 631 class_, initEnv, constructor.initializers, configuration); | 653 class_, initEnv, constructor.initializers, configuration); |
| 632 return new EvalConfiguration( | 654 return new EvalConfiguration( |
| 633 (initializer as LocalInitializer).variable.initializer, | 655 (initializer as LocalInitializer).variable.initializer, |
| 634 initEnv, | 656 initEnv, |
| 635 cont); | 657 cont); |
| 636 } | 658 } |
| 637 | 659 |
| 638 // Set head of configurations to be executed to configuration for current | 660 // Set head of configurations to be executed to configuration for current |
| 639 // constructor body. | 661 // constructor body. |
| 640 var state = new State.initial() | 662 var state = new State.initial() |
| 641 .withEnvironment(environment) | 663 .withEnvironment(environment) |
| 642 .withConfiguration(configuration); | 664 .withConfiguration(configuration); |
| 643 var bodyConfig = new ExecConfiguration(constructor.function.body, state); | 665 var bodyConfig = new ExecConfiguration(constructor.function.body, state); |
| 644 | 666 |
| 645 // Initialize fields in immediately enclosing class. | 667 // Initialize fields in immediately enclosing class. |
| 646 var cont = | 668 var cont = new InstanceFieldsA(constructor, environment, bodyConfig); |
| 647 new InstanceFieldsApplication(constructor, environment, bodyConfig); | |
| 648 var fieldExpressions = _createInstanceInitializers(constructor); | 669 var fieldExpressions = _createInstanceInitializers(constructor); |
| 649 | 670 |
| 650 return new EvalListConfiguration( | 671 return new EvalListConfiguration( |
| 651 fieldExpressions, new Environment.empty(), cont); | 672 fieldExpressions, new Environment.empty(), cont); |
| 652 } | 673 } |
| 653 | 674 |
| 654 /// Creates a list of expressions for instance field initializers in | 675 /// Creates a list of expressions for instance field initializers in |
| 655 /// immediately enclosing class. | 676 /// immediately enclosing class. |
| 656 static List<InterpreterExpression> _createInstanceInitializers( | 677 static List<InterpreterExpression> _createInstanceInitializers( |
| 657 Constructor ctr) { | 678 Constructor ctr) { |
| 658 Class currentClass = new Class(ctr.enclosingClass.reference); | 679 Class currentClass = new Class(ctr.enclosingClass.reference); |
| 659 List<InterpreterExpression> es = <InterpreterExpression>[]; | 680 List<InterpreterExpression> es = <InterpreterExpression>[]; |
| 660 | 681 |
| 661 for (int i = currentClass.superclass?.instanceSize ?? 0; | 682 for (int i = currentClass.superclass?.instanceSize ?? 0; |
| 662 i < currentClass.instanceSize; | 683 i < currentClass.instanceSize; |
| 663 i++) { | 684 i++) { |
| 664 Field current = currentClass.instanceFields[i]; | 685 Field current = currentClass.instanceFields[i]; |
| 665 if (current.initializer != null) { | 686 if (current.initializer != null) { |
| 666 es.add(new FieldInitializerExpression(current, current.initializer)); | 687 es.add(new FieldInitializerExpression(current, current.initializer)); |
| 667 } | 688 } |
| 668 } | 689 } |
| 669 | 690 |
| 670 return es; | 691 return es; |
| 671 } | 692 } |
| 672 } | 693 } |
| 673 | 694 |
| 674 /// Represents the application continuation applied on the list of evaluated | 695 /// Represents the application continuation applied on the list of evaluated |
| 675 /// field initializer expressions. | 696 /// field initializer expressions. |
| 676 class InstanceFieldsApplication extends ApplicationContinuation { | 697 class InstanceFieldsA extends ApplicationContinuation { |
| 677 final Constructor constructor; | 698 final Constructor constructor; |
| 678 final Environment environment; | 699 final Environment environment; |
| 679 final ExecConfiguration configuration; | 700 final ExecConfiguration configuration; |
| 680 | 701 |
| 681 final Class _currentClass; | 702 final Class _currentClass; |
| 682 final ObjectValue _newObject; | 703 final ObjectValue _newObject; |
| 683 | 704 |
| 684 InstanceFieldsApplication( | 705 InstanceFieldsA(this.constructor, this.environment, this.configuration) |
| 685 this.constructor, this.environment, this.configuration) | |
| 686 : _currentClass = new Class(constructor.enclosingClass.reference), | 706 : _currentClass = new Class(constructor.enclosingClass.reference), |
| 687 _newObject = environment.thisInstance; | 707 _newObject = environment.thisInstance; |
| 688 | 708 |
| 689 Configuration call(List<InterpreterValue> fieldValues) { | 709 Configuration call(List<InterpreterValue> fieldValues) { |
| 690 for (FieldInitializerValue current in fieldValues.reversed) { | 710 for (FieldInitializerValue current in fieldValues.reversed) { |
| 691 _currentClass.setProperty(_newObject, current.field, current.value); | 711 _currentClass.setProperty(_newObject, current.field, current.value); |
| 692 } | 712 } |
| 693 | 713 |
| 694 if (constructor.initializers.isEmpty) { | 714 if (constructor.initializers.isEmpty) { |
| 695 _initializeNullFields(_currentClass, _newObject); | 715 _initializeNullFields(_currentClass, _newObject); |
| 696 return configuration; | 716 return configuration; |
| 697 } | 717 } |
| 698 | 718 |
| 699 // Produce next configuration. | 719 // Produce next configuration. |
| 700 if (constructor.initializers.first is SuperInitializer) { | 720 if (constructor.initializers.first is SuperInitializer) { |
| 701 // SuperInitializer appears last in the initializer list. | 721 // SuperInitializer appears last in the initializer list. |
| 702 assert(constructor.initializers.length == 1); | 722 assert(constructor.initializers.length == 1); |
| 703 SuperInitializer current = constructor.initializers.first; | 723 SuperInitializer current = constructor.initializers.first; |
| 704 var args = _createArgumentExpressionList( | 724 var args = _createArgumentExpressionList( |
| 705 current.arguments, current.target.function); | 725 current.arguments, current.target.function); |
| 706 | 726 |
| 707 var superApp = new SuperConstructorApplication( | 727 var superApp = |
| 708 current.target, environment, configuration); | 728 new SuperConstructorA(current.target, environment, configuration); |
| 709 _initializeNullFields(_currentClass, _newObject); | 729 _initializeNullFields(_currentClass, _newObject); |
| 710 return new EvalListConfiguration(args, environment, superApp); | 730 return new EvalListConfiguration(args, environment, superApp); |
| 711 } | 731 } |
| 712 | 732 |
| 713 Class class_ = new Class(constructor.enclosingClass.reference); | 733 Class class_ = new Class(constructor.enclosingClass.reference); |
| 714 Environment initEnv = new Environment(environment); | 734 Environment initEnv = new Environment(environment); |
| 715 | 735 |
| 716 var cont = new InitializerContinuation( | 736 var cont = new InitializerEK( |
| 717 class_, initEnv, constructor.initializers, configuration); | 737 class_, initEnv, constructor.initializers, configuration); |
| 718 return new EvalConfiguration( | 738 return new EvalConfiguration( |
| 719 _getExpression(constructor.initializers.first), initEnv, cont); | 739 _getExpression(constructor.initializers.first), initEnv, cont); |
| 720 } | 740 } |
| 721 } | 741 } |
| 722 | 742 |
| 723 /// Represents the expression continuation applied on the list of evaluated | 743 /// Represents the expression continuation applied on the list of evaluated |
| 724 /// initializer expressions preceding a super call in the list. | 744 /// initializer expressions preceding a super call in the list. |
| 725 class InitializerContinuation extends ExpressionContinuation { | 745 class InitializerEK extends ExpressionContinuation { |
| 726 final Class currentClass; | 746 final Class currentClass; |
| 727 final Environment initializerEnvironment; | 747 final Environment initializerEnvironment; |
| 728 final List<Initializer> initializers; | 748 final List<Initializer> initializers; |
| 729 final ExecConfiguration configuration; | 749 final ExecConfiguration configuration; |
| 730 | 750 |
| 731 InitializerContinuation(this.currentClass, this.initializerEnvironment, | 751 InitializerEK(this.currentClass, this.initializerEnvironment, |
| 732 this.initializers, this.configuration); | 752 this.initializers, this.configuration); |
| 733 | 753 |
| 734 Configuration call(Value v) { | 754 Configuration call(Value v) { |
| 735 ObjectValue newObject = initializerEnvironment.thisInstance; | 755 ObjectValue newObject = initializerEnvironment.thisInstance; |
| 736 Initializer current = initializers.first; | 756 Initializer current = initializers.first; |
| 737 if (current is FieldInitializer) { | 757 if (current is FieldInitializer) { |
| 738 currentClass.setProperty(newObject, current.field, v); | 758 currentClass.setProperty(newObject, current.field, v); |
| 739 } else if (current is LocalInitializer) { | 759 } else if (current is LocalInitializer) { |
| 740 initializerEnvironment.expand(current.variable, v); | 760 initializerEnvironment.expand(current.variable, v); |
| 741 } else { | 761 } else { |
| 742 throw 'Assigning value $v to ${current.runtimeType}'; | 762 throw 'Assigning value $v to ${current.runtimeType}'; |
| 743 } | 763 } |
| 744 | 764 |
| 745 if (initializers.length <= 1) { | 765 if (initializers.length <= 1) { |
| 746 _initializeNullFields(currentClass, newObject); | 766 _initializeNullFields(currentClass, newObject); |
| 747 return configuration; | 767 return configuration; |
| 748 } | 768 } |
| 749 | 769 |
| 750 Initializer next = initializers[1]; | 770 Initializer next = initializers[1]; |
| 751 | 771 |
| 752 if (next is RedirectingInitializer) { | 772 if (next is RedirectingInitializer) { |
| 753 // RedirectingInitializer appears last in the initializer list. | 773 // RedirectingInitializer appears last in the initializer list. |
| 754 assert(initializers.length == 2); | 774 assert(initializers.length == 2); |
| 755 var app = new RedirectingConstructorApplication( | 775 var app = new RedirectingConstructorA( |
| 756 next.target, initializerEnvironment, configuration); | 776 next.target, initializerEnvironment, configuration); |
| 757 var args = | 777 var args = |
| 758 _createArgumentExpressionList(next.arguments, next.target.function); | 778 _createArgumentExpressionList(next.arguments, next.target.function); |
| 759 return new EvalListConfiguration(args, initializerEnvironment, app); | 779 return new EvalListConfiguration(args, initializerEnvironment, app); |
| 760 } | 780 } |
| 761 | 781 |
| 762 if (next is SuperInitializer) { | 782 if (next is SuperInitializer) { |
| 763 // SuperInitializer appears last in the initializer list. | 783 // SuperInitializer appears last in the initializer list. |
| 764 assert(initializers.length == 2); | 784 assert(initializers.length == 2); |
| 765 var args = | 785 var args = |
| 766 _createArgumentExpressionList(next.arguments, next.target.function); | 786 _createArgumentExpressionList(next.arguments, next.target.function); |
| 767 var superApp = new SuperConstructorApplication( | 787 var superApp = new SuperConstructorA( |
| 768 next.target, initializerEnvironment, configuration); | 788 next.target, initializerEnvironment, configuration); |
| 769 _initializeNullFields(currentClass, newObject); | 789 _initializeNullFields(currentClass, newObject); |
| 770 return new EvalListConfiguration(args, initializerEnvironment, superApp); | 790 return new EvalListConfiguration(args, initializerEnvironment, superApp); |
| 771 } | 791 } |
| 772 | 792 |
| 773 var cont = new InitializerContinuation(currentClass, initializerEnvironment, | 793 var cont = new InitializerEK(currentClass, initializerEnvironment, |
| 774 initializers.skip(1).toList(), configuration); | 794 initializers.skip(1).toList(), configuration); |
| 775 return new EvalConfiguration( | 795 return new EvalConfiguration( |
| 776 _getExpression(next), initializerEnvironment, cont); | 796 _getExpression(next), initializerEnvironment, cont); |
| 777 } | 797 } |
| 778 } | 798 } |
| 779 | 799 |
| 780 /// Represents the application continuation called after the evaluation of all | 800 /// Represents the application continuation called after the evaluation of all |
| 781 /// argument expressions for an invocation. | 801 /// argument expressions for an invocation. |
| 782 class ValueApplication extends ApplicationContinuation { | 802 class ValueA extends ApplicationContinuation { |
| 783 final InterpreterValue value; | 803 final InterpreterValue value; |
| 784 final ApplicationContinuation applicationContinuation; | 804 final ApplicationContinuation applicationContinuation; |
| 785 | 805 |
| 786 ValueApplication(this.value, this.applicationContinuation); | 806 ValueA(this.value, this.applicationContinuation); |
| 787 | 807 |
| 788 Configuration call(List<InterpreterValue> args) { | 808 Configuration call(List<InterpreterValue> args) { |
| 789 args.add(value); | 809 args.add(value); |
| 790 return new ApplicationConfiguration(applicationContinuation, args); | 810 return new ApplicationConfiguration(applicationContinuation, args); |
| 791 } | 811 } |
| 792 } | 812 } |
| 793 | 813 |
| 814 // ------------------------------------------------------------------------ |
| 815 // Expression Continuations |
| 816 // ------------------------------------------------------------------------ |
| 794 /// Represents an expression continuation. | 817 /// Represents an expression continuation. |
| 818 /// |
| 819 /// There are various kinds of [ExpressionContinuation]s and their names are |
| 820 /// suffixed with "EK". |
| 795 abstract class ExpressionContinuation extends Continuation { | 821 abstract class ExpressionContinuation extends Continuation { |
| 796 Configuration call(Value v); | 822 Configuration call(Value v); |
| 797 } | 823 } |
| 798 | 824 |
| 799 /// Represents a continuation that returns the next [ExecConfiguration] | 825 /// Represents a continuation that returns the next [ExecConfiguration] |
| 800 /// to be executed. | 826 /// to be executed. |
| 801 class ExpressionStatementContinuation extends ExpressionContinuation { | 827 class ExpressionEK extends ExpressionContinuation { |
| 802 final ExecConfiguration configuration; | 828 final ExecConfiguration configuration; |
| 803 | 829 |
| 804 ExpressionStatementContinuation(this.configuration); | 830 ExpressionEK(this.configuration); |
| 805 | 831 |
| 806 Configuration call(Value _) { | 832 Configuration call(Value _) { |
| 807 return configuration; | 833 return configuration; |
| 808 } | 834 } |
| 809 } | 835 } |
| 810 | 836 |
| 811 class PrintContinuation extends ExpressionContinuation { | 837 class PrintEK extends ExpressionContinuation { |
| 812 final ExpressionContinuation continuation; | 838 final ExpressionContinuation continuation; |
| 813 | 839 |
| 814 PrintContinuation(this.continuation); | 840 PrintEK(this.continuation); |
| 815 | 841 |
| 816 Configuration call(Value v) { | 842 Configuration call(Value v) { |
| 817 log.info('print(${v.value.runtimeType}: ${v.value})\n'); | 843 log.info('print(${v.value.runtimeType}: ${v.value})\n'); |
| 818 print(v.value); | 844 print(v.value); |
| 819 return new ValuePassingConfiguration(continuation, Value.nullInstance); | 845 return new ValuePassingConfiguration(continuation, Value.nullInstance); |
| 820 } | 846 } |
| 821 } | 847 } |
| 822 | 848 |
| 823 class PropertyGetContinuation extends ExpressionContinuation { | 849 class PropertyGetEK extends ExpressionContinuation { |
| 824 final Name name; | 850 final Name name; |
| 825 final ExpressionContinuation continuation; | 851 final ExpressionContinuation continuation; |
| 826 | 852 |
| 827 PropertyGetContinuation(this.name, this.continuation); | 853 PropertyGetEK(this.name, this.continuation); |
| 828 | 854 |
| 829 Configuration call(Value receiver) { | 855 Configuration call(Value receiver) { |
| 830 // TODO: CPS the invocation of the getter. | 856 // TODO: CPS the invocation of the getter. |
| 831 Value propertyValue = receiver.class_.lookupGetter(name)(receiver); | 857 Value propertyValue = receiver.class_.lookupGetter(name)(receiver); |
| 832 return new ValuePassingConfiguration(continuation, propertyValue); | 858 return new ValuePassingConfiguration(continuation, propertyValue); |
| 833 } | 859 } |
| 834 } | 860 } |
| 835 | 861 |
| 836 class PropertySetContinuation extends ExpressionContinuation { | 862 class PropertySetEK extends ExpressionContinuation { |
| 837 final Expression value; | 863 final Expression value; |
| 838 final Name setterName; | 864 final Name setterName; |
| 839 final Environment environment; | 865 final Environment environment; |
| 840 final ExpressionContinuation continuation; | 866 final ExpressionContinuation continuation; |
| 841 | 867 |
| 842 PropertySetContinuation( | 868 PropertySetEK( |
| 843 this.value, this.setterName, this.environment, this.continuation); | 869 this.value, this.setterName, this.environment, this.continuation); |
| 844 | 870 |
| 845 Configuration call(Value receiver) { | 871 Configuration call(Value receiver) { |
| 846 var cont = new SetterContinuation(receiver, setterName, continuation); | 872 var cont = new SetterEK(receiver, setterName, continuation); |
| 847 return new EvalConfiguration(value, environment, cont); | 873 return new EvalConfiguration(value, environment, cont); |
| 848 } | 874 } |
| 849 } | 875 } |
| 850 | 876 |
| 851 class SetterContinuation extends ExpressionContinuation { | 877 class SetterEK extends ExpressionContinuation { |
| 852 final Value receiver; | 878 final Value receiver; |
| 853 final Name name; | 879 final Name name; |
| 854 final ExpressionContinuation continuation; | 880 final ExpressionContinuation continuation; |
| 855 | 881 |
| 856 SetterContinuation(this.receiver, this.name, this.continuation); | 882 SetterEK(this.receiver, this.name, this.continuation); |
| 857 | 883 |
| 858 Configuration call(Value v) { | 884 Configuration call(Value v) { |
| 859 Setter setter = receiver.class_.lookupSetter(name); | 885 Setter setter = receiver.class_.lookupSetter(name); |
| 860 setter(receiver, v); | 886 setter(receiver, v); |
| 861 return new ValuePassingConfiguration(continuation, v); | 887 return new ValuePassingConfiguration(continuation, v); |
| 862 } | 888 } |
| 863 } | 889 } |
| 864 | 890 |
| 865 /// Represents a continuation to be called after the evaluation of an actual | 891 /// Represents a continuation to be called after the evaluation of an actual |
| 866 /// argument for function invocation. | 892 /// argument for function invocation. |
| 867 class ExpressionListContinuation extends ExpressionContinuation { | 893 class ExpressionListEK extends ExpressionContinuation { |
| 868 final InterpreterExpression currentExpression; | 894 final InterpreterExpression currentExpression; |
| 869 final List<InterpreterExpression> expressions; | 895 final List<InterpreterExpression> expressions; |
| 870 final Environment environment; | 896 final Environment environment; |
| 871 final ApplicationContinuation applicationContinuation; | 897 final ApplicationContinuation applicationContinuation; |
| 872 | 898 |
| 873 ExpressionListContinuation(this.currentExpression, this.expressions, | 899 ExpressionListEK(this.currentExpression, this.expressions, this.environment, |
| 874 this.environment, this.applicationContinuation); | 900 this.applicationContinuation); |
| 875 | 901 |
| 876 Configuration call(Value v) { | 902 Configuration call(Value v) { |
| 877 ValueApplication app = new ValueApplication( | 903 ValueA app = |
| 878 currentExpression.assignValue(v), applicationContinuation); | 904 new ValueA(currentExpression.assignValue(v), applicationContinuation); |
| 879 return new EvalListConfiguration(expressions, environment, app); | 905 return new EvalListConfiguration(expressions, environment, app); |
| 880 } | 906 } |
| 881 } | 907 } |
| 882 | 908 |
| 883 class MethodInvocationContinuation extends ExpressionContinuation { | 909 class MethodInvocationEK extends ExpressionContinuation { |
| 884 final Arguments arguments; | 910 final Arguments arguments; |
| 885 final Name methodName; | 911 final Name methodName; |
| 886 final Environment environment; | 912 final Environment environment; |
| 887 final ExpressionContinuation continuation; | 913 final ExpressionContinuation continuation; |
| 888 | 914 |
| 889 MethodInvocationContinuation( | 915 MethodInvocationEK( |
| 890 this.arguments, this.methodName, this.environment, this.continuation); | 916 this.arguments, this.methodName, this.environment, this.continuation); |
| 891 | 917 |
| 892 Configuration call(Value receiver) { | 918 Configuration call(Value receiver) { |
| 893 if (arguments.positional.isEmpty) { | 919 if (arguments.positional.isEmpty) { |
| 894 Value returnValue = receiver.invokeMethod(methodName); | 920 Value returnValue = receiver.invokeMethod(methodName); |
| 895 return new ValuePassingConfiguration(continuation, returnValue); | 921 return new ValuePassingConfiguration(continuation, returnValue); |
| 896 } | 922 } |
| 897 var cont = new ArgumentsContinuation( | 923 var cont = new ArgumentsEK( |
| 898 receiver, methodName, arguments, environment, continuation); | 924 receiver, methodName, arguments, environment, continuation); |
| 899 | 925 |
| 900 return new EvalConfiguration(arguments.positional.first, environment, cont); | 926 return new EvalConfiguration(arguments.positional.first, environment, cont); |
| 901 } | 927 } |
| 902 } | 928 } |
| 903 | 929 |
| 904 class ArgumentsContinuation extends ExpressionContinuation { | 930 class ArgumentsEK extends ExpressionContinuation { |
| 905 final Value receiver; | 931 final Value receiver; |
| 906 final Name methodName; | 932 final Name methodName; |
| 907 final Arguments arguments; | 933 final Arguments arguments; |
| 908 final Environment environment; | 934 final Environment environment; |
| 909 final ExpressionContinuation continuation; | 935 final ExpressionContinuation continuation; |
| 910 | 936 |
| 911 ArgumentsContinuation(this.receiver, this.methodName, this.arguments, | 937 ArgumentsEK(this.receiver, this.methodName, this.arguments, this.environment, |
| 912 this.environment, this.continuation); | 938 this.continuation); |
| 913 | 939 |
| 914 Configuration call(Value value) { | 940 Configuration call(Value value) { |
| 915 // Currently evaluates only one argument, for simple method invocations | 941 // Currently evaluates only one argument, for simple method invocations |
| 916 // with 1 argument. | 942 // with 1 argument. |
| 917 Value returnValue = receiver.invokeMethod(methodName, value); | 943 Value returnValue = receiver.invokeMethod(methodName, value); |
| 918 return new ValuePassingConfiguration(continuation, returnValue); | 944 return new ValuePassingConfiguration(continuation, returnValue); |
| 919 } | 945 } |
| 920 } | 946 } |
| 921 | 947 |
| 922 class VariableSetContinuation extends ExpressionContinuation { | 948 class VariableSetEK extends ExpressionContinuation { |
| 923 final VariableDeclaration variable; | 949 final VariableDeclaration variable; |
| 924 final Environment environment; | 950 final Environment environment; |
| 925 final ExpressionContinuation continuation; | 951 final ExpressionContinuation continuation; |
| 926 | 952 |
| 927 VariableSetContinuation(this.variable, this.environment, this.continuation); | 953 VariableSetEK(this.variable, this.environment, this.continuation); |
| 928 | 954 |
| 929 Configuration call(Value value) { | 955 Configuration call(Value value) { |
| 930 environment.assign(variable, value); | 956 environment.assign(variable, value); |
| 931 return new ValuePassingConfiguration(continuation, value); | 957 return new ValuePassingConfiguration(continuation, value); |
| 932 } | 958 } |
| 933 } | 959 } |
| 934 | 960 |
| 935 class NotContinuation extends ExpressionContinuation { | 961 class NotEK extends ExpressionContinuation { |
| 936 final ExpressionContinuation continuation; | 962 final ExpressionContinuation continuation; |
| 937 | 963 |
| 938 NotContinuation(this.continuation); | 964 NotEK(this.continuation); |
| 939 | 965 |
| 940 Configuration call(Value value) { | 966 Configuration call(Value value) { |
| 941 Value notValue = identical(Value.trueInstance, value) | 967 Value notValue = identical(Value.trueInstance, value) |
| 942 ? Value.falseInstance | 968 ? Value.falseInstance |
| 943 : Value.trueInstance; | 969 : Value.trueInstance; |
| 944 return new ValuePassingConfiguration(continuation, notValue); | 970 return new ValuePassingConfiguration(continuation, notValue); |
| 945 } | 971 } |
| 946 } | 972 } |
| 947 | 973 |
| 948 class OrContinuation extends ExpressionContinuation { | 974 class OrEK extends ExpressionContinuation { |
| 949 final Expression right; | 975 final Expression right; |
| 950 final Environment environment; | 976 final Environment environment; |
| 951 final ExpressionContinuation continuation; | 977 final ExpressionContinuation continuation; |
| 952 | 978 |
| 953 OrContinuation(this.right, this.environment, this.continuation); | 979 OrEK(this.right, this.environment, this.continuation); |
| 954 | 980 |
| 955 Configuration call(Value left) { | 981 Configuration call(Value left) { |
| 956 return identical(Value.trueInstance, left) | 982 return identical(Value.trueInstance, left) |
| 957 ? new ValuePassingConfiguration(continuation, Value.trueInstance) | 983 ? new ValuePassingConfiguration(continuation, Value.trueInstance) |
| 958 : new EvalConfiguration(right, environment, continuation); | 984 : new EvalConfiguration(right, environment, continuation); |
| 959 } | 985 } |
| 960 } | 986 } |
| 961 | 987 |
| 962 class AndContinuation extends ExpressionContinuation { | 988 class AndEK extends ExpressionContinuation { |
| 963 final Expression right; | 989 final Expression right; |
| 964 final Environment environment; | 990 final Environment environment; |
| 965 final ExpressionContinuation continuation; | 991 final ExpressionContinuation continuation; |
| 966 | 992 |
| 967 AndContinuation(this.right, this.environment, this.continuation); | 993 AndEK(this.right, this.environment, this.continuation); |
| 968 | 994 |
| 969 Configuration call(Value left) { | 995 Configuration call(Value left) { |
| 970 return identical(Value.falseInstance, left) | 996 return identical(Value.falseInstance, left) |
| 971 ? new ValuePassingConfiguration(continuation, Value.falseInstance) | 997 ? new ValuePassingConfiguration(continuation, Value.falseInstance) |
| 972 : new EvalConfiguration(right, environment, continuation); | 998 : new EvalConfiguration(right, environment, continuation); |
| 973 } | 999 } |
| 974 } | 1000 } |
| 975 | 1001 |
| 976 class ConditionalContinuation extends ExpressionContinuation { | 1002 class ConditionalEK extends ExpressionContinuation { |
| 977 final Expression then; | 1003 final Expression then; |
| 978 final Expression otherwise; | 1004 final Expression otherwise; |
| 979 final Environment environment; | 1005 final Environment environment; |
| 980 final ExpressionContinuation continuation; | 1006 final ExpressionContinuation continuation; |
| 981 | 1007 |
| 982 ConditionalContinuation( | 1008 ConditionalEK(this.then, this.otherwise, this.environment, this.continuation); |
| 983 this.then, this.otherwise, this.environment, this.continuation); | |
| 984 | 1009 |
| 985 Configuration call(Value value) { | 1010 Configuration call(Value value) { |
| 986 return identical(Value.trueInstance, value) | 1011 return identical(Value.trueInstance, value) |
| 987 ? new EvalConfiguration(then, environment, continuation) | 1012 ? new EvalConfiguration(then, environment, continuation) |
| 988 : new EvalConfiguration(otherwise, environment, continuation); | 1013 : new EvalConfiguration(otherwise, environment, continuation); |
| 989 } | 1014 } |
| 990 } | 1015 } |
| 991 | 1016 |
| 992 class StringConcatenationContinuation extends ApplicationContinuation { | 1017 class LetEK extends ExpressionContinuation { |
| 993 final ExpressionContinuation continuation; | |
| 994 | |
| 995 StringConcatenationContinuation(this.continuation); | |
| 996 | |
| 997 Configuration call(List<InterpreterValue> values) { | |
| 998 StringBuffer result = new StringBuffer(); | |
| 999 for (InterpreterValue v in values.reversed) { | |
| 1000 result.write(v.value.value); | |
| 1001 } | |
| 1002 return new ValuePassingConfiguration( | |
| 1003 continuation, new StringValue(result.toString())); | |
| 1004 } | |
| 1005 } | |
| 1006 | |
| 1007 class LetContinuation extends ExpressionContinuation { | |
| 1008 final VariableDeclaration variable; | 1018 final VariableDeclaration variable; |
| 1009 final Expression letBody; | 1019 final Expression letBody; |
| 1010 final Environment environment; | 1020 final Environment environment; |
| 1011 final ExpressionContinuation continuation; | 1021 final ExpressionContinuation continuation; |
| 1012 | 1022 |
| 1013 LetContinuation( | 1023 LetEK(this.variable, this.letBody, this.environment, this.continuation); |
| 1014 this.variable, this.letBody, this.environment, this.continuation); | |
| 1015 | 1024 |
| 1016 Configuration call(Value value) { | 1025 Configuration call(Value value) { |
| 1017 var letEnv = new Environment(environment); | 1026 var letEnv = new Environment(environment); |
| 1018 letEnv.expand(variable, value); | 1027 letEnv.expand(variable, value); |
| 1019 return new EvalConfiguration(letBody, letEnv, continuation); | 1028 return new EvalConfiguration(letBody, letEnv, continuation); |
| 1020 } | 1029 } |
| 1021 } | 1030 } |
| 1022 | 1031 |
| 1023 /// Represents the continuation for the condition expression in [WhileStatement]
. | 1032 /// Represents the continuation for the condition expression in [WhileStatement]
. |
| 1024 class WhileConditionContinuation extends ExpressionContinuation { | 1033 class WhileConditionEK extends ExpressionContinuation { |
| 1025 final WhileStatement node; | 1034 final WhileStatement node; |
| 1026 final State state; | 1035 final State state; |
| 1027 | 1036 |
| 1028 WhileConditionContinuation(this.node, this.state); | 1037 WhileConditionEK(this.node, this.state); |
| 1029 | 1038 |
| 1030 ExecConfiguration call(Value v) { | 1039 ExecConfiguration call(Value v) { |
| 1031 if (identical(v, Value.trueInstance)) { | 1040 if (identical(v, Value.trueInstance)) { |
| 1032 // Add configuration for the While statement to the linked list. | 1041 // Add configuration for the While statement to the linked list. |
| 1033 ExecConfiguration config = new ExecConfiguration(node, state); | 1042 ExecConfiguration config = new ExecConfiguration(node, state); |
| 1034 // Configuration for the body of the loop. | 1043 // Configuration for the body of the loop. |
| 1035 return new ExecConfiguration(node.body, state.withConfiguration(config)); | 1044 return new ExecConfiguration(node.body, state.withConfiguration(config)); |
| 1036 } | 1045 } |
| 1037 | 1046 |
| 1038 return state.statementConfiguration; | 1047 return state.statementConfiguration; |
| 1039 } | 1048 } |
| 1040 } | 1049 } |
| 1041 | 1050 |
| 1042 /// Represents the continuation for the condition expression in [IfStatement]. | 1051 /// Represents the continuation for the condition expression in [IfStatement]. |
| 1043 class IfConditionContinuation extends ExpressionContinuation { | 1052 class IfConditionEK extends ExpressionContinuation { |
| 1044 final Statement then; | 1053 final Statement then; |
| 1045 final Statement otherwise; | 1054 final Statement otherwise; |
| 1046 final State state; | 1055 final State state; |
| 1047 | 1056 |
| 1048 IfConditionContinuation(this.then, this.otherwise, this.state); | 1057 IfConditionEK(this.then, this.otherwise, this.state); |
| 1049 | 1058 |
| 1050 ExecConfiguration call(Value v) { | 1059 ExecConfiguration call(Value v) { |
| 1051 if (identical(v, Value.trueInstance)) { | 1060 if (identical(v, Value.trueInstance)) { |
| 1052 log.info("if-then\n"); | 1061 log.info("if-then\n"); |
| 1053 return new ExecConfiguration(then, state); | 1062 return new ExecConfiguration(then, state); |
| 1054 } else if (otherwise != null) { | 1063 } else if (otherwise != null) { |
| 1055 log.info("if-otherwise\n"); | 1064 log.info("if-otherwise\n"); |
| 1056 return new ExecConfiguration(otherwise, state); | 1065 return new ExecConfiguration(otherwise, state); |
| 1057 } | 1066 } |
| 1058 return state.statementConfiguration; | 1067 return state.statementConfiguration; |
| 1059 } | 1068 } |
| 1060 } | 1069 } |
| 1061 | 1070 |
| 1062 /// Represents the continuation for the initializer expression in | 1071 /// Represents the continuation for the initializer expression in |
| 1063 /// [VariableDeclaration]. | 1072 /// [VariableDeclaration]. |
| 1064 class VariableInitializerContinuation extends ExpressionContinuation { | 1073 class VariableInitializerEK extends ExpressionContinuation { |
| 1065 final VariableDeclaration variable; | 1074 final VariableDeclaration variable; |
| 1066 final Environment environment; | 1075 final Environment environment; |
| 1067 final ExecConfiguration nextConfiguration; | 1076 final ExecConfiguration nextConfiguration; |
| 1068 | 1077 |
| 1069 VariableInitializerContinuation( | 1078 VariableInitializerEK( |
| 1070 this.variable, this.environment, this.nextConfiguration); | 1079 this.variable, this.environment, this.nextConfiguration); |
| 1071 | 1080 |
| 1072 ExecConfiguration call(Value v) { | 1081 ExecConfiguration call(Value v) { |
| 1073 environment.expand(variable, v); | 1082 environment.expand(variable, v); |
| 1074 return nextConfiguration; | 1083 return nextConfiguration; |
| 1075 } | 1084 } |
| 1076 } | 1085 } |
| 1077 | 1086 |
| 1078 /// Executes statements. | 1087 /// Executes statements. |
| 1079 /// | 1088 /// |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1105 throw notImplemented( | 1114 throw notImplemented( |
| 1106 m: "Execution is not implemented for statement:\n$node "); | 1115 m: "Execution is not implemented for statement:\n$node "); |
| 1107 } | 1116 } |
| 1108 | 1117 |
| 1109 Configuration visitInvalidStatement(InvalidStatement node, State state) { | 1118 Configuration visitInvalidStatement(InvalidStatement node, State state) { |
| 1110 throw "Invalid statement at ${node.location}"; | 1119 throw "Invalid statement at ${node.location}"; |
| 1111 } | 1120 } |
| 1112 | 1121 |
| 1113 Configuration visitExpressionStatement( | 1122 Configuration visitExpressionStatement( |
| 1114 ExpressionStatement node, State state) { | 1123 ExpressionStatement node, State state) { |
| 1115 var cont = | 1124 var cont = new ExpressionEK(state.statementConfiguration); |
| 1116 new ExpressionStatementContinuation(state.statementConfiguration); | |
| 1117 return new EvalConfiguration(node.expression, state.environment, cont); | 1125 return new EvalConfiguration(node.expression, state.environment, cont); |
| 1118 } | 1126 } |
| 1119 | 1127 |
| 1120 Configuration visitBlock(Block node, State state) { | 1128 Configuration visitBlock(Block node, State state) { |
| 1121 if (node.statements.isEmpty) { | 1129 if (node.statements.isEmpty) { |
| 1122 return state.statementConfiguration; | 1130 return state.statementConfiguration; |
| 1123 } | 1131 } |
| 1124 State blockState = | 1132 State blockState = |
| 1125 state.withEnvironment(new Environment(state.environment)); | 1133 state.withEnvironment(new Environment(state.environment)); |
| 1126 ExecConfiguration configuration = state.statementConfiguration; | 1134 ExecConfiguration configuration = state.statementConfiguration; |
| 1127 for (Statement s in node.statements.reversed) { | 1135 for (Statement s in node.statements.reversed) { |
| 1128 configuration = | 1136 configuration = |
| 1129 new ExecConfiguration(s, blockState.withConfiguration(configuration)); | 1137 new ExecConfiguration(s, blockState.withConfiguration(configuration)); |
| 1130 } | 1138 } |
| 1131 return configuration; | 1139 return configuration; |
| 1132 } | 1140 } |
| 1133 | 1141 |
| 1134 Configuration visitEmptyStatement(EmptyStatement node, State state) { | 1142 Configuration visitEmptyStatement(EmptyStatement node, State state) { |
| 1135 return state.statementConfiguration; | 1143 return state.statementConfiguration; |
| 1136 } | 1144 } |
| 1137 | 1145 |
| 1138 Configuration visitIfStatement(IfStatement node, State state) { | 1146 Configuration visitIfStatement(IfStatement node, State state) { |
| 1139 var cont = new IfConditionContinuation(node.then, node.otherwise, state); | 1147 var cont = new IfConditionEK(node.then, node.otherwise, state); |
| 1140 | 1148 |
| 1141 return new EvalConfiguration(node.condition, state.environment, cont); | 1149 return new EvalConfiguration(node.condition, state.environment, cont); |
| 1142 } | 1150 } |
| 1143 | 1151 |
| 1144 Configuration visitLabeledStatement(LabeledStatement node, State state) { | 1152 Configuration visitLabeledStatement(LabeledStatement node, State state) { |
| 1145 return new ExecConfiguration(node.body, state.withBreak(node)); | 1153 return new ExecConfiguration(node.body, state.withBreak(node)); |
| 1146 } | 1154 } |
| 1147 | 1155 |
| 1148 Configuration visitBreakStatement(BreakStatement node, State state) { | 1156 Configuration visitBreakStatement(BreakStatement node, State state) { |
| 1149 return state.lookupLabel(node.target).configuration; | 1157 return state.lookupLabel(node.target).configuration; |
| 1150 } | 1158 } |
| 1151 | 1159 |
| 1152 Configuration visitWhileStatement(WhileStatement node, State state) { | 1160 Configuration visitWhileStatement(WhileStatement node, State state) { |
| 1153 var cont = new WhileConditionContinuation(node, state); | 1161 var cont = new WhileConditionEK(node, state); |
| 1154 | 1162 |
| 1155 return new EvalConfiguration(node.condition, state.environment, cont); | 1163 return new EvalConfiguration(node.condition, state.environment, cont); |
| 1156 } | 1164 } |
| 1157 | 1165 |
| 1158 Configuration visitDoStatement(DoStatement node, State state) { | 1166 Configuration visitDoStatement(DoStatement node, State state) { |
| 1159 WhileStatement whileStatement = | 1167 WhileStatement whileStatement = |
| 1160 new WhileStatement(node.condition, node.body); | 1168 new WhileStatement(node.condition, node.body); |
| 1161 ExecConfiguration configuration = | 1169 ExecConfiguration configuration = |
| 1162 new ExecConfiguration(whileStatement, state); | 1170 new ExecConfiguration(whileStatement, state); |
| 1163 | 1171 |
| 1164 return new ExecConfiguration( | 1172 return new ExecConfiguration( |
| 1165 node.body, state.withConfiguration(configuration)); | 1173 node.body, state.withConfiguration(configuration)); |
| 1166 } | 1174 } |
| 1167 | 1175 |
| 1168 Configuration visitReturnStatement(ReturnStatement node, State state) { | 1176 Configuration visitReturnStatement(ReturnStatement node, State state) { |
| 1169 assert(state.returnContinuation != null); | 1177 assert(state.returnContinuation != null); |
| 1170 log.info('return\n'); | 1178 log.info('return\n'); |
| 1171 if (node.expression == null) { | 1179 if (node.expression == null) { |
| 1172 return new ValuePassingConfiguration( | 1180 return new ValuePassingConfiguration( |
| 1173 state.returnContinuation, Value.nullInstance); | 1181 state.returnContinuation, Value.nullInstance); |
| 1174 } | 1182 } |
| 1175 | 1183 |
| 1176 return new EvalConfiguration( | 1184 return new EvalConfiguration( |
| 1177 node.expression, state.environment, state.returnContinuation); | 1185 node.expression, state.environment, state.returnContinuation); |
| 1178 } | 1186 } |
| 1179 | 1187 |
| 1180 Configuration visitVariableDeclaration( | 1188 Configuration visitVariableDeclaration( |
| 1181 VariableDeclaration node, State state) { | 1189 VariableDeclaration node, State state) { |
| 1182 if (node.initializer != null) { | 1190 if (node.initializer != null) { |
| 1183 var cont = new VariableInitializerContinuation( | 1191 var cont = new VariableInitializerEK( |
| 1184 node, state.environment, state.statementConfiguration); | 1192 node, state.environment, state.statementConfiguration); |
| 1185 return new EvalConfiguration(node.initializer, state.environment, cont); | 1193 return new EvalConfiguration(node.initializer, state.environment, cont); |
| 1186 } | 1194 } |
| 1187 state.environment.expand(node, Value.nullInstance); | 1195 state.environment.expand(node, Value.nullInstance); |
| 1188 return state.statementConfiguration; | 1196 return state.statementConfiguration; |
| 1189 } | 1197 } |
| 1190 } | 1198 } |
| 1191 | 1199 |
| 1192 // ------------------------------------------------------------------------ | 1200 // ------------------------------------------------------------------------ |
| 1193 // VALUES | 1201 // VALUES |
| (...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1476 void _initializeNullFields(Class class_, ObjectValue newObject) { | 1484 void _initializeNullFields(Class class_, ObjectValue newObject) { |
| 1477 int superClassSize = class_.superclass?.instanceSize ?? 0; | 1485 int superClassSize = class_.superclass?.instanceSize ?? 0; |
| 1478 for (int i = superClassSize; i < class_.instanceSize; i++) { | 1486 for (int i = superClassSize; i < class_.instanceSize; i++) { |
| 1479 Field field = class_.instanceFields[i]; | 1487 Field field = class_.instanceFields[i]; |
| 1480 if (class_.getProperty(newObject, field) == null) { | 1488 if (class_.getProperty(newObject, field) == null) { |
| 1481 assert(field.initializer == null); | 1489 assert(field.initializer == null); |
| 1482 class_.setProperty(newObject, field, Value.nullInstance); | 1490 class_.setProperty(newObject, field, Value.nullInstance); |
| 1483 } | 1491 } |
| 1484 } | 1492 } |
| 1485 } | 1493 } |
| OLD | NEW |