| 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 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 79 bindings.add(new Binding(variable, value)); | 79 bindings.add(new Binding(variable, value)); |
| 80 } | 80 } |
| 81 } | 81 } |
| 82 | 82 |
| 83 /// Evaluate expressions. | 83 /// Evaluate expressions. |
| 84 class Evaluator | 84 class Evaluator |
| 85 extends ExpressionVisitor1<Configuration, ExpressionConfiguration> { | 85 extends ExpressionVisitor1<Configuration, ExpressionConfiguration> { |
| 86 Configuration eval(Expression expr, ExpressionConfiguration config) => | 86 Configuration eval(Expression expr, ExpressionConfiguration config) => |
| 87 expr.accept1(this, config); | 87 expr.accept1(this, config); |
| 88 | 88 |
| 89 Configuration evalArgs(List<ArgumentExpression> args, Environment env, | 89 Configuration evalList(List<InterpreterExpression> list, Environment env, |
| 90 ApplicationContinuation cont) { | 90 ApplicationContinuation cont) { |
| 91 if (args.isNotEmpty) { | 91 if (list.isNotEmpty) { |
| 92 return new ExpressionConfiguration(args.first.expression, env, | 92 return new ExpressionConfiguration(list.first.expression, env, |
| 93 new ActualArgumentsContinuation(args.first, args.skip(1), env, cont)); | 93 new ExpressionListContinuation(list.first, list.skip(1), env, cont)); |
| 94 } | 94 } |
| 95 return new ArgumentContinuationConfiguration(cont, <ArgumentValue>[]); | 95 return new ExpressionListContinuationConfiguration( |
| 96 cont, <InterpreterValue>[]); |
| 96 } | 97 } |
| 97 | 98 |
| 98 Configuration defaultExpression( | 99 Configuration defaultExpression( |
| 99 Expression node, ExpressionConfiguration config) { | 100 Expression node, ExpressionConfiguration config) { |
| 100 throw new NotImplemented('Evaluation for expressions of type ' | 101 throw new NotImplemented('Evaluation for expressions of type ' |
| 101 '${node.runtimeType} is not implemented.'); | 102 '${node.runtimeType} is not implemented.'); |
| 102 } | 103 } |
| 103 | 104 |
| 104 Configuration visitInvalidExpression1( | 105 Configuration visitInvalidExpression1( |
| 105 InvalidExpression node, ExpressionConfiguration config) { | 106 InvalidExpression node, ExpressionConfiguration config) { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 141 | 142 |
| 142 Configuration visitStaticInvocation( | 143 Configuration visitStaticInvocation( |
| 143 StaticInvocation node, ExpressionConfiguration config) { | 144 StaticInvocation node, ExpressionConfiguration config) { |
| 144 if ('print' == node.name.toString()) { | 145 if ('print' == node.name.toString()) { |
| 145 var cont = new PrintContinuation(config.continuation); | 146 var cont = new PrintContinuation(config.continuation); |
| 146 return new ExpressionConfiguration( | 147 return new ExpressionConfiguration( |
| 147 node.arguments.positional.first, config.environment, cont); | 148 node.arguments.positional.first, config.environment, cont); |
| 148 } else { | 149 } else { |
| 149 log.info('static-invocation-${node.target.name.toString()}\n'); | 150 log.info('static-invocation-${node.target.name.toString()}\n'); |
| 150 | 151 |
| 151 List<ArgumentExpression> args = | 152 List<InterpreterExpression> args = |
| 152 _createArgumentExpressionList(node.arguments, node.target.function); | 153 _createArgumentExpressionList(node.arguments, node.target.function); |
| 153 ApplicationContinuation cont = new StaticInvocationApplication( | 154 ApplicationContinuation cont = new StaticInvocationApplication( |
| 154 node.target.function, config.continuation); | 155 node.target.function, config.continuation); |
| 155 return new ArgumentsConfiguration(args, config.environment, cont); | 156 return new ExpressionListConfiguration(args, config.environment, cont); |
| 156 } | 157 } |
| 157 } | 158 } |
| 158 | 159 |
| 159 Configuration visitMethodInvocation( | 160 Configuration visitMethodInvocation( |
| 160 MethodInvocation node, ExpressionConfiguration config) { | 161 MethodInvocation node, ExpressionConfiguration config) { |
| 161 // Currently supports only method invocation with <2 arguments and is used | 162 // Currently supports only method invocation with <2 arguments and is used |
| 162 // to evaluate implemented operators for int, double and String values. | 163 // to evaluate implemented operators for int, double and String values. |
| 163 var cont = new MethodInvocationContinuation( | 164 var cont = new MethodInvocationContinuation( |
| 164 node.arguments, node.name, config.environment, config.continuation); | 165 node.arguments, node.name, config.environment, config.continuation); |
| 165 | 166 |
| 166 return new ExpressionConfiguration(node.receiver, config.environment, cont); | 167 return new ExpressionConfiguration(node.receiver, config.environment, cont); |
| 167 } | 168 } |
| 168 | 169 |
| 169 Configuration visitConstructorInvocation( | 170 Configuration visitConstructorInvocation( |
| 170 ConstructorInvocation node, ExpressionConfiguration config) { | 171 ConstructorInvocation node, ExpressionConfiguration config) { |
| 171 Class class_ = new Class(node.target.enclosingClass.reference); | 172 // Currently, the bodies of the constructors are not executed. |
| 173 // Currently initializer list is executed only for redirecting |
| 174 // constructors. |
| 175 if (node.target.function.body is! EmptyStatement) { |
| 176 throw 'Execution for body of constructor is not implemented.'; |
| 177 } |
| 172 | 178 |
| 173 // Currently we don't support initializers. | 179 var class_ = new Class(node.target.enclosingClass.reference); |
| 174 // TODO: Modify to respect dart semantics for initialization. | 180 var newObject = |
| 175 // 1. Init fields and eval initializers, repeat the same with super. | 181 new ObjectValue(class_, new List<Value>(class_.instanceSize)); |
| 176 // 2. Eval the Function body of the constructor. | 182 ApplicationContinuation cont = new ConstructorInvocationApplication( |
| 177 List<Value> fields = <Value>[]; | 183 newObject, node.target, config.continuation); |
| 178 | 184 |
| 179 return new ContinuationConfiguration( | 185 var args = |
| 180 config.continuation, new ObjectValue(class_, fields)); | 186 _createArgumentExpressionList(node.arguments, node.target.function); |
| 187 |
| 188 return new ExpressionListConfiguration(args, config.environment, cont); |
| 181 } | 189 } |
| 182 | 190 |
| 183 Configuration visitNot(Not node, ExpressionConfiguration config) { | 191 Configuration visitNot(Not node, ExpressionConfiguration config) { |
| 184 return new ExpressionConfiguration(node.operand, config.environment, | 192 return new ExpressionConfiguration(node.operand, config.environment, |
| 185 new NotContinuation(config.continuation)); | 193 new NotContinuation(config.continuation)); |
| 186 } | 194 } |
| 187 | 195 |
| 188 Configuration visitLogicalExpression( | 196 Configuration visitLogicalExpression( |
| 189 LogicalExpression node, ExpressionConfiguration config) { | 197 LogicalExpression node, ExpressionConfiguration config) { |
| 190 if ('||' == node.operator) { | 198 if ('||' == node.operator) { |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 337 class ContinuationConfiguration extends Configuration { | 345 class ContinuationConfiguration extends Configuration { |
| 338 final ExpressionContinuation continuation; | 346 final ExpressionContinuation continuation; |
| 339 final Value value; | 347 final Value value; |
| 340 | 348 |
| 341 ContinuationConfiguration(this.continuation, this.value); | 349 ContinuationConfiguration(this.continuation, this.value); |
| 342 | 350 |
| 343 Configuration step(StatementExecuter _) => continuation(value); | 351 Configuration step(StatementExecuter _) => continuation(value); |
| 344 } | 352 } |
| 345 | 353 |
| 346 /// Represents the configuration for applying an [ApplicationContinuation]. | 354 /// Represents the configuration for applying an [ApplicationContinuation]. |
| 347 class ArgumentContinuationConfiguration extends Configuration { | 355 class ExpressionListContinuationConfiguration extends Configuration { |
| 348 final ApplicationContinuation continuation; | 356 final ApplicationContinuation continuation; |
| 349 final List<ArgumentValue> argumentValues; | 357 final List<InterpreterValue> values; |
| 350 | 358 |
| 351 ArgumentContinuationConfiguration(this.continuation, this.argumentValues); | 359 ExpressionListContinuationConfiguration(this.continuation, this.values); |
| 352 | 360 |
| 353 Configuration step(StatementExecuter _) => continuation(argumentValues); | 361 Configuration step(StatementExecuter _) => continuation(values); |
| 354 } | 362 } |
| 355 | 363 |
| 356 /// Represents the configuration for evaluating an [Expression]. | 364 /// Represents the configuration for evaluating an [Expression]. |
| 357 class ExpressionConfiguration extends Configuration { | 365 class ExpressionConfiguration extends Configuration { |
| 358 final Expression expression; | 366 final Expression expression; |
| 359 | 367 |
| 360 /// Environment in which the expression is evaluated. | 368 /// Environment in which the expression is evaluated. |
| 361 final Environment environment; | 369 final Environment environment; |
| 362 | 370 |
| 363 /// Next continuation to be applied. | 371 /// Next continuation to be applied. |
| 364 final Continuation continuation; | 372 final Continuation continuation; |
| 365 | 373 |
| 366 ExpressionConfiguration(this.expression, this.environment, this.continuation); | 374 ExpressionConfiguration(this.expression, this.environment, this.continuation); |
| 367 | 375 |
| 368 Configuration step(StatementExecuter executer) => | 376 Configuration step(StatementExecuter executer) => |
| 369 executer.eval(expression, this); | 377 executer.eval(expression, this); |
| 370 } | 378 } |
| 371 | 379 |
| 372 /// Represents the configuration for evaluating a list of argument expressions. | 380 /// Represents the configuration for evaluating a list of expressions. |
| 373 class ArgumentsConfiguration extends Configuration { | 381 class ExpressionListConfiguration extends Configuration { |
| 374 final List<ArgumentExpression> arguments; | 382 final List<InterpreterExpression> expressions; |
| 375 final Environment environment; | 383 final Environment environment; |
| 376 final Continuation continuation; | 384 final Continuation continuation; |
| 377 | 385 |
| 378 ArgumentsConfiguration(this.arguments, this.environment, this.continuation); | 386 ExpressionListConfiguration( |
| 387 this.expressions, this.environment, this.continuation); |
| 379 | 388 |
| 380 Configuration step(StatementExecuter executer) => | 389 Configuration step(StatementExecuter executer) => |
| 381 executer.evalArgs(arguments, environment, continuation); | 390 executer.evalList(expressions, environment, continuation); |
| 382 } | 391 } |
| 383 | 392 |
| 384 abstract class ArgumentExpression { | 393 abstract class InterpreterExpression { |
| 385 Expression get expression; | 394 Expression get expression; |
| 395 |
| 396 InterpreterValue assignValue(Value v); |
| 386 } | 397 } |
| 387 | 398 |
| 388 class PositionalArgumentExpression extends ArgumentExpression { | 399 class PositionalArgumentExpression extends InterpreterExpression { |
| 389 final Expression expression; | 400 final Expression expression; |
| 390 | 401 |
| 391 PositionalArgumentExpression(this.expression); | 402 PositionalArgumentExpression(this.expression); |
| 403 |
| 404 InterpreterValue assignValue(Value v) => new PositionalArgumentValue(v); |
| 392 } | 405 } |
| 393 | 406 |
| 394 class NamedArgumentExpression extends ArgumentExpression { | 407 class NamedArgumentExpression extends InterpreterExpression { |
| 395 final String name; | 408 final String name; |
| 396 final Expression expression; | 409 final Expression expression; |
| 397 | 410 |
| 398 NamedArgumentExpression(this.name, this.expression); | 411 NamedArgumentExpression(this.name, this.expression); |
| 412 InterpreterValue assignValue(Value v) => new NamedArgumentValue(name, v); |
| 399 } | 413 } |
| 400 | 414 |
| 401 abstract class ArgumentValue { | 415 class LocalInitializerExpression extends InterpreterExpression { |
| 416 final VariableDeclaration variable; |
| 417 |
| 418 Expression get expression => variable.initializer; |
| 419 |
| 420 LocalInitializerExpression(this.variable); |
| 421 |
| 422 InterpreterValue assignValue(Value v) => |
| 423 new LocalInitializerValue(variable, v); |
| 424 } |
| 425 |
| 426 class FieldInitializerExpression extends InterpreterExpression { |
| 427 final Field field; |
| 428 final Expression expression; |
| 429 |
| 430 FieldInitializerExpression(this.field, this.expression); |
| 431 |
| 432 InterpreterValue assignValue(Value v) => new FieldInitializerValue(field, v); |
| 433 } |
| 434 |
| 435 abstract class InterpreterValue { |
| 402 Value get value; | 436 Value get value; |
| 403 } | 437 } |
| 404 | 438 |
| 405 class PositionalArgumentValue extends ArgumentValue { | 439 class PositionalArgumentValue extends InterpreterValue { |
| 406 final Value value; | 440 final Value value; |
| 407 | 441 |
| 408 PositionalArgumentValue(this.value); | 442 PositionalArgumentValue(this.value); |
| 409 } | 443 } |
| 410 | 444 |
| 411 class NamedArgumentValue extends ArgumentValue { | 445 class NamedArgumentValue extends InterpreterValue { |
| 412 final String name; | 446 final String name; |
| 413 final Value value; | 447 final Value value; |
| 414 | 448 |
| 415 NamedArgumentValue(this.name, this.value); | 449 NamedArgumentValue(this.name, this.value); |
| 416 } | 450 } |
| 417 | 451 |
| 452 class LocalInitializerValue extends InterpreterValue { |
| 453 final VariableDeclaration variable; |
| 454 final Value value; |
| 455 |
| 456 LocalInitializerValue(this.variable, this.value); |
| 457 } |
| 458 |
| 459 class FieldInitializerValue extends InterpreterValue { |
| 460 final Field field; |
| 461 final Value value; |
| 462 |
| 463 FieldInitializerValue(this.field, this.value); |
| 464 } |
| 465 |
| 418 abstract class Continuation {} | 466 abstract class Continuation {} |
| 419 | 467 |
| 420 /// Represents the continuation called after the evaluation of argument | 468 /// Represents the continuation called after the evaluation of argument |
| 421 /// expressions. | 469 /// expressions. |
| 422 abstract class ApplicationContinuation extends Continuation { | 470 abstract class ApplicationContinuation extends Continuation { |
| 423 Configuration call(List<ArgumentValue> args); | 471 Configuration call(List<InterpreterValue> values); |
| 424 | 472 |
| 425 /// Creates an environment binding actual argument values to formal parameters | 473 /// Creates an environment binding actual argument values to formal parameters |
| 426 /// of the function in a new environment, which is used to execute the | 474 /// of the function in a new environment, which is used to execute the |
| 427 /// body od the function. | 475 /// body od the function. |
| 476 /// TODO: Add checks for validation of arguments according to spec. |
| 428 static Environment createEnvironment( | 477 static Environment createEnvironment( |
| 429 FunctionNode function, List<ArgumentValue> args) { | 478 FunctionNode function, List<InterpreterValue> args) { |
| 430 Environment newEnv = new Environment.empty(); | 479 Environment newEnv = new Environment.empty(); |
| 431 List<PositionalArgumentValue> positional = args.reversed | 480 List<PositionalArgumentValue> positional = args.reversed |
| 432 .where((ArgumentValue av) => av is PositionalArgumentValue) | 481 .where((InterpreterValue av) => av is PositionalArgumentValue) |
| 433 .toList(); | 482 .toList(); |
| 434 | 483 |
| 435 // Add positional parameters. | 484 // Add positional parameters. |
| 436 for (int i = 0; i < positional.length; ++i) { | 485 for (int i = 0; i < positional.length; ++i) { |
| 437 newEnv.expand(function.positionalParameters[i], positional[i].value); | 486 newEnv.expand(function.positionalParameters[i], positional[i].value); |
| 438 } | 487 } |
| 439 | 488 |
| 440 Map<String, Value> named = new Map.fromIterable( | 489 Map<String, Value> named = new Map.fromIterable( |
| 441 args.where((ArgumentValue av) => av is NamedArgumentValue), | 490 args.where((InterpreterValue av) => av is NamedArgumentValue), |
| 442 key: (NamedArgumentValue av) => av.name, | 491 key: (NamedArgumentValue av) => av.name, |
| 443 value: (NamedArgumentValue av) => av.value); | 492 value: (NamedArgumentValue av) => av.value); |
| 444 | 493 |
| 445 // Add named parameters. | 494 // Add named parameters. |
| 446 for (VariableDeclaration v in function.namedParameters) { | 495 for (VariableDeclaration v in function.namedParameters) { |
| 447 newEnv.expand(v, named[v.name.toString()]); | 496 newEnv.expand(v, named[v.name.toString()]); |
| 448 } | 497 } |
| 449 | 498 |
| 450 return newEnv; | 499 return newEnv; |
| 451 } | 500 } |
| 452 } | 501 } |
| 453 | 502 |
| 454 /// Represents the application continuation for static invocation. | 503 /// Represents the application continuation for static invocation. |
| 455 class StaticInvocationApplication extends ApplicationContinuation { | 504 class StaticInvocationApplication extends ApplicationContinuation { |
| 456 final FunctionNode function; | 505 final FunctionNode function; |
| 457 final ExpressionContinuation continuation; | 506 final ExpressionContinuation continuation; |
| 458 | 507 |
| 459 StaticInvocationApplication(this.function, this.continuation); | 508 StaticInvocationApplication(this.function, this.continuation); |
| 460 | 509 |
| 461 Configuration call(List<ArgumentValue> args) { | 510 Configuration call(List<InterpreterValue> argValues) { |
| 462 Environment functionEnv = | 511 Environment functionEnv = |
| 463 ApplicationContinuation.createEnvironment(function, args); | 512 ApplicationContinuation.createEnvironment(function, argValues); |
| 464 | 513 |
| 465 State bodyState = new State.initial() | 514 State bodyState = new State.initial() |
| 466 .withExpressionContinuation(continuation) | 515 .withExpressionContinuation(continuation) |
| 467 .withConfiguration(new ExitConfiguration(continuation)) | 516 .withConfiguration(new ExitConfiguration(continuation)) |
| 468 .withEnvironment(functionEnv); | 517 .withEnvironment(functionEnv); |
| 469 return new StatementConfiguration(function.body, bodyState); | 518 return new StatementConfiguration(function.body, bodyState); |
| 470 } | 519 } |
| 471 } | 520 } |
| 472 | 521 |
| 522 /// Represents the application continuation for constructor invocation applied |
| 523 /// on the list of evaluated arguments. |
| 524 class ConstructorInvocationApplication extends ApplicationContinuation { |
| 525 final ObjectValue newObject; |
| 526 final Constructor constructor; |
| 527 final ExpressionContinuation expressionContinuation; |
| 528 |
| 529 ConstructorInvocationApplication( |
| 530 this.newObject, this.constructor, this.expressionContinuation); |
| 531 |
| 532 Configuration call(List<InterpreterValue> argValues) { |
| 533 Environment ctrEnv = ApplicationContinuation.createEnvironment( |
| 534 constructor.function, argValues); |
| 535 |
| 536 if (constructor.initializers.isNotEmpty && |
| 537 constructor.initializers.last is RedirectingInitializer) { |
| 538 var cont = new RedirectingConstructorInvocationApplication(newObject, |
| 539 constructor.initializers.last, ctrEnv, expressionContinuation); |
| 540 var es = _createLocalInitializerExpressionList( |
| 541 constructor.initializers.take(constructor.initializers.length - 1)); |
| 542 return new ExpressionListConfiguration(es, ctrEnv, cont); |
| 543 } |
| 544 |
| 545 var cont = new InstanceFieldsApplication( |
| 546 newObject, constructor, expressionContinuation); |
| 547 var fieldExpressions = _createInstanceInitializers(constructor); |
| 548 |
| 549 return new ExpressionListConfiguration(fieldExpressions, ctrEnv, cont); |
| 550 } |
| 551 |
| 552 /// Creates a list of expressions for local initializers. |
| 553 static List<InterpreterExpression> _createLocalInitializerExpressionList( |
| 554 List<LocalInitializer> initializers) { |
| 555 List<InterpreterExpression> es = <InterpreterExpression>[]; |
| 556 |
| 557 for (int i = 0; i < initializers.length; i++) { |
| 558 var current = initializers[i]; |
| 559 es.add(new LocalInitializerExpression(current.variable)); |
| 560 } |
| 561 return es; |
| 562 } |
| 563 |
| 564 /// Creates a list of expressions for instance field initializers in |
| 565 /// immediately enclosing class. |
| 566 static List<InterpreterExpression> _createInstanceInitializers( |
| 567 Constructor ctr) { |
| 568 Class currentClass = new Class(ctr.enclosingClass.reference); |
| 569 List<InterpreterExpression> es = <InterpreterExpression>[]; |
| 570 |
| 571 for (int i = currentClass.superclass?.instanceSize ?? 0; |
| 572 i < currentClass.instanceSize; |
| 573 i++) { |
| 574 Field current = currentClass.instanceFields[i]; |
| 575 if (current.initializer != null) { |
| 576 es.add(new FieldInitializerExpression(current, current.initializer)); |
| 577 } |
| 578 } |
| 579 |
| 580 return es; |
| 581 } |
| 582 } |
| 583 |
| 584 /// Represents the application continuation applied on the list of evaluated |
| 585 /// local initializer expressions. |
| 586 class RedirectingConstructorInvocationApplication |
| 587 extends ApplicationContinuation { |
| 588 final ObjectValue newObject; |
| 589 final RedirectingInitializer initializer; |
| 590 final Environment environment; |
| 591 final ExpressionContinuation expressionContinuation; |
| 592 |
| 593 RedirectingConstructorInvocationApplication(this.newObject, this.initializer, |
| 594 this.environment, this.expressionContinuation); |
| 595 |
| 596 Configuration call(List<InterpreterValue> localValues) { |
| 597 for (LocalInitializerValue current in localValues.reversed) { |
| 598 environment.expand(current.variable, current.value); |
| 599 } |
| 600 var cont = new ConstructorInvocationApplication( |
| 601 newObject, initializer.target, expressionContinuation); |
| 602 var args = _createArgumentExpressionList( |
| 603 initializer.arguments, initializer.target.function); |
| 604 |
| 605 return new ExpressionListConfiguration(args, environment, cont); |
| 606 } |
| 607 } |
| 608 |
| 609 /// Represents the application continuation applied on the list of evaluated |
| 610 /// field initializer expressions. |
| 611 class InstanceFieldsApplication extends ApplicationContinuation { |
| 612 final ObjectValue newObject; |
| 613 final Constructor constructor; |
| 614 final ExpressionContinuation expressionContinuation; |
| 615 |
| 616 final Class _currentClass; |
| 617 |
| 618 InstanceFieldsApplication( |
| 619 this.newObject, this.constructor, this.expressionContinuation) |
| 620 : _currentClass = new Class(constructor.enclosingClass.reference); |
| 621 |
| 622 Configuration call(List<InterpreterValue> fieldValues) { |
| 623 for (FieldInitializerValue current in fieldValues.reversed) { |
| 624 _currentClass.setProperty(newObject, current.field, current.value); |
| 625 } |
| 626 |
| 627 return new ContinuationConfiguration(expressionContinuation, newObject); |
| 628 } |
| 629 } |
| 630 |
| 473 /// Represents the application continuation called after the evaluation of all | 631 /// Represents the application continuation called after the evaluation of all |
| 474 /// argument expressions for an invocation. | 632 /// argument expressions for an invocation. |
| 475 class ArgumentValueApplication extends ApplicationContinuation { | 633 class ValueApplication extends ApplicationContinuation { |
| 476 final ArgumentValue value; | 634 final InterpreterValue value; |
| 477 final ApplicationContinuation applicationContinuation; | 635 final ApplicationContinuation applicationContinuation; |
| 478 | 636 |
| 479 ArgumentValueApplication(this.value, this.applicationContinuation); | 637 ValueApplication(this.value, this.applicationContinuation); |
| 480 | 638 |
| 481 Configuration call(List<ArgumentValue> args) { | 639 Configuration call(List<InterpreterValue> args) { |
| 482 args.add(value); | 640 args.add(value); |
| 483 return new ArgumentContinuationConfiguration(applicationContinuation, args); | 641 return new ExpressionListContinuationConfiguration( |
| 642 applicationContinuation, args); |
| 484 } | 643 } |
| 485 } | 644 } |
| 486 | 645 |
| 487 /// Represents an expression continuation. | 646 /// Represents an expression continuation. |
| 488 abstract class ExpressionContinuation extends Continuation { | 647 abstract class ExpressionContinuation extends Continuation { |
| 489 Configuration call(Value v); | 648 Configuration call(Value v); |
| 490 } | 649 } |
| 491 | 650 |
| 492 /// Represents a continuation that returns the next [StatementConfiguration] | 651 /// Represents a continuation that returns the next [StatementConfiguration] |
| 493 /// to be executed. | 652 /// to be executed. |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 550 | 709 |
| 551 Configuration call(Value v) { | 710 Configuration call(Value v) { |
| 552 Setter setter = receiver.class_.lookupSetter(name); | 711 Setter setter = receiver.class_.lookupSetter(name); |
| 553 setter(receiver, v); | 712 setter(receiver, v); |
| 554 return new ContinuationConfiguration(continuation, v); | 713 return new ContinuationConfiguration(continuation, v); |
| 555 } | 714 } |
| 556 } | 715 } |
| 557 | 716 |
| 558 /// Represents a continuation to be called after the evaluation of an actual | 717 /// Represents a continuation to be called after the evaluation of an actual |
| 559 /// argument for function invocation. | 718 /// argument for function invocation. |
| 560 /// TODO: Add checks for validation of arguments according to spec. | 719 class ExpressionListContinuation extends ExpressionContinuation { |
| 561 class ActualArgumentsContinuation extends ExpressionContinuation { | 720 final InterpreterExpression currentExpression; |
| 562 final ArgumentExpression currentArgument; | 721 final List<InterpreterExpression> expressions; |
| 563 final List<ArgumentExpression> arguments; | |
| 564 final Environment environment; | 722 final Environment environment; |
| 565 final ApplicationContinuation applicationContinuation; | 723 final ApplicationContinuation applicationContinuation; |
| 566 | 724 |
| 567 ActualArgumentsContinuation(this.currentArgument, this.arguments, | 725 ExpressionListContinuation(this.currentExpression, this.expressions, |
| 568 this.environment, this.applicationContinuation); | 726 this.environment, this.applicationContinuation); |
| 569 | 727 |
| 570 Configuration call(Value v) { | 728 Configuration call(Value v) { |
| 571 ArgumentValue argumentValue; | 729 ValueApplication app = new ValueApplication( |
| 572 if (currentArgument is NamedArgumentExpression) { | 730 currentExpression.assignValue(v), applicationContinuation); |
| 573 argumentValue = new NamedArgumentValue( | 731 return new ExpressionListConfiguration(expressions, environment, app); |
| 574 (currentArgument as NamedArgumentExpression).name, v); | |
| 575 } else { | |
| 576 assert(currentArgument is PositionalArgumentExpression); | |
| 577 argumentValue = new PositionalArgumentValue(v); | |
| 578 } | |
| 579 | |
| 580 return new ArgumentsConfiguration(arguments, environment, | |
| 581 new ArgumentValueApplication(argumentValue, applicationContinuation)); | |
| 582 } | 732 } |
| 583 } | 733 } |
| 584 | 734 |
| 585 class MethodInvocationContinuation extends ExpressionContinuation { | 735 class MethodInvocationContinuation extends ExpressionContinuation { |
| 586 final Arguments arguments; | 736 final Arguments arguments; |
| 587 final Name methodName; | 737 final Name methodName; |
| 588 final Environment environment; | 738 final Environment environment; |
| 589 final ExpressionContinuation continuation; | 739 final ExpressionContinuation continuation; |
| 590 | 740 |
| 591 MethodInvocationContinuation( | 741 MethodInvocationContinuation( |
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 807 void trampolinedExecution(Configuration configuration) { | 957 void trampolinedExecution(Configuration configuration) { |
| 808 while (configuration != null) { | 958 while (configuration != null) { |
| 809 configuration = configuration.step(this); | 959 configuration = configuration.step(this); |
| 810 } | 960 } |
| 811 } | 961 } |
| 812 | 962 |
| 813 Configuration exec(Statement statement, State state) => | 963 Configuration exec(Statement statement, State state) => |
| 814 statement.accept1(this, state); | 964 statement.accept1(this, state); |
| 815 Configuration eval(Expression expression, ExpressionConfiguration config) => | 965 Configuration eval(Expression expression, ExpressionConfiguration config) => |
| 816 evaluator.eval(expression, config); | 966 evaluator.eval(expression, config); |
| 817 Configuration evalArgs( | 967 Configuration evalList( |
| 818 List<ArgumentExpression> args, Environment env, Continuation cont) => | 968 List<InterpreterExpression> es, Environment env, Continuation cont) => |
| 819 evaluator.evalArgs(args, env, cont); | 969 evaluator.evalList(es, env, cont); |
| 820 | 970 |
| 821 Configuration defaultStatement(Statement node, State state) { | 971 Configuration defaultStatement(Statement node, State state) { |
| 822 throw notImplemented( | 972 throw notImplemented( |
| 823 m: "Execution is not implemented for statement:\n$node "); | 973 m: "Execution is not implemented for statement:\n$node "); |
| 824 } | 974 } |
| 825 | 975 |
| 826 Configuration visitInvalidStatement(InvalidStatement node, State state) { | 976 Configuration visitInvalidStatement(InvalidStatement node, State state) { |
| 827 throw "Invalid statement at ${node.location}"; | 977 throw "Invalid statement at ${node.location}"; |
| 828 } | 978 } |
| 829 | 979 |
| (...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1139 notImplemented({String m, Object obj}) { | 1289 notImplemented({String m, Object obj}) { |
| 1140 throw new NotImplemented(m ?? 'Evaluation for $obj is not implemented'); | 1290 throw new NotImplemented(m ?? 'Evaluation for $obj is not implemented'); |
| 1141 } | 1291 } |
| 1142 | 1292 |
| 1143 // ------------------------------------------------------------------------ | 1293 // ------------------------------------------------------------------------ |
| 1144 // INTERNAL FUNCTIONS | 1294 // INTERNAL FUNCTIONS |
| 1145 // ------------------------------------------------------------------------ | 1295 // ------------------------------------------------------------------------ |
| 1146 /// Creates a list of all argument expressions to be evaluated for the | 1296 /// Creates a list of all argument expressions to be evaluated for the |
| 1147 /// invocation of the provided [FunctionNode] containing the actual arguments | 1297 /// invocation of the provided [FunctionNode] containing the actual arguments |
| 1148 /// and the optional argument initializers. | 1298 /// and the optional argument initializers. |
| 1149 List<ArgumentExpression> _createArgumentExpressionList( | 1299 List<InterpreterExpression> _createArgumentExpressionList( |
| 1150 Arguments providedArgs, FunctionNode fun) { | 1300 Arguments providedArgs, FunctionNode fun) { |
| 1151 List<ArgumentExpression> args = <ArgumentExpression>[]; | 1301 List<InterpreterExpression> args = <InterpreterExpression>[]; |
| 1152 // Add positional arguments expressions. | 1302 // Add positional arguments expressions. |
| 1153 args.addAll(providedArgs.positional | 1303 args.addAll(providedArgs.positional |
| 1154 .map((Expression e) => new PositionalArgumentExpression(e))); | 1304 .map((Expression e) => new PositionalArgumentExpression(e))); |
| 1155 | 1305 |
| 1156 // Add optional positional argument initializers. | 1306 // Add optional positional argument initializers. |
| 1157 for (int i = providedArgs.positional.length; | 1307 for (int i = providedArgs.positional.length; |
| 1158 i < fun.positionalParameters.length; | 1308 i < fun.positionalParameters.length; |
| 1159 i++) { | 1309 i++) { |
| 1160 args.add(new PositionalArgumentExpression( | 1310 args.add(new PositionalArgumentExpression( |
| 1161 fun.positionalParameters[i].initializer)); | 1311 fun.positionalParameters[i].initializer)); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1172 var current = providedArgs.named[i]; | 1322 var current = providedArgs.named[i]; |
| 1173 args.add(new NamedArgumentExpression(current.name, current.value)); | 1323 args.add(new NamedArgumentExpression(current.name, current.value)); |
| 1174 namedFormals.remove(current.name); | 1324 namedFormals.remove(current.name); |
| 1175 } | 1325 } |
| 1176 | 1326 |
| 1177 // Add missing optional named initializers. | 1327 // Add missing optional named initializers. |
| 1178 args.addAll(namedFormals.values); | 1328 args.addAll(namedFormals.values); |
| 1179 | 1329 |
| 1180 return args; | 1330 return args; |
| 1181 } | 1331 } |
| OLD | NEW |