Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(74)

Side by Side Diff: pkg/kernel/lib/interpreter/interpreter.dart

Issue 2832873004: Add support for static invocation with arguments (Closed)
Patch Set: Apply comments Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698