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

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

Issue 2833733003: Remove state for expression evaluation (Closed)
Patch Set: Rename variables 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 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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 }
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