| 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 class NotImplemented { | 9 class NotImplemented { |
| 10 String message; | 10 String message; |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 124 StaticSet node, ExpressionConfiguration config) => | 124 StaticSet node, ExpressionConfiguration config) => |
| 125 defaultExpression(node, config); | 125 defaultExpression(node, config); |
| 126 | 126 |
| 127 Configuration visitStaticInvocation( | 127 Configuration visitStaticInvocation( |
| 128 StaticInvocation node, ExpressionConfiguration config) { | 128 StaticInvocation node, ExpressionConfiguration config) { |
| 129 if ('print' == node.name.toString()) { | 129 if ('print' == node.name.toString()) { |
| 130 var cont = new PrintContinuation(config.continuation); | 130 var cont = new PrintContinuation(config.continuation); |
| 131 return new ExpressionConfiguration( | 131 return new ExpressionConfiguration( |
| 132 node.arguments.positional.first, config.environment, cont); | 132 node.arguments.positional.first, config.environment, cont); |
| 133 } else { | 133 } else { |
| 134 // Currently supports only static invocations with no arguments. | 134 var cont = new ActualArgumentsContinuation(node.arguments, |
| 135 if (node.arguments.positional.isEmpty && node.arguments.named.isEmpty) { | 135 node.target.function, config.environment, config.continuation); |
| 136 State statementState = new State.initial() | 136 return cont.createCurrentConfiguration(); |
| 137 .withExpressionContinuation(config.continuation) | |
| 138 .withConfiguration(new ExitConfiguration(config.continuation)); | |
| 139 | |
| 140 return new StatementConfiguration( | |
| 141 node.target.function.body, statementState); | |
| 142 } | |
| 143 throw new NotImplemented( | |
| 144 'Support for static invocation with arguments is not implemented'); | |
| 145 } | 137 } |
| 146 } | 138 } |
| 147 | 139 |
| 148 Configuration visitMethodInvocation( | 140 Configuration visitMethodInvocation( |
| 149 MethodInvocation node, ExpressionConfiguration config) { | 141 MethodInvocation node, ExpressionConfiguration config) { |
| 150 // Currently supports only method invocation with <2 arguments and is used | 142 // Currently supports only method invocation with <2 arguments and is used |
| 151 // to evaluate implemented operators for int, double and String values. | 143 // to evaluate implemented operators for int, double and String values. |
| 152 var cont = new MethodInvocationContinuation( | 144 var cont = new MethodInvocationContinuation( |
| 153 node.arguments, node.name, config.environment, config.continuation); | 145 node.arguments, node.name, config.environment, config.continuation); |
| 154 | 146 |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 411 | 403 |
| 412 SetterContinuation(this.receiver, this.name, this.continuation); | 404 SetterContinuation(this.receiver, this.name, this.continuation); |
| 413 | 405 |
| 414 Configuration call(Value v) { | 406 Configuration call(Value v) { |
| 415 Setter setter = receiver.class_.lookupSetter(name); | 407 Setter setter = receiver.class_.lookupSetter(name); |
| 416 setter(receiver, v); | 408 setter(receiver, v); |
| 417 return new ContinuationConfiguration(continuation, v); | 409 return new ContinuationConfiguration(continuation, v); |
| 418 } | 410 } |
| 419 } | 411 } |
| 420 | 412 |
| 421 class StaticInvocationContinuation extends ExpressionContinuation { | 413 /// Represents a continuation to be called after the evaluation of an actual |
| 414 /// argument for function invocation. |
| 415 /// TODO: Add checks for validation of arguments according to spec. |
| 416 class ActualArgumentsContinuation extends ExpressionContinuation { |
| 417 final Arguments arguments; |
| 418 final FunctionNode functionNode; |
| 419 final Environment environment; |
| 422 final ExpressionContinuation continuation; | 420 final ExpressionContinuation continuation; |
| 423 | 421 |
| 424 StaticInvocationContinuation(this.continuation); | 422 final List<Value> _positional = <Value>[]; |
| 423 int _currentPositional = 0; |
| 424 final Map<String, Value> _named = <String, Value>{}; |
| 425 int _currentNamed = 0; |
| 426 |
| 427 ActualArgumentsContinuation( |
| 428 this.arguments, this.functionNode, this.environment, this.continuation); |
| 425 | 429 |
| 426 Configuration call(Value v) { | 430 Configuration call(Value v) { |
| 427 return new ContinuationConfiguration(continuation, v); | 431 if (_currentPositional < arguments.positional.length) { |
| 432 _positional.add(v); |
| 433 _currentPositional++; |
| 434 } else { |
| 435 assert(_currentNamed < arguments.named.length); |
| 436 String name = arguments.named[_currentNamed].name; |
| 437 _named[name] = v; |
| 438 _currentNamed++; |
| 439 } |
| 440 |
| 441 return createCurrentConfiguration(); |
| 442 } |
| 443 |
| 444 Configuration createCurrentConfiguration() { |
| 445 // Next argument to evaluate is a provided positional argument. |
| 446 if (_currentPositional < arguments.positional.length) { |
| 447 return new ExpressionConfiguration( |
| 448 arguments.positional[_currentPositional], environment, this); |
| 449 } |
| 450 // Next argument to evaluate is a provided named argument. |
| 451 if (_currentNamed < arguments.named.length) { |
| 452 return new ExpressionConfiguration( |
| 453 arguments.named[_currentNamed].value, environment, this); |
| 454 } |
| 455 |
| 456 // TODO: check if the number of actual arguments is larger then the number |
| 457 // of required arguments and smaller then the number of formal arguments. |
| 458 |
| 459 return new OptionalArgumentsContinuation( |
| 460 _positional, _named, functionNode, environment, continuation) |
| 461 .createCurrentConfiguration(); |
| 428 } | 462 } |
| 429 } | 463 } |
| 430 | 464 |
| 465 class OptionalArgumentsContinuation extends ExpressionContinuation { |
| 466 final List<Value> positional; |
| 467 final Map<String, Value> named; |
| 468 final FunctionNode functionNode; |
| 469 final Environment environment; |
| 470 final ExpressionContinuation continuation; |
| 471 |
| 472 final Map<String, VariableDeclaration> _missingFormalNamed = |
| 473 <String, VariableDeclaration>{}; |
| 474 |
| 475 int _currentPositional; |
| 476 String _currentNamed; |
| 477 |
| 478 OptionalArgumentsContinuation(this.positional, this.named, this.functionNode, |
| 479 this.environment, this.continuation) { |
| 480 _currentPositional = positional.length; |
| 481 assert(_currentPositional >= functionNode.requiredParameterCount); |
| 482 |
| 483 for (VariableDeclaration vd in functionNode.namedParameters) { |
| 484 if (named[vd.name] == null) { |
| 485 _missingFormalNamed[vd.name] = vd; |
| 486 } |
| 487 } |
| 488 } |
| 489 |
| 490 Configuration call(Value v) { |
| 491 if (_currentPositional < functionNode.positionalParameters.length) { |
| 492 // Value is a optional positional argument |
| 493 positional.add(v); |
| 494 _currentPositional++; |
| 495 } else { |
| 496 // Value is a optional named argument. |
| 497 assert(named[_currentNamed] == null); |
| 498 named[_currentNamed] = v; |
| 499 } |
| 500 |
| 501 return createCurrentConfiguration(); |
| 502 } |
| 503 |
| 504 /// Creates the current configuration for the evaluation of invocation a |
| 505 /// function. |
| 506 Configuration createCurrentConfiguration() { |
| 507 if (_currentPositional < functionNode.positionalParameters.length) { |
| 508 // Next argument to evaluate is a missing positional argument. |
| 509 // Evaluate its initializer. |
| 510 return new ExpressionConfiguration( |
| 511 functionNode.positionalParameters[_currentPositional].initializer, |
| 512 environment, |
| 513 this); |
| 514 } |
| 515 if (named.length < functionNode.namedParameters.length) { |
| 516 // Next argument to evaluate is a missing named argument. |
| 517 // Evaluate its initializer. |
| 518 _currentNamed = _missingFormalNamed.keys.first; |
| 519 Expression initializer = _missingFormalNamed[_currentNamed].initializer; |
| 520 _missingFormalNamed.remove(_currentNamed); |
| 521 return new ExpressionConfiguration(initializer, environment, this); |
| 522 } |
| 523 |
| 524 Environment newEnv = _createEnvironment(); |
| 525 State bodyState = new State.initial() |
| 526 .withExpressionContinuation(continuation) |
| 527 .withConfiguration(new ExitConfiguration(continuation)) |
| 528 .withEnvironment(newEnv); |
| 529 |
| 530 return new StatementConfiguration(functionNode.body, bodyState); |
| 531 } |
| 532 |
| 533 /// Creates an environment binding actual argument values to formal parameters |
| 534 /// of the function in a new environment, which is used to execute the |
| 535 /// body od the function. |
| 536 Environment _createEnvironment() { |
| 537 Environment newEnv = new Environment.empty(); |
| 538 // Add positional parameters. |
| 539 for (int i = 0; i < positional.length; ++i) { |
| 540 newEnv.expand(functionNode.positionalParameters[i], positional[i]); |
| 541 } |
| 542 // Add named parameters. |
| 543 for (VariableDeclaration v in functionNode.namedParameters) { |
| 544 newEnv.expand(v, named[v.name.toString()]); |
| 545 } |
| 546 |
| 547 return newEnv; |
| 548 } |
| 549 } |
| 550 |
| 431 class MethodInvocationContinuation extends ExpressionContinuation { | 551 class MethodInvocationContinuation extends ExpressionContinuation { |
| 432 final Arguments arguments; | 552 final Arguments arguments; |
| 433 final Name methodName; | 553 final Name methodName; |
| 434 final Environment environment; | 554 final Environment environment; |
| 435 final ExpressionContinuation continuation; | 555 final ExpressionContinuation continuation; |
| 436 | 556 |
| 437 MethodInvocationContinuation( | 557 MethodInvocationContinuation( |
| 438 this.arguments, this.methodName, this.environment, this.continuation); | 558 this.arguments, this.methodName, this.environment, this.continuation); |
| 439 | 559 |
| 440 Configuration call(Value receiver) { | 560 Configuration call(Value receiver) { |
| (...skipping 530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 971 | 1091 |
| 972 class NullValue extends LiteralValue { | 1092 class NullValue extends LiteralValue { |
| 973 Object get value => null; | 1093 Object get value => null; |
| 974 | 1094 |
| 975 const NullValue(); | 1095 const NullValue(); |
| 976 } | 1096 } |
| 977 | 1097 |
| 978 notImplemented({String m, Object obj}) { | 1098 notImplemented({String m, Object obj}) { |
| 979 throw new NotImplemented(m ?? 'Evaluation for $obj is not implemented'); | 1099 throw new NotImplemented(m ?? 'Evaluation for $obj is not implemented'); |
| 980 } | 1100 } |
| OLD | NEW |