| 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, ExpressionState> { | 78 class Evaluator |
| 79 Configuration eval(Expression expr, ExpressionState state) => | 79 extends ExpressionVisitor1<Configuration, ExpressionConfiguration> { |
| 80 expr.accept1(this, state); | 80 Configuration eval(Expression expr, ExpressionConfiguration config) => |
| 81 expr.accept1(this, config); |
| 81 | 82 |
| 82 Configuration defaultExpression(Expression node, ExpressionState state) { | 83 Configuration defaultExpression( |
| 84 Expression node, ExpressionConfiguration config) { |
| 83 throw new NotImplemented('Evaluation for expressions of type ' | 85 throw new NotImplemented('Evaluation for expressions of type ' |
| 84 '${node.runtimeType} is not implemented.'); | 86 '${node.runtimeType} is not implemented.'); |
| 85 } | 87 } |
| 86 | 88 |
| 87 Configuration visitInvalidExpression1( | 89 Configuration visitInvalidExpression1( |
| 88 InvalidExpression node, ExpressionState state) { | 90 InvalidExpression node, ExpressionConfiguration config) { |
| 89 throw 'Invalid expression at ${node.location.toString()}'; | 91 throw 'Invalid expression at ${node.location.toString()}'; |
| 90 } | 92 } |
| 91 | 93 |
| 92 Configuration visitVariableGet(VariableGet node, ExpressionState state) { | 94 Configuration visitVariableGet( |
| 93 Value value = state.environment.lookup(node.variable); | 95 VariableGet node, ExpressionConfiguration config) { |
| 94 return new ContinuationConfiguration(state.continuation, value); | 96 Value value = config.environment.lookup(node.variable); |
| 97 return new ContinuationConfiguration(config.continuation, value); |
| 95 } | 98 } |
| 96 | 99 |
| 97 Configuration visitVariableSet(VariableSet node, ExpressionState state) { | 100 Configuration visitVariableSet( |
| 98 var cont = new VariableSetContinuation(state, node.variable); | 101 VariableSet node, ExpressionConfiguration config) { |
| 99 return new ExpressionConfiguration( | 102 var cont = new VariableSetContinuation( |
| 100 node.value, state.withContinuation(cont)); | 103 node.variable, config.environment, config.continuation); |
| 104 return new ExpressionConfiguration(node.value, config.environment, cont); |
| 101 } | 105 } |
| 102 | 106 |
| 103 Configuration visitPropertyGet(PropertyGet node, ExpressionState state) { | 107 Configuration visitPropertyGet( |
| 104 var cont = new PropertyGetContinuation(node.name, state); | 108 PropertyGet node, ExpressionConfiguration config) { |
| 105 return new ExpressionConfiguration( | 109 var cont = new PropertyGetContinuation(node.name, config.continuation); |
| 106 node.receiver, state.withContinuation(cont)); | 110 return new ExpressionConfiguration(node.receiver, config.environment, cont); |
| 107 } | 111 } |
| 108 | 112 |
| 109 Configuration visitPropertySet(PropertySet node, ExpressionState state) { | 113 Configuration visitPropertySet( |
| 110 var cont = new PropertySetContinuation(node.value, node.name, state); | 114 PropertySet node, ExpressionConfiguration config) { |
| 111 return new ExpressionConfiguration( | 115 var cont = new PropertySetContinuation( |
| 112 node.receiver, state.withContinuation(cont)); | 116 node.value, node.name, config.environment, config.continuation); |
| 117 return new ExpressionConfiguration(node.receiver, config.environment, cont); |
| 113 } | 118 } |
| 114 | 119 |
| 115 Configuration visitStaticGet(StaticGet node, ExpressionState state) => | 120 Configuration visitStaticGet( |
| 116 defaultExpression(node, state); | 121 StaticGet node, ExpressionConfiguration config) => |
| 117 Configuration visitStaticSet(StaticSet node, ExpressionState state) => | 122 defaultExpression(node, config); |
| 118 defaultExpression(node, state); | 123 Configuration visitStaticSet( |
| 124 StaticSet node, ExpressionConfiguration config) => |
| 125 defaultExpression(node, config); |
| 119 | 126 |
| 120 Configuration visitStaticInvocation( | 127 Configuration visitStaticInvocation( |
| 121 StaticInvocation node, ExpressionState state) { | 128 StaticInvocation node, ExpressionConfiguration config) { |
| 122 if ('print' == node.name.toString()) { | 129 if ('print' == node.name.toString()) { |
| 123 return new ExpressionConfiguration(node.arguments.positional.first, | 130 var cont = new PrintContinuation(config.continuation); |
| 124 state.withContinuation(new PrintContinuation(state))); | 131 return new ExpressionConfiguration( |
| 132 node.arguments.positional.first, config.environment, cont); |
| 125 } else { | 133 } else { |
| 126 // Currently supports only static invocations with no arguments. | 134 // Currently supports only static invocations with no arguments. |
| 127 if (node.arguments.positional.isEmpty && node.arguments.named.isEmpty) { | 135 if (node.arguments.positional.isEmpty && node.arguments.named.isEmpty) { |
| 128 State statementState = new State.initial() | 136 State statementState = new State.initial() |
| 129 .withExpressionContinuation(state.continuation) | 137 .withExpressionContinuation(config.continuation) |
| 130 .withConfiguration(new ExitConfiguration(state.continuation)); | 138 .withConfiguration(new ExitConfiguration(config.continuation)); |
| 131 | 139 |
| 132 return new StatementConfiguration( | 140 return new StatementConfiguration( |
| 133 node.target.function.body, statementState); | 141 node.target.function.body, statementState); |
| 134 } | 142 } |
| 135 throw new NotImplemented( | 143 throw new NotImplemented( |
| 136 'Support for static invocation with arguments is not implemented'); | 144 'Support for static invocation with arguments is not implemented'); |
| 137 } | 145 } |
| 138 } | 146 } |
| 139 | 147 |
| 140 Configuration visitMethodInvocation( | 148 Configuration visitMethodInvocation( |
| 141 MethodInvocation node, ExpressionState state) { | 149 MethodInvocation node, ExpressionConfiguration config) { |
| 142 // Currently supports only method invocation with <2 arguments and is used | 150 // Currently supports only method invocation with <2 arguments and is used |
| 143 // to evaluate implemented operators for int, double and String values. | 151 // to evaluate implemented operators for int, double and String values. |
| 144 var cont = | 152 var cont = new MethodInvocationContinuation( |
| 145 new MethodInvocationContinuation(node.arguments, node.name, state); | 153 node.arguments, node.name, config.environment, config.continuation); |
| 146 | 154 |
| 147 return new ExpressionConfiguration( | 155 return new ExpressionConfiguration(node.receiver, config.environment, cont); |
| 148 node.receiver, state.withContinuation(cont)); | |
| 149 } | 156 } |
| 150 | 157 |
| 151 Configuration visitConstructorInvocation( | 158 Configuration visitConstructorInvocation( |
| 152 ConstructorInvocation node, ExpressionState state) { | 159 ConstructorInvocation node, ExpressionConfiguration config) { |
| 153 Class class_ = new Class(node.target.enclosingClass.reference); | 160 Class class_ = new Class(node.target.enclosingClass.reference); |
| 154 | 161 |
| 155 // Currently we don't support initializers. | 162 // Currently we don't support initializers. |
| 156 // TODO: Modify to respect dart semantics for initialization. | 163 // TODO: Modify to respect dart semantics for initialization. |
| 157 // 1. Init fields and eval initializers, repeat the same with super. | 164 // 1. Init fields and eval initializers, repeat the same with super. |
| 158 // 2. Eval the Function body of the constructor. | 165 // 2. Eval the Function body of the constructor. |
| 159 List<Value> fields = <Value>[]; | 166 List<Value> fields = <Value>[]; |
| 160 | 167 |
| 161 return new ContinuationConfiguration( | 168 return new ContinuationConfiguration( |
| 162 state.continuation, new ObjectValue(class_, fields)); | 169 config.continuation, new ObjectValue(class_, fields)); |
| 163 } | 170 } |
| 164 | 171 |
| 165 Configuration visitNot(Not node, ExpressionState state) { | 172 Configuration visitNot(Not node, ExpressionConfiguration config) { |
| 166 return new ExpressionConfiguration( | 173 return new ExpressionConfiguration(node.operand, config.environment, |
| 167 node.operand, state.withContinuation(new NotContinuation(state))); | 174 new NotContinuation(config.continuation)); |
| 168 } | 175 } |
| 169 | 176 |
| 170 Configuration visitLogicalExpression( | 177 Configuration visitLogicalExpression( |
| 171 LogicalExpression node, ExpressionState state) { | 178 LogicalExpression node, ExpressionConfiguration config) { |
| 172 if ('||' == node.operator) { | 179 if ('||' == node.operator) { |
| 173 var cont = new OrContinuation(node.right, state); | 180 var cont = new OrContinuation( |
| 174 return new ExpressionConfiguration( | 181 node.right, config.environment, config.continuation); |
| 175 node.left, state.withContinuation(cont)); | 182 return new ExpressionConfiguration(node.left, config.environment, cont); |
| 176 } else { | 183 } else { |
| 177 assert('&&' == node.operator); | 184 assert('&&' == node.operator); |
| 178 var cont = new AndContinuation(node.right, state); | 185 var cont = new AndContinuation( |
| 179 return new ExpressionConfiguration( | 186 node.right, config.environment, config.continuation); |
| 180 node.left, state.withContinuation(cont)); | 187 return new ExpressionConfiguration(node.left, config.environment, cont); |
| 181 } | 188 } |
| 182 } | 189 } |
| 183 | 190 |
| 184 Configuration visitConditionalExpression( | 191 Configuration visitConditionalExpression( |
| 185 ConditionalExpression node, ExpressionState state) { | 192 ConditionalExpression node, ExpressionConfiguration config) { |
| 186 var cont = new ConditionalContinuation(node.then, node.otherwise, state); | 193 var cont = new ConditionalContinuation( |
| 194 node.then, node.otherwise, config.environment, config.continuation); |
| 187 return new ExpressionConfiguration( | 195 return new ExpressionConfiguration( |
| 188 node.condition, state.withContinuation(cont)); | 196 node.condition, config.environment, cont); |
| 189 } | 197 } |
| 190 | 198 |
| 191 Configuration visitStringConcatenation( | 199 Configuration visitStringConcatenation( |
| 192 StringConcatenation node, ExpressionState state) { | 200 StringConcatenation node, ExpressionConfiguration config) { |
| 193 var cont = new StringConcatenationContinuation(node.expressions, state); | 201 var cont = new StringConcatenationContinuation( |
| 202 node.expressions, config.environment, config.continuation); |
| 194 return new ExpressionConfiguration( | 203 return new ExpressionConfiguration( |
| 195 node.expressions.first, state.withContinuation(cont)); | 204 node.expressions.first, config.environment, cont); |
| 196 } | 205 } |
| 197 | 206 |
| 198 // Evaluation of BasicLiterals. | 207 // Evaluation of BasicLiterals. |
| 199 Configuration visitStringLiteral(StringLiteral node, ExpressionState state) { | 208 Configuration visitStringLiteral( |
| 209 StringLiteral node, ExpressionConfiguration config) { |
| 200 return new ContinuationConfiguration( | 210 return new ContinuationConfiguration( |
| 201 state.continuation, new StringValue(node.value)); | 211 config.continuation, new StringValue(node.value)); |
| 202 } | 212 } |
| 203 | 213 |
| 204 Configuration visitIntLiteral(IntLiteral node, ExpressionState state) { | 214 Configuration visitIntLiteral( |
| 215 IntLiteral node, ExpressionConfiguration config) { |
| 205 return new ContinuationConfiguration( | 216 return new ContinuationConfiguration( |
| 206 state.continuation, new IntValue(node.value)); | 217 config.continuation, new IntValue(node.value)); |
| 207 } | 218 } |
| 208 | 219 |
| 209 Configuration visitDoubleLiteral(DoubleLiteral node, ExpressionState state) { | 220 Configuration visitDoubleLiteral( |
| 221 DoubleLiteral node, ExpressionConfiguration config) { |
| 210 return new ContinuationConfiguration( | 222 return new ContinuationConfiguration( |
| 211 state.continuation, new DoubleValue(node.value)); | 223 config.continuation, new DoubleValue(node.value)); |
| 212 } | 224 } |
| 213 | 225 |
| 214 Configuration visitBoolLiteral(BoolLiteral node, ExpressionState state) { | 226 Configuration visitBoolLiteral( |
| 227 BoolLiteral node, ExpressionConfiguration config) { |
| 215 Value value = node.value ? Value.trueInstance : Value.falseInstance; | 228 Value value = node.value ? Value.trueInstance : Value.falseInstance; |
| 216 return new ContinuationConfiguration(state.continuation, value); | 229 return new ContinuationConfiguration(config.continuation, value); |
| 217 } | 230 } |
| 218 | 231 |
| 219 Configuration visitNullLiteral(NullLiteral node, ExpressionState state) { | 232 Configuration visitNullLiteral( |
| 233 NullLiteral node, ExpressionConfiguration config) { |
| 220 return new ContinuationConfiguration( | 234 return new ContinuationConfiguration( |
| 221 state.continuation, Value.nullInstance); | 235 config.continuation, Value.nullInstance); |
| 222 } | 236 } |
| 223 | 237 |
| 224 Configuration visitLet(Let node, ExpressionState state) { | 238 Configuration visitLet(Let node, ExpressionConfiguration config) { |
| 225 var letCont = new LetContinuation(node.variable, node.body, state); | 239 var letCont = new LetContinuation( |
| 240 node.variable, node.body, config.environment, config.continuation); |
| 226 return new ExpressionConfiguration( | 241 return new ExpressionConfiguration( |
| 227 node.variable.initializer, state.withContinuation(letCont)); | 242 node.variable.initializer, config.environment, letCont); |
| 228 } | 243 } |
| 229 } | 244 } |
| 230 | 245 |
| 231 /// Represents a state for statement execution. | 246 /// Represents a state for statement execution. |
| 232 class State { | 247 class State { |
| 233 final Environment environment; | 248 final Environment environment; |
| 234 final Label labels; | 249 final Label labels; |
| 235 final StatementConfiguration statementConfiguration; | 250 final StatementConfiguration statementConfiguration; |
| 236 | 251 |
| 237 final ExpressionContinuation returnContinuation; | 252 final ExpressionContinuation returnContinuation; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 258 State withExpressionContinuation(ExpressionContinuation cont) { | 273 State withExpressionContinuation(ExpressionContinuation cont) { |
| 259 return new State(environment, labels, statementConfiguration, cont); | 274 return new State(environment, labels, statementConfiguration, cont); |
| 260 } | 275 } |
| 261 | 276 |
| 262 Label lookupLabel(LabeledStatement s) { | 277 Label lookupLabel(LabeledStatement s) { |
| 263 assert(labels != null); | 278 assert(labels != null); |
| 264 return labels.lookupLabel(s); | 279 return labels.lookupLabel(s); |
| 265 } | 280 } |
| 266 } | 281 } |
| 267 | 282 |
| 268 /// Represents a state for expression evaluation. | |
| 269 class ExpressionState { | |
| 270 /// Environment in which the expression is evaluated. | |
| 271 final Environment environment; | |
| 272 | |
| 273 /// Next continuation to be applied. | |
| 274 final ExpressionContinuation continuation; | |
| 275 | |
| 276 ExpressionState(this.environment, this.continuation); | |
| 277 | |
| 278 ExpressionState.fromStatementState(State state) | |
| 279 : this(state.environment, | |
| 280 new ExpressionStatementContinuation(state.statementConfiguration)); | |
| 281 | |
| 282 ExpressionState withEnvironment(Environment env) { | |
| 283 return new ExpressionState(env, continuation); | |
| 284 } | |
| 285 | |
| 286 ExpressionState withContinuation(ExpressionContinuation cont) { | |
| 287 return new ExpressionState(environment, cont); | |
| 288 } | |
| 289 } | |
| 290 | |
| 291 /// Represents a labeled statement, the corresponding continuation and the | 283 /// Represents a labeled statement, the corresponding continuation and the |
| 292 /// enclosing label. | 284 /// enclosing label. |
| 293 class Label { | 285 class Label { |
| 294 final LabeledStatement statement; | 286 final LabeledStatement statement; |
| 295 final StatementConfiguration configuration; | 287 final StatementConfiguration configuration; |
| 296 final Label enclosingLabel; | 288 final Label enclosingLabel; |
| 297 | 289 |
| 298 Label(this.statement, this.configuration, this.enclosingLabel); | 290 Label(this.statement, this.configuration, this.enclosingLabel); |
| 299 | 291 |
| 300 Label lookupLabel(LabeledStatement s) { | 292 Label lookupLabel(LabeledStatement s) { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 336 final Value value; | 328 final Value value; |
| 337 | 329 |
| 338 ContinuationConfiguration(this.continuation, this.value); | 330 ContinuationConfiguration(this.continuation, this.value); |
| 339 | 331 |
| 340 Configuration step(StatementExecuter executer) => continuation(value); | 332 Configuration step(StatementExecuter executer) => continuation(value); |
| 341 } | 333 } |
| 342 | 334 |
| 343 /// Represents the configuration for evaluating an [Expression]. | 335 /// Represents the configuration for evaluating an [Expression]. |
| 344 class ExpressionConfiguration extends Configuration { | 336 class ExpressionConfiguration extends Configuration { |
| 345 final Expression expression; | 337 final Expression expression; |
| 346 final ExpressionState state; | |
| 347 | 338 |
| 348 ExpressionConfiguration(this.expression, this.state); | 339 /// Environment in which the expression is evaluated. |
| 340 final Environment environment; |
| 341 |
| 342 /// Next continuation to be applied. |
| 343 final ExpressionContinuation continuation; |
| 344 |
| 345 ExpressionConfiguration(this.expression, this.environment, this.continuation); |
| 349 | 346 |
| 350 Configuration step(StatementExecuter executer) => | 347 Configuration step(StatementExecuter executer) => |
| 351 executer.eval(expression, state); | 348 executer.eval(expression, this); |
| 352 } | 349 } |
| 353 | 350 |
| 354 /// Represents an expression continuation. | 351 /// Represents an expression continuation. |
| 355 abstract class ExpressionContinuation { | 352 abstract class ExpressionContinuation { |
| 356 Configuration call(Value v); | 353 Configuration call(Value v); |
| 357 } | 354 } |
| 358 | 355 |
| 359 /// Represents a continuation that returns the next [StatementConfiguration] | 356 /// Represents a continuation that returns the next [StatementConfiguration] |
| 360 /// to be executed. | 357 /// to be executed. |
| 361 class ExpressionStatementContinuation extends ExpressionContinuation { | 358 class ExpressionStatementContinuation extends ExpressionContinuation { |
| 362 final StatementConfiguration configuration; | 359 final StatementConfiguration configuration; |
| 363 | 360 |
| 364 ExpressionStatementContinuation(this.configuration); | 361 ExpressionStatementContinuation(this.configuration); |
| 365 | 362 |
| 366 Configuration call(Value _) { | 363 Configuration call(Value _) { |
| 367 return configuration; | 364 return configuration; |
| 368 } | 365 } |
| 369 } | 366 } |
| 370 | 367 |
| 371 class PrintContinuation extends ExpressionContinuation { | 368 class PrintContinuation extends ExpressionContinuation { |
| 372 final ExpressionState state; | 369 final ExpressionContinuation continuation; |
| 373 | 370 |
| 374 PrintContinuation(this.state); | 371 PrintContinuation(this.continuation); |
| 375 | 372 |
| 376 Configuration call(Value v) { | 373 Configuration call(Value v) { |
| 377 print(v.value); | 374 print(v.value); |
| 378 return new ContinuationConfiguration( | 375 return new ContinuationConfiguration(continuation, Value.nullInstance); |
| 379 state.continuation, Value.nullInstance); | |
| 380 } | 376 } |
| 381 } | 377 } |
| 382 | 378 |
| 383 class PropertyGetContinuation extends ExpressionContinuation { | 379 class PropertyGetContinuation extends ExpressionContinuation { |
| 384 final Name name; | 380 final Name name; |
| 385 final ExpressionState state; | 381 final ExpressionContinuation continuation; |
| 386 | 382 |
| 387 PropertyGetContinuation(this.name, this.state); | 383 PropertyGetContinuation(this.name, this.continuation); |
| 388 | 384 |
| 389 Configuration call(Value receiver) { | 385 Configuration call(Value receiver) { |
| 390 // TODO: CPS the invocation of the getter. | 386 // TODO: CPS the invocation of the getter. |
| 391 Value propertyValue = receiver.class_.lookupGetter(name)(receiver); | 387 Value propertyValue = receiver.class_.lookupGetter(name)(receiver); |
| 392 return new ContinuationConfiguration(state.continuation, propertyValue); | 388 return new ContinuationConfiguration(continuation, propertyValue); |
| 393 } | 389 } |
| 394 } | 390 } |
| 395 | 391 |
| 396 class PropertySetContinuation extends ExpressionContinuation { | 392 class PropertySetContinuation extends ExpressionContinuation { |
| 397 final Expression value; | 393 final Expression value; |
| 398 final Name setterName; | 394 final Name setterName; |
| 399 final ExpressionState state; | 395 final Environment environment; |
| 396 final ExpressionContinuation continuation; |
| 400 | 397 |
| 401 PropertySetContinuation(this.value, this.setterName, this.state); | 398 PropertySetContinuation( |
| 399 this.value, this.setterName, this.environment, this.continuation); |
| 402 | 400 |
| 403 Configuration call(Value receiver) { | 401 Configuration call(Value receiver) { |
| 404 var cont = new SetterContinuation(receiver, setterName, state); | 402 var cont = new SetterContinuation(receiver, setterName, continuation); |
| 405 return new ExpressionConfiguration(value, state.withContinuation(cont)); | 403 return new ExpressionConfiguration(value, environment, cont); |
| 406 } | 404 } |
| 407 } | 405 } |
| 408 | 406 |
| 409 class SetterContinuation extends ExpressionContinuation { | 407 class SetterContinuation extends ExpressionContinuation { |
| 410 final Value receiver; | 408 final Value receiver; |
| 411 final Name name; | 409 final Name name; |
| 412 final ExpressionState state; | 410 final ExpressionContinuation continuation; |
| 413 | 411 |
| 414 SetterContinuation(this.receiver, this.name, this.state); | 412 SetterContinuation(this.receiver, this.name, this.continuation); |
| 415 | 413 |
| 416 Configuration call(Value v) { | 414 Configuration call(Value v) { |
| 417 Setter setter = receiver.class_.lookupSetter(name); | 415 Setter setter = receiver.class_.lookupSetter(name); |
| 418 setter(receiver, v); | 416 setter(receiver, v); |
| 419 return new ContinuationConfiguration(state.continuation, v); | 417 return new ContinuationConfiguration(continuation, v); |
| 420 } | 418 } |
| 421 } | 419 } |
| 422 | 420 |
| 423 class StaticInvocationContinuation extends ExpressionContinuation { | 421 class StaticInvocationContinuation extends ExpressionContinuation { |
| 424 final ExpressionState state; | 422 final ExpressionContinuation continuation; |
| 425 | 423 |
| 426 StaticInvocationContinuation(this.state); | 424 StaticInvocationContinuation(this.continuation); |
| 427 | 425 |
| 428 Configuration call(Value v) { | 426 Configuration call(Value v) { |
| 429 return new ContinuationConfiguration(state.continuation, v); | 427 return new ContinuationConfiguration(continuation, v); |
| 430 } | 428 } |
| 431 } | 429 } |
| 432 | 430 |
| 433 class MethodInvocationContinuation extends ExpressionContinuation { | 431 class MethodInvocationContinuation extends ExpressionContinuation { |
| 434 final Arguments arguments; | 432 final Arguments arguments; |
| 435 final Name methodName; | 433 final Name methodName; |
| 436 final ExpressionState state; | 434 final Environment environment; |
| 435 final ExpressionContinuation continuation; |
| 437 | 436 |
| 438 MethodInvocationContinuation(this.arguments, this.methodName, this.state); | 437 MethodInvocationContinuation( |
| 438 this.arguments, this.methodName, this.environment, this.continuation); |
| 439 | 439 |
| 440 Configuration call(Value receiver) { | 440 Configuration call(Value receiver) { |
| 441 if (arguments.positional.isEmpty) { | 441 if (arguments.positional.isEmpty) { |
| 442 Value returnValue = receiver.invokeMethod(methodName); | 442 Value returnValue = receiver.invokeMethod(methodName); |
| 443 return new ContinuationConfiguration(state.continuation, returnValue); | 443 return new ContinuationConfiguration(continuation, returnValue); |
| 444 } | 444 } |
| 445 var cont = | 445 var cont = new ArgumentsContinuation( |
| 446 new ArgumentsContinuation(receiver, methodName, arguments, state); | 446 receiver, methodName, arguments, environment, continuation); |
| 447 | 447 |
| 448 return new ExpressionConfiguration( | 448 return new ExpressionConfiguration( |
| 449 arguments.positional.first, state.withContinuation(cont)); | 449 arguments.positional.first, environment, cont); |
| 450 } | 450 } |
| 451 } | 451 } |
| 452 | 452 |
| 453 class ArgumentsContinuation extends ExpressionContinuation { | 453 class ArgumentsContinuation extends ExpressionContinuation { |
| 454 final Value receiver; | 454 final Value receiver; |
| 455 final Name methodName; | 455 final Name methodName; |
| 456 final Arguments arguments; | 456 final Arguments arguments; |
| 457 final ExpressionState state; | 457 final Environment environment; |
| 458 final ExpressionContinuation continuation; |
| 458 | 459 |
| 459 ArgumentsContinuation( | 460 ArgumentsContinuation(this.receiver, this.methodName, this.arguments, |
| 460 this.receiver, this.methodName, this.arguments, this.state); | 461 this.environment, this.continuation); |
| 461 | 462 |
| 462 Configuration call(Value value) { | 463 Configuration call(Value value) { |
| 463 // Currently evaluates only one argument, for simple method invocations | 464 // Currently evaluates only one argument, for simple method invocations |
| 464 // with 1 argument. | 465 // with 1 argument. |
| 465 Value returnValue = receiver.invokeMethod(methodName, value); | 466 Value returnValue = receiver.invokeMethod(methodName, value); |
| 466 return new ContinuationConfiguration(state.continuation, returnValue); | 467 return new ContinuationConfiguration(continuation, returnValue); |
| 467 } | 468 } |
| 468 } | 469 } |
| 469 | 470 |
| 470 class VariableSetContinuation extends ExpressionContinuation { | 471 class VariableSetContinuation extends ExpressionContinuation { |
| 471 final ExpressionState state; | |
| 472 final VariableDeclaration variable; | 472 final VariableDeclaration variable; |
| 473 final Environment environment; |
| 474 final ExpressionContinuation continuation; |
| 473 | 475 |
| 474 VariableSetContinuation(this.state, this.variable); | 476 VariableSetContinuation(this.variable, this.environment, this.continuation); |
| 475 | 477 |
| 476 Configuration call(Value value) { | 478 Configuration call(Value value) { |
| 477 state.environment.assign(variable, value); | 479 environment.assign(variable, value); |
| 478 return new ContinuationConfiguration(state.continuation, value); | 480 return new ContinuationConfiguration(continuation, value); |
| 479 } | 481 } |
| 480 } | 482 } |
| 481 | 483 |
| 482 class NotContinuation extends ExpressionContinuation { | 484 class NotContinuation extends ExpressionContinuation { |
| 483 final ExpressionState state; | 485 final ExpressionContinuation continuation; |
| 484 | 486 |
| 485 NotContinuation(this.state); | 487 NotContinuation(this.continuation); |
| 486 | 488 |
| 487 Configuration call(Value value) { | 489 Configuration call(Value value) { |
| 488 Value notValue = identical(Value.trueInstance, value) | 490 Value notValue = identical(Value.trueInstance, value) |
| 489 ? Value.falseInstance | 491 ? Value.falseInstance |
| 490 : Value.trueInstance; | 492 : Value.trueInstance; |
| 491 return new ContinuationConfiguration(state.continuation, notValue); | 493 return new ContinuationConfiguration(continuation, notValue); |
| 492 } | 494 } |
| 493 } | 495 } |
| 494 | 496 |
| 495 class OrContinuation extends ExpressionContinuation { | 497 class OrContinuation extends ExpressionContinuation { |
| 496 final Expression right; | 498 final Expression right; |
| 497 final ExpressionState state; | 499 final Environment environment; |
| 500 final ExpressionContinuation continuation; |
| 498 | 501 |
| 499 OrContinuation(this.right, this.state); | 502 OrContinuation(this.right, this.environment, this.continuation); |
| 500 | 503 |
| 501 Configuration call(Value left) { | 504 Configuration call(Value left) { |
| 502 return identical(Value.trueInstance, left) | 505 return identical(Value.trueInstance, left) |
| 503 ? new ContinuationConfiguration(state.continuation, Value.trueInstance) | 506 ? new ContinuationConfiguration(continuation, Value.trueInstance) |
| 504 : new ExpressionConfiguration(right, state); | 507 : new ExpressionConfiguration(right, environment, continuation); |
| 505 } | 508 } |
| 506 } | 509 } |
| 507 | 510 |
| 508 class AndContinuation extends ExpressionContinuation { | 511 class AndContinuation extends ExpressionContinuation { |
| 509 final Expression right; | 512 final Expression right; |
| 510 final ExpressionState state; | 513 final Environment environment; |
| 514 final ExpressionContinuation continuation; |
| 511 | 515 |
| 512 AndContinuation(this.right, this.state); | 516 AndContinuation(this.right, this.environment, this.continuation); |
| 513 | 517 |
| 514 Configuration call(Value left) { | 518 Configuration call(Value left) { |
| 515 return identical(Value.falseInstance, left) | 519 return identical(Value.falseInstance, left) |
| 516 ? new ContinuationConfiguration(state.continuation, Value.falseInstance) | 520 ? new ContinuationConfiguration(continuation, Value.falseInstance) |
| 517 : new ExpressionConfiguration(right, state); | 521 : new ExpressionConfiguration(right, environment, continuation); |
| 518 } | 522 } |
| 519 } | 523 } |
| 520 | 524 |
| 521 class ConditionalContinuation extends ExpressionContinuation { | 525 class ConditionalContinuation extends ExpressionContinuation { |
| 522 final Expression then; | 526 final Expression then; |
| 523 final Expression otherwise; | 527 final Expression otherwise; |
| 524 final ExpressionState state; | 528 final Environment environment; |
| 529 final ExpressionContinuation continuation; |
| 525 | 530 |
| 526 ConditionalContinuation(this.then, this.otherwise, this.state); | 531 ConditionalContinuation( |
| 532 this.then, this.otherwise, this.environment, this.continuation); |
| 527 | 533 |
| 528 Configuration call(Value value) { | 534 Configuration call(Value value) { |
| 529 return identical(Value.trueInstance, value) | 535 return identical(Value.trueInstance, value) |
| 530 ? new ExpressionConfiguration(then, state) | 536 ? new ExpressionConfiguration(then, environment, continuation) |
| 531 : new ExpressionConfiguration(otherwise, state); | 537 : new ExpressionConfiguration(otherwise, environment, continuation); |
| 532 } | 538 } |
| 533 } | 539 } |
| 534 | 540 |
| 535 class StringConcatenationContinuation extends ExpressionContinuation { | 541 class StringConcatenationContinuation extends ExpressionContinuation { |
| 536 final List<Expression> expressions; | 542 final List<Expression> expressions; |
| 537 final ExpressionState state; | 543 final Environment environment; |
| 544 final ExpressionContinuation continuation; |
| 538 | 545 |
| 539 int _currentPosition = 0; | 546 int _currentPosition = 0; |
| 540 final List<Value> _values = <Value>[]; | 547 final List<Value> _values = <Value>[]; |
| 541 | 548 |
| 542 StringConcatenationContinuation(this.expressions, this.state); | 549 StringConcatenationContinuation( |
| 550 this.expressions, this.environment, this.continuation); |
| 543 | 551 |
| 544 Configuration call(Value value) { | 552 Configuration call(Value value) { |
| 545 _values.add(value); | 553 _values.add(value); |
| 546 if (_values.length == expressions.length) { | 554 if (_values.length == expressions.length) { |
| 547 StringBuffer res = new StringBuffer(); | 555 StringBuffer res = new StringBuffer(); |
| 548 | 556 |
| 549 for (int i = 0; i < expressions.length; i++) { | 557 for (int i = 0; i < expressions.length; i++) { |
| 550 res.write(_values[i].value); | 558 res.write(_values[i].value); |
| 551 } | 559 } |
| 552 | 560 |
| 553 Value value = new StringValue(res.toString()); | 561 Value value = new StringValue(res.toString()); |
| 554 return new ContinuationConfiguration(state.continuation, value); | 562 return new ContinuationConfiguration(continuation, value); |
| 555 } | 563 } |
| 556 return new ExpressionConfiguration( | 564 return new ExpressionConfiguration( |
| 557 expressions[++_currentPosition], state.withContinuation(this)); | 565 expressions[++_currentPosition], environment, this); |
| 558 } | 566 } |
| 559 } | 567 } |
| 560 | 568 |
| 561 class LetContinuation extends ExpressionContinuation { | 569 class LetContinuation extends ExpressionContinuation { |
| 562 final VariableDeclaration variable; | 570 final VariableDeclaration variable; |
| 563 final Expression letBody; | 571 final Expression letBody; |
| 564 final ExpressionState state; | 572 final Environment environment; |
| 573 final ExpressionContinuation continuation; |
| 565 | 574 |
| 566 LetContinuation(this.variable, this.letBody, this.state); | 575 LetContinuation( |
| 576 this.variable, this.letBody, this.environment, this.continuation); |
| 567 | 577 |
| 568 Configuration call(Value value) { | 578 Configuration call(Value value) { |
| 569 var letState = state.withEnvironment(new Environment(state.environment)); | 579 var letEnv = new Environment(environment); |
| 570 letState.environment.expand(variable, value); | 580 letEnv.expand(variable, value); |
| 571 return new ExpressionConfiguration(letBody, letState); | 581 return new ExpressionConfiguration(letBody, letEnv, continuation); |
| 572 } | 582 } |
| 573 } | 583 } |
| 574 | 584 |
| 575 /// Represents the continuation for the condition expression in [WhileStatement]
. | 585 /// Represents the continuation for the condition expression in [WhileStatement]
. |
| 576 class WhileConditionContinuation extends ExpressionContinuation { | 586 class WhileConditionContinuation extends ExpressionContinuation { |
| 577 final WhileStatement node; | 587 final WhileStatement node; |
| 578 final State state; | 588 final State state; |
| 579 | 589 |
| 580 WhileConditionContinuation(this.node, this.state); | 590 WhileConditionContinuation(this.node, this.state); |
| 581 | 591 |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 639 Evaluator evaluator = new Evaluator(); | 649 Evaluator evaluator = new Evaluator(); |
| 640 | 650 |
| 641 void trampolinedExecution(Configuration configuration) { | 651 void trampolinedExecution(Configuration configuration) { |
| 642 while (configuration != null) { | 652 while (configuration != null) { |
| 643 configuration = configuration.step(this); | 653 configuration = configuration.step(this); |
| 644 } | 654 } |
| 645 } | 655 } |
| 646 | 656 |
| 647 Configuration exec(Statement statement, State state) => | 657 Configuration exec(Statement statement, State state) => |
| 648 statement.accept1(this, state); | 658 statement.accept1(this, state); |
| 649 Configuration eval(Expression expression, ExpressionState state) => | 659 Configuration eval(Expression expression, ExpressionConfiguration config) => |
| 650 evaluator.eval(expression, state); | 660 evaluator.eval(expression, config); |
| 651 | 661 |
| 652 Configuration defaultStatement(Statement node, State state) { | 662 Configuration defaultStatement(Statement node, State state) { |
| 653 throw notImplemented( | 663 throw notImplemented( |
| 654 m: "Execution is not implemented for statement:\n$node "); | 664 m: "Execution is not implemented for statement:\n$node "); |
| 655 } | 665 } |
| 656 | 666 |
| 657 Configuration visitInvalidStatement(InvalidStatement node, State state) { | 667 Configuration visitInvalidStatement(InvalidStatement node, State state) { |
| 658 throw "Invalid statement at ${node.location}"; | 668 throw "Invalid statement at ${node.location}"; |
| 659 } | 669 } |
| 660 | 670 |
| 661 Configuration visitExpressionStatement( | 671 Configuration visitExpressionStatement( |
| 662 ExpressionStatement node, State state) { | 672 ExpressionStatement node, State state) { |
| 673 var cont = |
| 674 new ExpressionStatementContinuation(state.statementConfiguration); |
| 663 return new ExpressionConfiguration( | 675 return new ExpressionConfiguration( |
| 664 node.expression, new ExpressionState.fromStatementState(state)); | 676 node.expression, state.environment, cont); |
| 665 } | 677 } |
| 666 | 678 |
| 667 Configuration visitBlock(Block node, State state) { | 679 Configuration visitBlock(Block node, State state) { |
| 668 if (node.statements.isEmpty) { | 680 if (node.statements.isEmpty) { |
| 669 return state.statementConfiguration; | 681 return state.statementConfiguration; |
| 670 } | 682 } |
| 671 State blockState = | 683 State blockState = |
| 672 state.withEnvironment(new Environment(state.environment)); | 684 state.withEnvironment(new Environment(state.environment)); |
| 673 StatementConfiguration configuration = state.statementConfiguration; | 685 StatementConfiguration configuration = state.statementConfiguration; |
| 674 for (Statement s in node.statements.reversed) { | 686 for (Statement s in node.statements.reversed) { |
| 675 configuration = new StatementConfiguration( | 687 configuration = new StatementConfiguration( |
| 676 s, blockState.withConfiguration(configuration)); | 688 s, blockState.withConfiguration(configuration)); |
| 677 } | 689 } |
| 678 return configuration; | 690 return configuration; |
| 679 } | 691 } |
| 680 | 692 |
| 681 Configuration visitEmptyStatement(EmptyStatement node, State state) { | 693 Configuration visitEmptyStatement(EmptyStatement node, State state) { |
| 682 return state.statementConfiguration; | 694 return state.statementConfiguration; |
| 683 } | 695 } |
| 684 | 696 |
| 685 Configuration visitIfStatement(IfStatement node, State state) { | 697 Configuration visitIfStatement(IfStatement node, State state) { |
| 686 var expState = new ExpressionState.fromStatementState(state); | |
| 687 var cont = new IfConditionContinuation(node.then, node.otherwise, state); | 698 var cont = new IfConditionContinuation(node.then, node.otherwise, state); |
| 688 return new ExpressionConfiguration( | 699 |
| 689 node.condition, expState.withContinuation(cont)); | 700 return new ExpressionConfiguration(node.condition, state.environment, cont); |
| 690 } | 701 } |
| 691 | 702 |
| 692 Configuration visitLabeledStatement(LabeledStatement node, State state) { | 703 Configuration visitLabeledStatement(LabeledStatement node, State state) { |
| 693 return new StatementConfiguration(node.body, state.withBreak(node)); | 704 return new StatementConfiguration(node.body, state.withBreak(node)); |
| 694 } | 705 } |
| 695 | 706 |
| 696 Configuration visitBreakStatement(BreakStatement node, State state) { | 707 Configuration visitBreakStatement(BreakStatement node, State state) { |
| 697 return state.lookupLabel(node.target).configuration; | 708 return state.lookupLabel(node.target).configuration; |
| 698 } | 709 } |
| 699 | 710 |
| 700 Configuration visitWhileStatement(WhileStatement node, State state) { | 711 Configuration visitWhileStatement(WhileStatement node, State state) { |
| 701 var expState = new ExpressionState.fromStatementState(state); | |
| 702 var cont = new WhileConditionContinuation(node, state); | 712 var cont = new WhileConditionContinuation(node, state); |
| 703 | 713 |
| 704 return new ExpressionConfiguration( | 714 return new ExpressionConfiguration(node.condition, state.environment, cont); |
| 705 node.condition, expState.withContinuation(cont)); | |
| 706 } | 715 } |
| 707 | 716 |
| 708 Configuration visitDoStatement(DoStatement node, State state) { | 717 Configuration visitDoStatement(DoStatement node, State state) { |
| 709 WhileStatement whileStatement = | 718 WhileStatement whileStatement = |
| 710 new WhileStatement(node.condition, node.body); | 719 new WhileStatement(node.condition, node.body); |
| 711 StatementConfiguration configuration = | 720 StatementConfiguration configuration = |
| 712 new StatementConfiguration(whileStatement, state); | 721 new StatementConfiguration(whileStatement, state); |
| 713 | 722 |
| 714 return new StatementConfiguration( | 723 return new StatementConfiguration( |
| 715 node.body, state.withConfiguration(configuration)); | 724 node.body, state.withConfiguration(configuration)); |
| 716 } | 725 } |
| 717 | 726 |
| 718 Configuration visitReturnStatement(ReturnStatement node, State state) { | 727 Configuration visitReturnStatement(ReturnStatement node, State state) { |
| 719 assert(state.returnContinuation != null); | 728 assert(state.returnContinuation != null); |
| 720 // The new ExpressionState contains the next expression continuation. | 729 if (node.expression == null) { |
| 721 var expState = new ExpressionState.fromStatementState(state) | 730 return new ContinuationConfiguration( |
| 722 .withContinuation(state.returnContinuation); | 731 state.returnContinuation, Value.nullInstance); |
| 732 } |
| 733 |
| 723 return new ExpressionConfiguration( | 734 return new ExpressionConfiguration( |
| 724 node.expression ?? new NullLiteral(), expState); | 735 node.expression, state.environment, state.returnContinuation); |
| 725 } | 736 } |
| 726 | 737 |
| 727 Configuration visitVariableDeclaration( | 738 Configuration visitVariableDeclaration( |
| 728 VariableDeclaration node, State state) { | 739 VariableDeclaration node, State state) { |
| 729 if (node.initializer != null) { | 740 if (node.initializer != null) { |
| 730 var expState = new ExpressionState.fromStatementState(state); | |
| 731 var cont = new VariableInitializerContinuation( | 741 var cont = new VariableInitializerContinuation( |
| 732 node, state.environment, state.statementConfiguration); | 742 node, state.environment, state.statementConfiguration); |
| 733 return new ExpressionConfiguration( | 743 return new ExpressionConfiguration( |
| 734 node.initializer, expState.withContinuation(cont)); | 744 node.initializer, state.environment, cont); |
| 735 } | 745 } |
| 736 state.environment.expand(node, Value.nullInstance); | 746 state.environment.expand(node, Value.nullInstance); |
| 737 return state.statementConfiguration; | 747 return state.statementConfiguration; |
| 738 } | 748 } |
| 739 } | 749 } |
| 740 | 750 |
| 741 // ------------------------------------------------------------------------ | 751 // ------------------------------------------------------------------------ |
| 742 // VALUES | 752 // VALUES |
| 743 // ------------------------------------------------------------------------ | 753 // ------------------------------------------------------------------------ |
| 744 | 754 |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 961 | 971 |
| 962 class NullValue extends LiteralValue { | 972 class NullValue extends LiteralValue { |
| 963 Object get value => null; | 973 Object get value => null; |
| 964 | 974 |
| 965 const NullValue(); | 975 const NullValue(); |
| 966 } | 976 } |
| 967 | 977 |
| 968 notImplemented({String m, Object obj}) { | 978 notImplemented({String m, Object obj}) { |
| 969 throw new NotImplemented(m ?? 'Evaluation for $obj is not implemented'); | 979 throw new NotImplemented(m ?? 'Evaluation for $obj is not implemented'); |
| 970 } | 980 } |
| OLD | NEW |