Chromium Code Reviews| 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 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 68 lookupBinding(variable).value = value; | 68 lookupBinding(variable).value = value; |
| 69 } | 69 } |
| 70 | 70 |
| 71 void expand(VariableDeclaration variable, Value value) { | 71 void expand(VariableDeclaration variable, Value value) { |
| 72 assert(!contains(variable)); | 72 assert(!contains(variable)); |
| 73 bindings.add(new Binding(variable, value)); | 73 bindings.add(new Binding(variable, value)); |
| 74 } | 74 } |
| 75 } | 75 } |
| 76 | 76 |
| 77 /// Evaluate expressions. | 77 /// Evaluate expressions. |
| 78 class Evaluator extends ExpressionVisitor1<Configuration> { | 78 class Evaluator extends ExpressionVisitor1<Configuration, ExpressionState> { |
| 79 Configuration eval(Expression expr, ExpressionState state) => | 79 Configuration eval(Expression expr, ExpressionState state) => |
| 80 expr.accept1(this, state); | 80 expr.accept1(this, state); |
| 81 | 81 |
| 82 Configuration defaultExpression(Expression node, state) { | 82 Configuration defaultExpression(Expression node, ExpressionState state) { |
| 83 throw new NotImplemented('Evaluation for expressions of type ' | 83 throw new NotImplemented('Evaluation for expressions of type ' |
| 84 '${node.runtimeType} is not implemented.'); | 84 '${node.runtimeType} is not implemented.'); |
| 85 } | 85 } |
| 86 | 86 |
| 87 Configuration visitInvalidExpression1(InvalidExpression node, state) { | 87 Configuration visitInvalidExpression1( |
| 88 InvalidExpression node, ExpressionState state) { | |
| 88 throw 'Invalid expression at ${node.location.toString()}'; | 89 throw 'Invalid expression at ${node.location.toString()}'; |
| 89 } | 90 } |
| 90 | 91 |
| 91 Configuration visitVariableGet(VariableGet node, state) { | 92 Configuration visitVariableGet(VariableGet node, ExpressionState state) { |
| 92 Value value = state.environment.lookup(node.variable); | 93 Value value = state.environment.lookup(node.variable); |
| 93 return new ContinuationConfiguration(state.continuation, value); | 94 return new ContinuationConfiguration(state.continuation, value); |
| 94 } | 95 } |
| 95 | 96 |
| 96 Configuration visitVariableSet(VariableSet node, state) { | 97 Configuration visitVariableSet(VariableSet node, ExpressionState state) { |
| 97 var cont = new VariableSetContinuation(state, node.variable); | 98 var cont = new VariableSetContinuation(state, node.variable); |
| 98 return new ExpressionConfiguration( | 99 return new ExpressionConfiguration( |
| 99 node.value, state.withContinuation(cont)); | 100 node.value, state.withContinuation(cont)); |
| 100 } | 101 } |
| 101 | 102 |
| 102 Configuration visitPropertyGet(PropertyGet node, state) { | 103 Configuration visitPropertyGet(PropertyGet node, ExpressionState state) { |
| 103 var cont = new PropertyGetContinuation(node.name, state); | 104 var cont = new PropertyGetContinuation(node.name, state); |
| 104 return new ExpressionConfiguration( | 105 return new ExpressionConfiguration( |
| 105 node.receiver, state.withContinuation(cont)); | 106 node.receiver, state.withContinuation(cont)); |
| 106 } | 107 } |
| 107 | 108 |
| 108 Configuration visitPropertySet(PropertySet node, state) { | 109 Configuration visitPropertySet(PropertySet node, ExpressionState state) { |
| 109 var cont = new PropertySetContinuation(node.value, node.name, state); | 110 var cont = new PropertySetContinuation(node.value, node.name, state); |
| 110 return new ExpressionConfiguration( | 111 return new ExpressionConfiguration( |
| 111 node.receiver, state.withContinuation(cont)); | 112 node.receiver, state.withContinuation(cont)); |
| 112 } | 113 } |
| 113 | 114 |
| 114 Configuration visitStaticGet(StaticGet node, state) => | 115 Configuration visitStaticGet(StaticGet node, state) => |
|
Dmitry Stefantsov
2017/04/20 15:48:15
What about this method and the next one?
zhivkag
2017/04/20 16:02:52
I have missed them, thanks for noticing!
| |
| 115 defaultExpression(node, state); | 116 defaultExpression(node, state); |
| 116 Configuration visitStaticSet(StaticSet node, state) => | 117 Configuration visitStaticSet(StaticSet node, state) => |
| 117 defaultExpression(node, state); | 118 defaultExpression(node, state); |
| 118 | 119 |
| 119 Configuration visitStaticInvocation(StaticInvocation node, state) { | 120 Configuration visitStaticInvocation( |
| 121 StaticInvocation node, ExpressionState state) { | |
| 120 if ('print' == node.name.toString()) { | 122 if ('print' == node.name.toString()) { |
| 121 return new ExpressionConfiguration(node.arguments.positional.first, | 123 return new ExpressionConfiguration(node.arguments.positional.first, |
| 122 state.withContinuation(new PrintContinuation(state))); | 124 state.withContinuation(new PrintContinuation(state))); |
| 123 } else { | 125 } else { |
| 124 // Currently supports only static invocations with no arguments. | 126 // Currently supports only static invocations with no arguments. |
| 125 if (node.arguments.positional.isEmpty && node.arguments.named.isEmpty) { | 127 if (node.arguments.positional.isEmpty && node.arguments.named.isEmpty) { |
| 126 State statementState = new State.initial() | 128 State statementState = new State.initial() |
| 127 .withExpressionContinuation(state.continuation) | 129 .withExpressionContinuation(state.continuation) |
| 128 .withConfiguration(new ExitConfiguration(state.continuation)); | 130 .withConfiguration(new ExitConfiguration(state.continuation)); |
| 129 | 131 |
| 130 return new StatementConfiguration( | 132 return new StatementConfiguration( |
| 131 node.target.function.body, statementState); | 133 node.target.function.body, statementState); |
| 132 } | 134 } |
| 133 throw new NotImplemented( | 135 throw new NotImplemented( |
| 134 'Support for static invocation with arguments is not implemented'); | 136 'Support for static invocation with arguments is not implemented'); |
| 135 } | 137 } |
| 136 } | 138 } |
| 137 | 139 |
| 138 Configuration visitMethodInvocation(MethodInvocation node, state) { | 140 Configuration visitMethodInvocation( |
| 141 MethodInvocation node, ExpressionState state) { | |
| 139 // Currently supports only method invocation with <2 arguments and is used | 142 // Currently supports only method invocation with <2 arguments and is used |
| 140 // to evaluate implemented operators for int, double and String values. | 143 // to evaluate implemented operators for int, double and String values. |
| 141 var cont = | 144 var cont = |
| 142 new MethodInvocationContinuation(node.arguments, node.name, state); | 145 new MethodInvocationContinuation(node.arguments, node.name, state); |
| 143 | 146 |
| 144 return new ExpressionConfiguration( | 147 return new ExpressionConfiguration( |
| 145 node.receiver, state.withContinuation(cont)); | 148 node.receiver, state.withContinuation(cont)); |
| 146 } | 149 } |
| 147 | 150 |
| 148 Configuration visitConstructorInvocation(ConstructorInvocation node, state) { | 151 Configuration visitConstructorInvocation( |
| 152 ConstructorInvocation node, ExpressionState state) { | |
| 149 Class class_ = new Class(node.target.enclosingClass.reference); | 153 Class class_ = new Class(node.target.enclosingClass.reference); |
| 150 | 154 |
| 151 // Currently we don't support initializers. | 155 // Currently we don't support initializers. |
| 152 // TODO: Modify to respect dart semantics for initialization. | 156 // TODO: Modify to respect dart semantics for initialization. |
| 153 // 1. Init fields and eval initializers, repeat the same with super. | 157 // 1. Init fields and eval initializers, repeat the same with super. |
| 154 // 2. Eval the Function body of the constructor. | 158 // 2. Eval the Function body of the constructor. |
| 155 List<Value> fields = <Value>[]; | 159 List<Value> fields = <Value>[]; |
| 156 | 160 |
| 157 return new ContinuationConfiguration( | 161 return new ContinuationConfiguration( |
| 158 state.continuation, new ObjectValue(class_, fields)); | 162 state.continuation, new ObjectValue(class_, fields)); |
| 159 } | 163 } |
| 160 | 164 |
| 161 Configuration visitNot(Not node, state) { | 165 Configuration visitNot(Not node, ExpressionState state) { |
| 162 return new ExpressionConfiguration( | 166 return new ExpressionConfiguration( |
| 163 node.operand, state.withContinuation(new NotContinuation(state))); | 167 node.operand, state.withContinuation(new NotContinuation(state))); |
| 164 } | 168 } |
| 165 | 169 |
| 166 Configuration visitLogicalExpression(LogicalExpression node, state) { | 170 Configuration visitLogicalExpression( |
| 171 LogicalExpression node, ExpressionState state) { | |
| 167 if ('||' == node.operator) { | 172 if ('||' == node.operator) { |
| 168 var cont = new OrContinuation(node.right, state); | 173 var cont = new OrContinuation(node.right, state); |
| 169 return new ExpressionConfiguration( | 174 return new ExpressionConfiguration( |
| 170 node.left, state.withContinuation(cont)); | 175 node.left, state.withContinuation(cont)); |
| 171 } else { | 176 } else { |
| 172 assert('&&' == node.operator); | 177 assert('&&' == node.operator); |
| 173 var cont = new AndContinuation(node.right, state); | 178 var cont = new AndContinuation(node.right, state); |
| 174 return new ExpressionConfiguration( | 179 return new ExpressionConfiguration( |
| 175 node.left, state.withContinuation(cont)); | 180 node.left, state.withContinuation(cont)); |
| 176 } | 181 } |
| 177 } | 182 } |
| 178 | 183 |
| 179 Configuration visitConditionalExpression(ConditionalExpression node, state) { | 184 Configuration visitConditionalExpression( |
| 185 ConditionalExpression node, ExpressionState state) { | |
| 180 var cont = new ConditionalContinuation(node.then, node.otherwise, state); | 186 var cont = new ConditionalContinuation(node.then, node.otherwise, state); |
| 181 return new ExpressionConfiguration( | 187 return new ExpressionConfiguration( |
| 182 node.condition, state.withContinuation(cont)); | 188 node.condition, state.withContinuation(cont)); |
| 183 } | 189 } |
| 184 | 190 |
| 185 Configuration visitStringConcatenation(StringConcatenation node, state) { | 191 Configuration visitStringConcatenation( |
| 192 StringConcatenation node, ExpressionState state) { | |
| 186 var cont = new StringConcatenationContinuation(node.expressions, state); | 193 var cont = new StringConcatenationContinuation(node.expressions, state); |
| 187 return new ExpressionConfiguration( | 194 return new ExpressionConfiguration( |
| 188 node.expressions.first, state.withContinuation(cont)); | 195 node.expressions.first, state.withContinuation(cont)); |
| 189 } | 196 } |
| 190 | 197 |
| 191 // Evaluation of BasicLiterals. | 198 // Evaluation of BasicLiterals. |
| 192 Configuration visitStringLiteral(StringLiteral node, state) { | 199 Configuration visitStringLiteral(StringLiteral node, ExpressionState state) { |
| 193 return new ContinuationConfiguration( | 200 return new ContinuationConfiguration( |
| 194 state.continuation, new StringValue(node.value)); | 201 state.continuation, new StringValue(node.value)); |
| 195 } | 202 } |
| 196 | 203 |
| 197 Configuration visitIntLiteral(IntLiteral node, state) { | 204 Configuration visitIntLiteral(IntLiteral node, ExpressionState state) { |
| 198 return new ContinuationConfiguration( | 205 return new ContinuationConfiguration( |
| 199 state.continuation, new IntValue(node.value)); | 206 state.continuation, new IntValue(node.value)); |
| 200 } | 207 } |
| 201 | 208 |
| 202 Configuration visitDoubleLiteral(DoubleLiteral node, state) { | 209 Configuration visitDoubleLiteral(DoubleLiteral node, ExpressionState state) { |
| 203 return new ContinuationConfiguration( | 210 return new ContinuationConfiguration( |
| 204 state.continuation, new DoubleValue(node.value)); | 211 state.continuation, new DoubleValue(node.value)); |
| 205 } | 212 } |
| 206 | 213 |
| 207 Configuration visitBoolLiteral(BoolLiteral node, state) { | 214 Configuration visitBoolLiteral(BoolLiteral node, ExpressionState state) { |
| 208 Value value = node.value ? Value.trueInstance : Value.falseInstance; | 215 Value value = node.value ? Value.trueInstance : Value.falseInstance; |
| 209 return new ContinuationConfiguration(state.continuation, value); | 216 return new ContinuationConfiguration(state.continuation, value); |
| 210 } | 217 } |
| 211 | 218 |
| 212 Configuration visitNullLiteral(NullLiteral node, state) { | 219 Configuration visitNullLiteral(NullLiteral node, ExpressionState state) { |
| 213 return new ContinuationConfiguration( | 220 return new ContinuationConfiguration( |
| 214 state.continuation, Value.nullInstance); | 221 state.continuation, Value.nullInstance); |
| 215 } | 222 } |
| 216 | 223 |
| 217 Configuration visitLet(Let node, state) { | 224 Configuration visitLet(Let node, ExpressionState state) { |
| 218 var letCont = new LetContinuation(node.variable, node.body, state); | 225 var letCont = new LetContinuation(node.variable, node.body, state); |
| 219 return new ExpressionConfiguration( | 226 return new ExpressionConfiguration( |
| 220 node.variable.initializer, state.withContinuation(letCont)); | 227 node.variable.initializer, state.withContinuation(letCont)); |
| 221 } | 228 } |
| 222 } | 229 } |
| 223 | 230 |
| 224 /// Represents a state for statement execution. | 231 /// Represents a state for statement execution. |
| 225 class State { | 232 class State { |
| 226 final Environment environment; | 233 final Environment environment; |
| 227 final Label labels; | 234 final Label labels; |
| (...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 621 | 628 |
| 622 /// Executes statements. | 629 /// Executes statements. |
| 623 /// | 630 /// |
| 624 /// Execution of a statement completes in one of the following ways: | 631 /// Execution of a statement completes in one of the following ways: |
| 625 /// - it completes normally, in which case the execution proceeds to applying | 632 /// - it completes normally, in which case the execution proceeds to applying |
| 626 /// the next continuation | 633 /// the next continuation |
| 627 /// - it breaks with a label, in which case the corresponding continuation is | 634 /// - it breaks with a label, in which case the corresponding continuation is |
| 628 /// returned and applied | 635 /// returned and applied |
| 629 /// - it returns with or without value, TBD | 636 /// - it returns with or without value, TBD |
| 630 /// - it throws, TBD | 637 /// - it throws, TBD |
| 631 class StatementExecuter extends StatementVisitor1<Configuration> { | 638 class StatementExecuter extends StatementVisitor1<Configuration, State> { |
| 632 Evaluator evaluator = new Evaluator(); | 639 Evaluator evaluator = new Evaluator(); |
| 633 | 640 |
| 634 void trampolinedExecution(Configuration configuration) { | 641 void trampolinedExecution(Configuration configuration) { |
| 635 while (configuration != null) { | 642 while (configuration != null) { |
| 636 configuration = configuration.step(this); | 643 configuration = configuration.step(this); |
| 637 } | 644 } |
| 638 } | 645 } |
| 639 | 646 |
| 640 Configuration exec(Statement statement, State state) => | 647 Configuration exec(Statement statement, State state) => |
| 641 statement.accept1(this, state); | 648 statement.accept1(this, state); |
| 642 Configuration eval(Expression expression, ExpressionState state) => | 649 Configuration eval(Expression expression, ExpressionState state) => |
| 643 evaluator.eval(expression, state); | 650 evaluator.eval(expression, state); |
| 644 | 651 |
| 645 Configuration defaultStatement(Statement node, state) { | 652 Configuration defaultStatement(Statement node, State state) { |
| 646 throw notImplemented( | 653 throw notImplemented( |
| 647 m: "Execution is not implemented for statement:\n$node "); | 654 m: "Execution is not implemented for statement:\n$node "); |
| 648 } | 655 } |
| 649 | 656 |
| 650 Configuration visitInvalidStatement(InvalidStatement node, state) { | 657 Configuration visitInvalidStatement(InvalidStatement node, State state) { |
| 651 throw "Invalid statement at ${node.location}"; | 658 throw "Invalid statement at ${node.location}"; |
| 652 } | 659 } |
| 653 | 660 |
| 654 Configuration visitExpressionStatement(ExpressionStatement node, state) { | 661 Configuration visitExpressionStatement( |
| 662 ExpressionStatement node, State state) { | |
| 655 return new ExpressionConfiguration( | 663 return new ExpressionConfiguration( |
| 656 node.expression, new ExpressionState.fromStatementState(state)); | 664 node.expression, new ExpressionState.fromStatementState(state)); |
| 657 } | 665 } |
| 658 | 666 |
| 659 Configuration visitBlock(Block node, state) { | 667 Configuration visitBlock(Block node, State state) { |
| 660 if (node.statements.isEmpty) { | 668 if (node.statements.isEmpty) { |
| 661 return state.statementConfiguration; | 669 return state.statementConfiguration; |
| 662 } | 670 } |
| 663 State blockState = | 671 State blockState = |
| 664 state.withEnvironment(new Environment(state.environment)); | 672 state.withEnvironment(new Environment(state.environment)); |
| 665 StatementConfiguration configuration = state.statementConfiguration; | 673 StatementConfiguration configuration = state.statementConfiguration; |
| 666 for (Statement s in node.statements.reversed) { | 674 for (Statement s in node.statements.reversed) { |
| 667 configuration = new StatementConfiguration( | 675 configuration = new StatementConfiguration( |
| 668 s, blockState.withConfiguration(configuration)); | 676 s, blockState.withConfiguration(configuration)); |
| 669 } | 677 } |
| 670 return configuration; | 678 return configuration; |
| 671 } | 679 } |
| 672 | 680 |
| 673 Configuration visitEmptyStatement(EmptyStatement node, state) { | 681 Configuration visitEmptyStatement(EmptyStatement node, State state) { |
| 674 return state.statementConfiguration; | 682 return state.statementConfiguration; |
| 675 } | 683 } |
| 676 | 684 |
| 677 Configuration visitIfStatement(IfStatement node, state) { | 685 Configuration visitIfStatement(IfStatement node, State state) { |
| 678 var expState = new ExpressionState.fromStatementState(state); | 686 var expState = new ExpressionState.fromStatementState(state); |
| 679 var cont = new IfConditionContinuation(node.then, node.otherwise, state); | 687 var cont = new IfConditionContinuation(node.then, node.otherwise, state); |
| 680 return new ExpressionConfiguration( | 688 return new ExpressionConfiguration( |
| 681 node.condition, expState.withContinuation(cont)); | 689 node.condition, expState.withContinuation(cont)); |
| 682 } | 690 } |
| 683 | 691 |
| 684 Configuration visitLabeledStatement(LabeledStatement node, state) { | 692 Configuration visitLabeledStatement(LabeledStatement node, State state) { |
| 685 return new StatementConfiguration(node.body, state.withBreak(node)); | 693 return new StatementConfiguration(node.body, state.withBreak(node)); |
| 686 } | 694 } |
| 687 | 695 |
| 688 Configuration visitBreakStatement(BreakStatement node, state) { | 696 Configuration visitBreakStatement(BreakStatement node, State state) { |
| 689 return state.lookupLabel(node.target).configuration; | 697 return state.lookupLabel(node.target).configuration; |
| 690 } | 698 } |
| 691 | 699 |
| 692 Configuration visitWhileStatement(WhileStatement node, state) { | 700 Configuration visitWhileStatement(WhileStatement node, State state) { |
| 693 var expState = new ExpressionState.fromStatementState(state); | 701 var expState = new ExpressionState.fromStatementState(state); |
| 694 var cont = new WhileConditionContinuation(node, state); | 702 var cont = new WhileConditionContinuation(node, state); |
| 695 | 703 |
| 696 return new ExpressionConfiguration( | 704 return new ExpressionConfiguration( |
| 697 node.condition, expState.withContinuation(cont)); | 705 node.condition, expState.withContinuation(cont)); |
| 698 } | 706 } |
| 699 | 707 |
| 700 Configuration visitDoStatement(DoStatement node, state) { | 708 Configuration visitDoStatement(DoStatement node, State state) { |
| 701 WhileStatement whileStatement = | 709 WhileStatement whileStatement = |
| 702 new WhileStatement(node.condition, node.body); | 710 new WhileStatement(node.condition, node.body); |
| 703 StatementConfiguration configuration = | 711 StatementConfiguration configuration = |
| 704 new StatementConfiguration(whileStatement, state); | 712 new StatementConfiguration(whileStatement, state); |
| 705 | 713 |
| 706 return new StatementConfiguration( | 714 return new StatementConfiguration( |
| 707 node.body, state.withConfiguration(configuration)); | 715 node.body, state.withConfiguration(configuration)); |
| 708 } | 716 } |
| 709 | 717 |
| 710 Configuration visitReturnStatement(ReturnStatement node, state) { | 718 Configuration visitReturnStatement(ReturnStatement node, State state) { |
| 711 assert(state.returnContinuation != null); | 719 assert(state.returnContinuation != null); |
| 712 // The new ExpressionState contains the next expression continuation. | 720 // The new ExpressionState contains the next expression continuation. |
| 713 var expState = new ExpressionState.fromStatementState(state) | 721 var expState = new ExpressionState.fromStatementState(state) |
| 714 .withContinuation(state.returnContinuation); | 722 .withContinuation(state.returnContinuation); |
| 715 return new ExpressionConfiguration( | 723 return new ExpressionConfiguration( |
| 716 node.expression ?? new NullLiteral(), expState); | 724 node.expression ?? new NullLiteral(), expState); |
| 717 } | 725 } |
| 718 | 726 |
| 719 Configuration visitVariableDeclaration(VariableDeclaration node, state) { | 727 Configuration visitVariableDeclaration( |
| 728 VariableDeclaration node, State state) { | |
| 720 if (node.initializer != null) { | 729 if (node.initializer != null) { |
| 721 var expState = new ExpressionState.fromStatementState(state); | 730 var expState = new ExpressionState.fromStatementState(state); |
| 722 var cont = new VariableInitializerContinuation( | 731 var cont = new VariableInitializerContinuation( |
| 723 node, state.environment, state.statementConfiguration); | 732 node, state.environment, state.statementConfiguration); |
| 724 return new ExpressionConfiguration( | 733 return new ExpressionConfiguration( |
| 725 node.initializer, expState.withContinuation(cont)); | 734 node.initializer, expState.withContinuation(cont)); |
| 726 } | 735 } |
| 727 state.environment.expand(node, Value.nullInstance); | 736 state.environment.expand(node, Value.nullInstance); |
| 728 return state.statementConfiguration; | 737 return state.statementConfiguration; |
| 729 } | 738 } |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 952 | 961 |
| 953 class NullValue extends LiteralValue { | 962 class NullValue extends LiteralValue { |
| 954 Object get value => null; | 963 Object get value => null; |
| 955 | 964 |
| 956 const NullValue(); | 965 const NullValue(); |
| 957 } | 966 } |
| 958 | 967 |
| 959 notImplemented({String m, Object obj}) { | 968 notImplemented({String m, Object obj}) { |
| 960 throw new NotImplemented(m ?? 'Evaluation for $obj is not implemented'); | 969 throw new NotImplemented(m ?? 'Evaluation for $obj is not implemented'); |
| 961 } | 970 } |
| OLD | NEW |