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

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

Issue 2832873004: Add support for static invocation with arguments (Closed)
Patch Set: 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
477 OptionalArgumentsContinuation(this.positional, this.named, this.functionNode,
478 this.environment, this.continuation)
479 : _currentPositional = positional.length {
480 for (VariableDeclaration vd in functionNode.namedParameters) {
481 if (named[vd.name] == null) {
482 _missingFormalNamed[vd.name] = vd;
483 }
484 }
485 }
486
487 Configuration call(Value v) {
488 if (_currentPositional < functionNode.positionalParameters.length) {
489 // Value is a optional positional argument
490 assert(_currentPositional >= functionNode.requiredParameterCount);
Dmitry Stefantsov 2017/04/21 13:49:36 I think we can make this assertion once, in the co
zhivkag 2017/04/21 16:44:01 Done.
491 positional.add(v);
492 _currentPositional++;
493 } else {
494 // Value is a optional named argument.
495 String name = _missingFormalNamed.keys.first;
Dmitry Stefantsov 2017/04/21 13:49:36 I think we need to find another way of determining
zhivkag 2017/04/21 16:44:01 Done. Indeed, another approach for this would be b
496 named[name] = v;
497 _missingFormalNamed.remove(name);
498 }
499
500 return createCurrentConfiguration();
501 }
502
503 /// Creates the current configuration for the evaluation of invocation a
504 /// function.
505 Configuration createCurrentConfiguration() {
506 if (_currentPositional < functionNode.positionalParameters.length) {
507 // Next argument to evaluate is a missing positional argument.
508 // Evaluate its initializer.
509 return new ExpressionConfiguration(
510 functionNode.positionalParameters[_currentPositional].initializer,
511 environment,
512 this);
513 }
514 if (named.length < functionNode.namedParameters.length) {
515 // Next argument to evaluate is a missing named argument.
516 // Evaluate its initializer.
517 String next = _missingFormalNamed.keys.first;
518 return new ExpressionConfiguration(
519 _missingFormalNamed[next].initializer, environment, this);
520 }
521
522 Environment newEnv = _createEnvironment();
523 State bodyState = new State.initial()
524 .withExpressionContinuation(continuation)
525 .withConfiguration(new ExitConfiguration(continuation))
526 .withEnvironment(newEnv);
527
528 return new StatementConfiguration(functionNode.body, bodyState);
529 }
530
531 /// Creates an environment binding actual argument values to formal parameters
532 /// of the function in a new environment, which is used to execute the
533 /// body od the function.
534 Environment _createEnvironment() {
535 Environment newEnv = new Environment.empty();
536 // Add positional parameters.
537 for (int i = 0; i < positional.length; ++i) {
538 newEnv.expand(functionNode.positionalParameters[i], positional[i]);
539 }
540 // Add named parameters.
541 for (VariableDeclaration v in functionNode.namedParameters) {
542 newEnv.expand(v, named[v.name.toString()]);
543 }
544
545 return newEnv;
546 }
547 }
548
431 class MethodInvocationContinuation extends ExpressionContinuation { 549 class MethodInvocationContinuation extends ExpressionContinuation {
432 final Arguments arguments; 550 final Arguments arguments;
433 final Name methodName; 551 final Name methodName;
434 final Environment environment; 552 final Environment environment;
435 final ExpressionContinuation continuation; 553 final ExpressionContinuation continuation;
436 554
437 MethodInvocationContinuation( 555 MethodInvocationContinuation(
438 this.arguments, this.methodName, this.environment, this.continuation); 556 this.arguments, this.methodName, this.environment, this.continuation);
439 557
440 Configuration call(Value receiver) { 558 Configuration call(Value receiver) {
(...skipping 530 matching lines...) Expand 10 before | Expand all | Expand 10 after
971 1089
972 class NullValue extends LiteralValue { 1090 class NullValue extends LiteralValue {
973 Object get value => null; 1091 Object get value => null;
974 1092
975 const NullValue(); 1093 const NullValue();
976 } 1094 }
977 1095
978 notImplemented({String m, Object obj}) { 1096 notImplemented({String m, Object obj}) {
979 throw new NotImplemented(m ?? 'Evaluation for $obj is not implemented'); 1097 throw new NotImplemented(m ?? 'Evaluation for $obj is not implemented');
980 } 1098 }
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