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

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

Issue 2975173002: Introduce statement continuations following the specification (Closed)
Patch Set: Apply review comments Created 3 years, 5 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 | pkg/kernel/test/interpreter/interpreter.status » ('j') | 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 import '../log.dart'; 9 import '../log.dart';
10 export '../log.dart'; 10 export '../log.dart';
(...skipping 12 matching lines...) Expand all
23 23
24 Interpreter(this.program); 24 Interpreter(this.program);
25 25
26 void run() { 26 void run() {
27 assert(program.libraries.isEmpty); 27 assert(program.libraries.isEmpty);
28 Procedure mainMethod = program.mainMethod; 28 Procedure mainMethod = program.mainMethod;
29 29
30 if (mainMethod == null) return; 30 if (mainMethod == null) return;
31 31
32 Statement statementBlock = mainMethod.function.body; 32 Statement statementBlock = mainMethod.function.body;
33 ExecConfiguration configuration = 33 ExecConfiguration configuration = new ExecConfiguration(
34 new ExecConfiguration(statementBlock, new State.initial()); 34 statementBlock, new Environment.empty(), const State.initial());
35 visitor.trampolinedExecution(configuration); 35 visitor.trampolinedExecution(configuration);
36 } 36 }
37 } 37 }
38 38
39 class Location { 39 class Location {
40 Value value; 40 Value value;
41 41
42 Location(this.value); 42 Location(this.value);
43 } 43 }
44 44
45 class Binding { 45 class Binding {
46 final VariableDeclaration variable; 46 final VariableDeclaration variable;
47 final Location location; 47 final Location location;
48 48
49 Binding(this.variable, this.location); 49 Binding(this.variable, this.location);
50 } 50 }
51 51
52 class Environment { 52 class Environment {
53 final List<Binding> bindings = <Binding>[]; 53 final List<Binding> bindings = <Binding>[];
54 final Environment parent; 54 final Environment parent;
55 55
56 Value get thisInstance => (parent != null)
57 ? parent.thisInstance
58 : throw "Invalid reference to 'this' expression";
59
60 Environment.empty() : parent = null; 56 Environment.empty() : parent = null;
61 Environment(this.parent); 57 Environment(this.parent);
62 58
63 bool contains(VariableDeclaration variable) { 59 bool contains(VariableDeclaration variable) {
64 for (Binding b in bindings.reversed) { 60 for (Binding b in bindings.reversed) {
65 if (identical(b.variable, variable)) return true; 61 if (identical(b.variable, variable)) return true;
66 } 62 }
67 return parent?.contains(variable) ?? false; 63 return parent?.contains(variable) ?? false;
68 } 64 }
69 65
70 Binding lookupBinding(VariableDeclaration variable) { 66 Binding lookupBinding(VariableDeclaration variable) {
71 assert(contains(variable)); 67 assert(contains(variable));
72 for (Binding b in bindings) { 68 for (Binding b in bindings) {
73 if (identical(b.variable, variable)) return b; 69 if (identical(b.variable, variable)) return b;
74 } 70 }
75 return parent.lookupBinding(variable); 71 return parent.lookupBinding(variable);
76 } 72 }
77 73
78 Value lookup(VariableDeclaration variable) { 74 Value lookup(VariableDeclaration variable) {
79 return lookupBinding(variable).location.value; 75 return lookupBinding(variable).location.value;
80 } 76 }
81 77
82 void assign(VariableDeclaration variable, Value value) { 78 void assign(VariableDeclaration variable, Value value) {
83 assert(contains(variable)); 79 assert(contains(variable));
84 lookupBinding(variable).location.value = value; 80 lookupBinding(variable).location.value = value;
85 } 81 }
86 82
87 void expand(VariableDeclaration variable, Value value) { 83 Environment extend(VariableDeclaration variable, Value value) {
88 assert(!contains(variable)); 84 assert(!contains(variable));
89 bindings.add(new Binding(variable, new Location(value))); 85 return new Environment(this)
86 ..bindings.add(new Binding(variable, new Location(value)));
90 } 87 }
91 } 88 }
92 89
93 class InstanceEnvironment extends Environment {
94 final ObjectValue _thisInstance;
95 Value get thisInstance => _thisInstance;
96
97 InstanceEnvironment(this._thisInstance, Environment env) : super(env);
98 }
99
100 /// Evaluate expressions. 90 /// Evaluate expressions.
101 class Evaluator extends ExpressionVisitor1<Configuration, EvalConfiguration> { 91 class Evaluator extends ExpressionVisitor1<Configuration, EvalConfiguration> {
102 Configuration eval(Expression expr, EvalConfiguration config) => 92 Configuration eval(Expression expr, EvalConfiguration config) =>
103 expr.accept1(this, config); 93 expr.accept1(this, config);
104 94
105 Configuration evalList(List<InterpreterExpression> list, Environment env, 95 Configuration evalList(List<InterpreterExpression> list, Environment env,
106 ApplicationContinuation cont) { 96 ApplicationContinuation cont) {
107 if (list.isNotEmpty) { 97 if (list.isNotEmpty) {
108 return new EvalConfiguration(list.first.expression, env, 98 return new EvalConfiguration(list.first.expression, env,
109 new ExpressionListEK(list.first, list.skip(1), env, cont)); 99 new ExpressionListEK(list.first, list.skip(1), env, cont));
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 135
146 Configuration visitStaticGet(StaticGet node, EvalConfiguration config) => 136 Configuration visitStaticGet(StaticGet node, EvalConfiguration config) =>
147 defaultExpression(node, config); 137 defaultExpression(node, config);
148 Configuration visitStaticSet(StaticSet node, EvalConfiguration config) => 138 Configuration visitStaticSet(StaticSet node, EvalConfiguration config) =>
149 defaultExpression(node, config); 139 defaultExpression(node, config);
150 140
151 Configuration visitStaticInvocation( 141 Configuration visitStaticInvocation(
152 StaticInvocation node, EvalConfiguration config) { 142 StaticInvocation node, EvalConfiguration config) {
153 if ('print' == node.name.toString()) { 143 if ('print' == node.name.toString()) {
154 var cont = new PrintEK(config.continuation); 144 var cont = new PrintEK(config.continuation);
155
156 return new EvalConfiguration( 145 return new EvalConfiguration(
157 node.arguments.positional.first, config.environment, cont); 146 node.arguments.positional.first, config.environment, cont);
158 } else { 147 } else {
159 log.info('static-invocation-${node.target.name.toString()}\n'); 148 log.info('static-invocation-${node.target.name.toString()}\n');
160 149
161 List<InterpreterExpression> args = 150 List<InterpreterExpression> args =
162 _createArgumentExpressionList(node.arguments, node.target.function); 151 _createArgumentExpressionList(node.arguments, node.target.function);
163 ApplicationContinuation cont = 152 ApplicationContinuation cont =
164 new StaticInvocationA(node.target.function, config.continuation); 153 new StaticInvocationA(node.target.function, config.continuation);
165
166 return new EvalListConfiguration(args, config.environment, cont); 154 return new EvalListConfiguration(args, config.environment, cont);
167 } 155 }
168 } 156 }
169 157
170 Configuration visitMethodInvocation( 158 Configuration visitMethodInvocation(
171 MethodInvocation node, EvalConfiguration config) { 159 MethodInvocation node, EvalConfiguration config) {
172 // Currently supports only method invocation with <2 arguments and is used 160 // Currently supports only method invocation with <2 arguments and is used
173 // to evaluate implemented operators for int, double and String values. 161 // to evaluate implemented operators for int, double and String values.
174 var cont = new MethodInvocationEK( 162 var cont = new MethodInvocationEK(
175 node.arguments, node.name, config.environment, config.continuation); 163 node.arguments, node.name, config.environment, config.continuation);
176 164
177 return new EvalConfiguration(node.receiver, config.environment, cont); 165 return new EvalConfiguration(node.receiver, config.environment, cont);
178 } 166 }
179 167
180 Configuration visitConstructorInvocation( 168 Configuration visitConstructorInvocation(
181 ConstructorInvocation node, EvalConfiguration config) { 169 ConstructorInvocation node, EvalConfiguration config) =>
182 ApplicationContinuation cont = 170 defaultExpression(node, config);
183 new ConstructorInvocationA(node.target, config.continuation);
184 var args =
185 _createArgumentExpressionList(node.arguments, node.target.function);
186
187 return new EvalListConfiguration(args, config.environment, cont);
188 }
189 171
190 Configuration visitNot(Not node, EvalConfiguration config) { 172 Configuration visitNot(Not node, EvalConfiguration config) {
191 return new EvalConfiguration( 173 return new EvalConfiguration(
192 node.operand, config.environment, new NotEK(config.continuation)); 174 node.operand, config.environment, new NotEK(config.continuation));
193 } 175 }
194 176
195 Configuration visitLogicalExpression( 177 Configuration visitLogicalExpression(
196 LogicalExpression node, EvalConfiguration config) { 178 LogicalExpression node, EvalConfiguration config) {
197 if ('||' == node.operator) { 179 if ('||' == node.operator) {
198 var cont = new OrEK(node.right, config.environment, config.continuation); 180 var cont = new OrEK(node.right, config.environment, config.continuation);
(...skipping 15 matching lines...) Expand all
214 Configuration visitStringConcatenation( 196 Configuration visitStringConcatenation(
215 StringConcatenation node, EvalConfiguration config) { 197 StringConcatenation node, EvalConfiguration config) {
216 var cont = new StringConcatenationA(config.continuation); 198 var cont = new StringConcatenationA(config.continuation);
217 var expressions = node.expressions 199 var expressions = node.expressions
218 .map((Expression e) => new PositionalExpression(e)) 200 .map((Expression e) => new PositionalExpression(e))
219 .toList(); 201 .toList();
220 return new EvalListConfiguration(expressions, config.environment, cont); 202 return new EvalListConfiguration(expressions, config.environment, cont);
221 } 203 }
222 204
223 Configuration visitThisExpression( 205 Configuration visitThisExpression(
224 ThisExpression node, EvalConfiguration config) { 206 ThisExpression node, EvalConfiguration config) =>
225 return new ValuePassingConfiguration( 207 defaultExpression(node, config);
226 config.continuation, config.environment.thisInstance);
227 }
228 208
229 // Evaluation of BasicLiterals. 209 // Evaluation of BasicLiterals.
230 Configuration visitStringLiteral( 210 Configuration visitStringLiteral(
231 StringLiteral node, EvalConfiguration config) { 211 StringLiteral node, EvalConfiguration config) {
232 return new ValuePassingConfiguration( 212 return new ValuePassingConfiguration(
233 config.continuation, new StringValue(node.value)); 213 config.continuation, new StringValue(node.value));
234 } 214 }
235 215
236 Configuration visitIntLiteral(IntLiteral node, EvalConfiguration config) { 216 Configuration visitIntLiteral(IntLiteral node, EvalConfiguration config) {
237 return new ValuePassingConfiguration( 217 return new ValuePassingConfiguration(
(...skipping 19 matching lines...) Expand all
257 Configuration visitLet(Let node, EvalConfiguration config) { 237 Configuration visitLet(Let node, EvalConfiguration config) {
258 var letCont = new LetEK( 238 var letCont = new LetEK(
259 node.variable, node.body, config.environment, config.continuation); 239 node.variable, node.body, config.environment, config.continuation);
260 return new EvalConfiguration( 240 return new EvalConfiguration(
261 node.variable.initializer, config.environment, letCont); 241 node.variable.initializer, config.environment, letCont);
262 } 242 }
263 } 243 }
264 244
265 /// Represents a state for statement execution. 245 /// Represents a state for statement execution.
266 class State { 246 class State {
267 final Environment environment;
268 final Label labels; 247 final Label labels;
269 final ExecConfiguration statementConfiguration; 248 // TODO: Add switch labels.
249 // TODO: Add component for exception support.
250 final ExpressionContinuation returnContinuation;
251 final StatementContinuation continuation;
270 252
271 final ExpressionContinuation returnContinuation; 253 State(this.labels, this.returnContinuation, this.continuation);
272 254
273 State(this.environment, this.labels, this.statementConfiguration, 255 const State.initial()
274 this.returnContinuation); 256 : labels = null,
257 returnContinuation = null,
258 continuation = null;
275 259
276 State.initial() : this(new Environment.empty(), null, null, null); 260 State withBreak(Statement stmt, Environment env) {
277 261 Label breakLabels = new Label(stmt, env, continuation, labels);
278 State withEnvironment(Environment env) { 262 return new State(breakLabels, returnContinuation, continuation);
279 return new State(env, labels, statementConfiguration, returnContinuation);
280 } 263 }
281 264
282 State withBreak(Statement stmt) { 265 State withReturnContinuation(ExpressionContinuation returnCont) {
283 Label breakLabels = new Label(stmt, statementConfiguration, labels); 266 return new State(labels, returnCont, continuation);
284 return new State(
285 environment, breakLabels, statementConfiguration, returnContinuation);
286 } 267 }
287 268
288 State withConfiguration(Configuration config) { 269 State withContinuation(StatementContinuation cont) {
289 return new State(environment, labels, config, returnContinuation); 270 return new State(labels, returnContinuation, cont);
290 }
291
292 State withExpressionContinuation(ExpressionContinuation cont) {
293 return new State(environment, labels, statementConfiguration, cont);
294 } 271 }
295 272
296 Label lookupLabel(LabeledStatement s) { 273 Label lookupLabel(LabeledStatement s) {
297 assert(labels != null); 274 assert(labels != null);
298 return labels.lookupLabel(s); 275 return labels.lookupLabel(s);
299 } 276 }
300 } 277 }
301 278
302 /// Represents a labeled statement, the corresponding continuation and the 279 /// Represents a labeled statement, the corresponding continuation and the
303 /// enclosing label. 280 /// enclosing label.
304 class Label { 281 class Label {
305 final LabeledStatement statement; 282 final LabeledStatement statement;
306 final ExecConfiguration configuration; 283 final Environment environment;
284 final StatementContinuation continuation;
307 final Label enclosingLabel; 285 final Label enclosingLabel;
308 286
309 Label(this.statement, this.configuration, this.enclosingLabel); 287 Label(
288 this.statement, this.environment, this.continuation, this.enclosingLabel);
310 289
311 Label lookupLabel(LabeledStatement s) { 290 Label lookupLabel(LabeledStatement s) {
312 if (identical(s, statement)) return this; 291 if (identical(s, statement)) return this;
313 assert(enclosingLabel != null); 292 assert(enclosingLabel != null);
314 return enclosingLabel.lookupLabel(s); 293 return enclosingLabel.lookupLabel(s);
315 } 294 }
316 } 295 }
317 296
318 // ------------------------------------------------------------------------ 297 // ------------------------------------------------------------------------
319 // Configurations 298 // Configurations
320 // ------------------------------------------------------------------------ 299 // ------------------------------------------------------------------------
321 300
322 abstract class Configuration { 301 abstract class Configuration {
323 /// Executes the current and returns the next configuration. 302 /// Executes the current and returns the next configuration.
324 Configuration step(StatementExecuter executer); 303 Configuration step(StatementExecuter executer);
325 } 304 }
326 305
327 /// Represents the configuration for evaluating an [Expression]. 306 /// Configuration for evaluating an [Expression].
328 class EvalConfiguration extends Configuration { 307 class EvalConfiguration extends Configuration {
329 final Expression expression; 308 final Expression expression;
330 309
331 /// Environment in which the expression is evaluated. 310 /// Environment in which the expression is evaluated.
332 final Environment environment; 311 final Environment environment;
333 312
334 /// Next continuation to be applied. 313 /// Next continuation to be applied.
335 final Continuation continuation; 314 final Continuation continuation;
336 315
337 EvalConfiguration(this.expression, this.environment, this.continuation); 316 EvalConfiguration(this.expression, this.environment, this.continuation);
338 317
339 Configuration step(StatementExecuter executer) => 318 Configuration step(StatementExecuter executer) =>
340 executer.eval(expression, this); 319 executer.eval(expression, this);
341 } 320 }
342 321
343 /// Represents the configuration for evaluating a list of expressions. 322 /// Configuration for evaluating a `List<InterpreterExpression>`.
344 class EvalListConfiguration extends Configuration { 323 class EvalListConfiguration extends Configuration {
345 final List<InterpreterExpression> expressions; 324 final List<InterpreterExpression> expressions;
346 final Environment environment; 325 final Environment environment;
347 final Continuation continuation; 326 final ApplicationContinuation continuation;
348 327
349 EvalListConfiguration(this.expressions, this.environment, this.continuation); 328 EvalListConfiguration(this.expressions, this.environment, this.continuation);
350 329
351 Configuration step(StatementExecuter executer) => 330 Configuration step(StatementExecuter executer) =>
352 executer.evalList(expressions, environment, continuation); 331 executer.evalList(expressions, environment, continuation);
353 } 332 }
354 333
355 /// Represents the configuration for execution of statement. 334 /// Configuration for execution of a [Statement].
356 class ExecConfiguration extends Configuration { 335 class ExecConfiguration extends Configuration {
357 final Statement statement; 336 final Statement currentStatement;
337 final Environment environment;
358 final State state; 338 final State state;
359 339
360 ExecConfiguration(this.statement, this.state); 340 ExecConfiguration(this.currentStatement, this.environment, this.state);
361 341
362 Configuration step(StatementExecuter executer) => 342 Configuration step(StatementExecuter executer) =>
363 executer.exec(statement, state); 343 executer.exec(currentStatement, this);
364 } 344 }
365 345
366 class ExitConfiguration extends ExecConfiguration { 346 /// Configuration for applying a [StatementContinuation] to an [Environment].
367 final ExpressionContinuation returnContinuation; 347 class ForwardConfiguration extends Configuration {
348 final StatementContinuation continuation;
349 final Environment environment;
368 350
369 ExitConfiguration(this.returnContinuation) : super(null, null); 351 ForwardConfiguration(this.continuation, this.environment);
370 352
371 Configuration step(StatementExecuter _) { 353 Configuration step(StatementExecuter _) => continuation?.call(environment);
372 return returnContinuation(Value.nullInstance);
373 }
374 } 354 }
375 355
376 class NewInstanceConfiguration extends ExecConfiguration { 356 /// Configuration for applying [ExpressionContinuation] to a [Value].
377 final ExpressionContinuation continuation;
378 final ObjectValue newObject;
379
380 NewInstanceConfiguration(this.continuation, this.newObject)
381 : super(null, new State.initial());
382
383 Configuration step(StatementExecuter _) {
384 return continuation(newObject);
385 }
386 }
387
388 /// Represents the configuration for applying an [ExpressionContinuation].
389 class ValuePassingConfiguration extends Configuration { 357 class ValuePassingConfiguration extends Configuration {
390 final ExpressionContinuation continuation; 358 final ExpressionContinuation continuation;
391 final Value value; 359 final Value value;
392 360
393 ValuePassingConfiguration(this.continuation, this.value); 361 ValuePassingConfiguration(this.continuation, this.value);
394 362
395 Configuration step(StatementExecuter _) => continuation(value); 363 Configuration step(StatementExecuter _) => continuation(value);
396 } 364 }
397 365
398 /// Represents the configuration for applying an [ApplicationContinuation]. 366 /// Configuration for applying an [ApplicationContinuation] to a
367 /// `List<InterpreterValue>`.
399 class ApplicationConfiguration extends Configuration { 368 class ApplicationConfiguration extends Configuration {
400 final ApplicationContinuation continuation; 369 final ApplicationContinuation continuation;
401 final List<InterpreterValue> values; 370 final List<InterpreterValue> values;
402 371
403 ApplicationConfiguration(this.continuation, this.values); 372 ApplicationConfiguration(this.continuation, this.values);
404 373
405 Configuration step(StatementExecuter _) => continuation(values); 374 Configuration step(StatementExecuter _) => continuation(values);
406 } 375 }
407 376
408 // ------------------------------------------------------------------------ 377 // ------------------------------------------------------------------------
409 // Interpreter Expressions and Values 378 // Interpreter Expressions and Values
410 // ------------------------------------------------------------------------ 379 // ------------------------------------------------------------------------
380
411 abstract class InterpreterExpression { 381 abstract class InterpreterExpression {
412 Expression get expression; 382 Expression get expression;
413 383
414 InterpreterValue assignValue(Value v); 384 InterpreterValue assignValue(Value v);
415 } 385 }
416 386
417 class PositionalExpression extends InterpreterExpression { 387 class PositionalExpression extends InterpreterExpression {
418 final Expression expression; 388 final Expression expression;
419 389
420 PositionalExpression(this.expression); 390 PositionalExpression(this.expression);
421 391
422 InterpreterValue assignValue(Value v) => new PositionalValue(v); 392 InterpreterValue assignValue(Value v) => new PositionalValue(v);
423 } 393 }
424 394
425 class NamedExpression extends InterpreterExpression { 395 class NamedExpression extends InterpreterExpression {
426 final String name; 396 final String name;
427 final Expression expression; 397 final Expression expression;
428 398
429 NamedExpression(this.name, this.expression); 399 NamedExpression(this.name, this.expression);
430 InterpreterValue assignValue(Value v) => new NamedValue(name, v); 400 InterpreterValue assignValue(Value v) => new NamedValue(name, v);
431 } 401 }
432 402
433 class LocalInitializerExpression extends InterpreterExpression {
434 final VariableDeclaration variable;
435
436 Expression get expression => variable.initializer;
437
438 LocalInitializerExpression(this.variable);
439
440 InterpreterValue assignValue(Value v) =>
441 new LocalInitializerValue(variable, v);
442 }
443
444 class FieldInitializerExpression extends InterpreterExpression { 403 class FieldInitializerExpression extends InterpreterExpression {
445 final Field field; 404 final Field field;
446 final Expression expression; 405 final Expression expression;
447 406
448 FieldInitializerExpression(this.field, this.expression); 407 FieldInitializerExpression(this.field, this.expression);
449 408
450 InterpreterValue assignValue(Value v) => new FieldInitializerValue(field, v); 409 InterpreterValue assignValue(Value v) => new FieldInitializerValue(field, v);
451 } 410 }
452 411
453 abstract class InterpreterValue { 412 abstract class InterpreterValue {
454 Value get value; 413 Value get value;
455 } 414 }
456 415
457 class PositionalValue extends InterpreterValue { 416 class PositionalValue extends InterpreterValue {
458 final Value value; 417 final Value value;
459 418
460 PositionalValue(this.value); 419 PositionalValue(this.value);
461 } 420 }
462 421
463 class NamedValue extends InterpreterValue { 422 class NamedValue extends InterpreterValue {
464 final String name; 423 final String name;
465 final Value value; 424 final Value value;
466 425
467 NamedValue(this.name, this.value); 426 NamedValue(this.name, this.value);
468 } 427 }
469 428
470 class LocalInitializerValue extends InterpreterValue {
471 final VariableDeclaration variable;
472 final Value value;
473
474 LocalInitializerValue(this.variable, this.value);
475 }
476
477 class FieldInitializerValue extends InterpreterValue { 429 class FieldInitializerValue extends InterpreterValue {
478 final Field field; 430 final Field field;
479 final Value value; 431 final Value value;
480 432
481 FieldInitializerValue(this.field, this.value); 433 FieldInitializerValue(this.field, this.value);
482 } 434 }
483 435
484 abstract class Continuation {} 436 abstract class Continuation {}
485 437
438 // ------------------------------------------------------------------------
439 // Statement Continuations
440 // ------------------------------------------------------------------------
441
442 /// Represents a the continuation for the execution of the next statement of
443 /// the program.
444 ///
445 /// There are various kinds of [StatementContinuation]s and their names are
446 /// suffixed with "SK".
447 abstract class StatementContinuation extends Continuation {
448 Configuration call(Environment env);
449 }
450
451 /// Applies the expression continuation to the provided value.
452 class ExitSK extends StatementContinuation {
453 final ExpressionContinuation continuation;
454 final Value value;
455
456 ExitSK(this.continuation, this.value);
457
458 Configuration call(Environment _) =>
459 new ValuePassingConfiguration(continuation, value);
460 }
461
462 /// Executes the next statement from a block with the corresponding environment
463 /// or proceeds with next statement continuation.
464 class BlockSK extends StatementContinuation {
465 final List<Statement> statements;
466 final Environment enclosingEnv;
467 final State state;
468
469 BlockSK(this.statements, this.enclosingEnv, this.state);
470
471 BlockSK.fromConfig(this.statements, ExecConfiguration conf)
472 : enclosingEnv = conf.environment,
473 state = conf.state;
474
475 Configuration call(Environment env) {
476 if (statements.isEmpty) {
477 return new ForwardConfiguration(state.continuation, enclosingEnv);
478 }
479 // Proceed with the execution statement when there are some remaining to
480 // be executed.
481 var cont = new BlockSK(statements.skip(1).toList(), enclosingEnv, state);
482 return new ExecConfiguration(
483 statements.first, env, state.withContinuation(cont));
484 }
485 }
486
487 class NewSK extends StatementContinuation {
488 final ExpressionContinuation continuation;
489 final Location location;
490
491 NewSK(this.continuation, this.location);
492
493 Configuration call(Environment _) =>
494 new ValuePassingConfiguration(continuation, location.value);
495 }
496
497 class WhileConditionSK extends StatementContinuation {
498 final Expression condition;
499 final Statement body;
500 final Environment enclosingEnv;
501 final State state;
502
503 WhileConditionSK(this.condition, this.body, this.enclosingEnv, this.state);
504
505 Configuration call(Environment _) {
506 // Evaluate the condition for the while loop execution.
507 var cont = new WhileConditionEK(condition, body, enclosingEnv, state);
508 return new EvalConfiguration(condition, enclosingEnv, cont);
509 }
510 }
511
512 // ------------------------------------------------------------------------
513 // Application Continuations
514 // ------------------------------------------------------------------------
515
486 /// Represents the continuation called after the evaluation of argument 516 /// Represents the continuation called after the evaluation of argument
487 /// expressions. 517 /// expressions.
488 /// 518 ///
489 /// There are various kinds of [ApplicationContinuation] and their names are 519 /// There are various kinds of [ApplicationContinuation] and their names are
490 /// suffixed with "A". 520 /// suffixed with "A".
491 abstract class ApplicationContinuation extends Continuation { 521 abstract class ApplicationContinuation extends Continuation {
492 Configuration call(List<InterpreterValue> values); 522 Configuration call(List<InterpreterValue> values);
493 523
494 /// Binds actual argument values to formal parameters of the function in a 524 /// Binds actual argument values to formal parameters of the function in a
495 /// new environment or in the provided initial environment. 525 /// new environment or in the provided initial environment.
496 /// TODO: Add checks for validation of arguments according to spec. 526 /// TODO: Add checks for validation of arguments according to spec.
497 static Environment createEnvironment( 527 static Environment createEnvironment(
498 FunctionNode function, List<InterpreterValue> args, 528 FunctionNode function, List<InterpreterValue> args,
499 [Environment parentEnv]) { 529 [Environment parentEnv]) {
500 Environment newEnv = new Environment(parentEnv); 530 Environment newEnv = new Environment(parentEnv ?? new Environment.empty());
531
501 List<PositionalValue> positional = args.reversed 532 List<PositionalValue> positional = args.reversed
502 .where((InterpreterValue av) => av is PositionalValue) 533 .where((InterpreterValue av) => av is PositionalValue)
503 .toList(); 534 .toList();
504 535
505 // Add positional parameters. 536 // Add positional parameters.
506 for (int i = 0; i < positional.length; ++i) { 537 for (int i = 0; i < positional.length; ++i) {
507 newEnv.expand(function.positionalParameters[i], positional[i].value); 538 newEnv =
539 newEnv.extend(function.positionalParameters[i], positional[i].value);
508 } 540 }
509 541
510 Map<String, Value> named = new Map.fromIterable( 542 Map<String, Value> named = new Map.fromIterable(
511 args.where((InterpreterValue av) => av is NamedValue), 543 args.where((InterpreterValue av) => av is NamedValue),
512 key: (NamedValue av) => av.name, 544 key: (NamedValue av) => av.name,
513 value: (NamedValue av) => av.value); 545 value: (NamedValue av) => av.value);
514 546
515 // Add named parameters. 547 // Add named parameters.
516 for (VariableDeclaration v in function.namedParameters) { 548 for (VariableDeclaration v in function.namedParameters) {
517 newEnv.expand(v, named[v.name.toString()]); 549 newEnv = newEnv.extend(v, named[v.name.toString()]);
518 } 550 }
519 551
520 return newEnv; 552 return newEnv;
521 } 553 }
522 } 554 }
523 555
556 /// Represents the application continuation called after the evaluation of all
557 /// argument expressions for an invocation.
558 class ValueA extends ApplicationContinuation {
559 final InterpreterValue value;
560 final ApplicationContinuation applicationContinuation;
561
562 ValueA(this.value, this.applicationContinuation);
563
564 Configuration call(List<InterpreterValue> args) {
565 args.add(value);
566 return new ApplicationConfiguration(applicationContinuation, args);
567 }
568 }
569
524 class StringConcatenationA extends ApplicationContinuation { 570 class StringConcatenationA extends ApplicationContinuation {
525 final ExpressionContinuation continuation; 571 final ExpressionContinuation continuation;
526 572
527 StringConcatenationA(this.continuation); 573 StringConcatenationA(this.continuation);
528 574
529 Configuration call(List<InterpreterValue> values) { 575 Configuration call(List<InterpreterValue> values) {
530 StringBuffer result = new StringBuffer(); 576 StringBuffer result = new StringBuffer();
531 for (InterpreterValue v in values.reversed) { 577 for (InterpreterValue v in values.reversed) {
532 result.write(v.value.value); 578 result.write(v.value.value);
533 } 579 }
534 return new ValuePassingConfiguration( 580 return new ValuePassingConfiguration(
535 continuation, new StringValue(result.toString())); 581 continuation, new StringValue(result.toString()));
536 } 582 }
537 } 583 }
538 584
539 /// Represents the application continuation for static invocation. 585 /// Represents the application continuation for static invocation.
540 class StaticInvocationA extends ApplicationContinuation { 586 class StaticInvocationA extends ApplicationContinuation {
541 final FunctionNode function; 587 final FunctionNode function;
542 final ExpressionContinuation continuation; 588 final ExpressionContinuation continuation;
543 589
544 StaticInvocationA(this.function, this.continuation); 590 StaticInvocationA(this.function, this.continuation);
545 591
546 Configuration call(List<InterpreterValue> argValues) { 592 Configuration call(List<InterpreterValue> argValues) {
547 Environment functionEnv = 593 Environment functionEnv =
548 ApplicationContinuation.createEnvironment(function, argValues); 594 ApplicationContinuation.createEnvironment(function, argValues);
595 State bodyState = new State(
596 null, continuation, new ExitSK(continuation, Value.nullInstance));
549 597
550 State bodyState = new State.initial() 598 return new ExecConfiguration(function.body, functionEnv, bodyState);
551 .withExpressionContinuation(continuation)
552 .withConfiguration(new ExitConfiguration(continuation))
553 .withEnvironment(functionEnv);
554 return new ExecConfiguration(function.body, bodyState);
555 }
556 }
557
558 /// Represents the application continuation for constructor invocation applied
559 /// on the list of evaluated arguments.
560 class ConstructorInvocationA extends ApplicationContinuation {
561 final Constructor constructor;
562 final ExpressionContinuation continuation;
563
564 ConstructorInvocationA(this.constructor, this.continuation);
565
566 Configuration call(List<InterpreterValue> argValues) {
567 Environment ctrEnv = ApplicationContinuation.createEnvironment(
568 constructor.function, argValues);
569
570 var class_ = new Class(constructor.enclosingClass.reference);
571 var newObject =
572 new ObjectValue(class_, new List<Value>(class_.instanceSize));
573
574 return new ObjectInitializationConfiguration(
575 constructor,
576 new InstanceEnvironment(newObject, ctrEnv),
577 new NewInstanceConfiguration(continuation, newObject));
578 }
579 }
580
581 /// Represents the application continuation for redirecting constructor
582 /// invocation applied on the list of evaluated arguments.
583 class RedirectingConstructorA extends ApplicationContinuation {
584 final Constructor constructor;
585 final Environment environment;
586 final ExecConfiguration configuration;
587
588 RedirectingConstructorA(
589 this.constructor, this.environment, this.configuration);
590
591 Configuration call(List<InterpreterValue> argValues) {
592 Value object = environment.thisInstance;
593 Environment ctrEnv = ApplicationContinuation.createEnvironment(
594 constructor.function,
595 argValues,
596 new InstanceEnvironment(object, new Environment.empty()));
597
598 return new ObjectInitializationConfiguration(
599 constructor, ctrEnv, configuration);
600 }
601 }
602
603 /// Represents the application continuation for super constructor
604 /// invocation applied on the list of evaluated arguments.
605 class SuperConstructorA extends ApplicationContinuation {
606 final Constructor constructor;
607 final Environment environment;
608 final ExecConfiguration configuration;
609
610 SuperConstructorA(this.constructor, this.environment, this.configuration);
611
612 Configuration call(List<InterpreterValue> argValues) {
613 Value object = environment.thisInstance;
614
615 Environment superEnv = ApplicationContinuation.createEnvironment(
616 constructor.function,
617 argValues,
618 new InstanceEnvironment(object, new Environment.empty()));
619
620 return new ObjectInitializationConfiguration(
621 constructor, superEnv, configuration);
622 }
623 }
624
625 /// Represents the configuration for execution of initializer and
626 /// constructor body statements for initialization of a newly allocated object.
627 class ObjectInitializationConfiguration extends Configuration {
628 final Constructor constructor;
629 final Environment environment;
630 final ExecConfiguration configuration;
631
632 ObjectInitializationConfiguration(
633 this.constructor, this.environment, this.configuration);
634
635 Configuration step(StatementExecuter _) {
636 if (constructor.initializers.isNotEmpty &&
637 constructor.initializers.last is RedirectingInitializer) {
638 // Constructor is redirecting.
639 Initializer initializer = constructor.initializers.first;
640 if (initializer is RedirectingInitializer) {
641 var app = new RedirectingConstructorA(
642 initializer.target, environment, configuration);
643 var args = _createArgumentExpressionList(
644 initializer.arguments, initializer.target.function);
645
646 return new EvalListConfiguration(args, environment, app);
647 }
648 // Redirecting initializer is not the only initializer.
649 for (Initializer i in constructor.initializers.reversed.skip(1)) {
650 assert(i is LocalInitializer);
651 }
652 var class_ = new Class(constructor.enclosingClass.reference);
653 var initEnv = new Environment(environment);
654 var cont = new InitializerEK(
655 class_, initEnv, constructor.initializers, configuration);
656 return new EvalConfiguration(
657 (initializer as LocalInitializer).variable.initializer,
658 initEnv,
659 cont);
660 }
661
662 // Set head of configurations to be executed to configuration for current
663 // constructor body.
664 var state = new State.initial()
665 .withEnvironment(environment)
666 .withConfiguration(configuration);
667 var bodyConfig = new ExecConfiguration(constructor.function.body, state);
668
669 // Initialize fields in immediately enclosing class.
670 var cont = new InstanceFieldsA(constructor, environment, bodyConfig);
671 var fieldExpressions = _createInstanceInitializers(constructor);
672
673 return new EvalListConfiguration(
674 fieldExpressions, new Environment.empty(), cont);
675 }
676
677 /// Creates a list of expressions for instance field initializers in
678 /// immediately enclosing class.
679 static List<InterpreterExpression> _createInstanceInitializers(
680 Constructor ctr) {
681 Class currentClass = new Class(ctr.enclosingClass.reference);
682 List<InterpreterExpression> es = <InterpreterExpression>[];
683
684 for (int i = currentClass.superclass?.instanceSize ?? 0;
685 i < currentClass.instanceSize;
686 i++) {
687 Field current = currentClass.instanceFields[i];
688 if (current.initializer != null) {
689 es.add(new FieldInitializerExpression(current, current.initializer));
690 }
691 }
692
693 return es;
694 }
695 }
696
697 /// Represents the application continuation applied on the list of evaluated
698 /// field initializer expressions.
699 class InstanceFieldsA extends ApplicationContinuation {
700 final Constructor constructor;
701 final Environment environment;
702 final ExecConfiguration configuration;
703
704 final Class _currentClass;
705 final ObjectValue _newObject;
706
707 InstanceFieldsA(this.constructor, this.environment, this.configuration)
708 : _currentClass = new Class(constructor.enclosingClass.reference),
709 _newObject = environment.thisInstance;
710
711 Configuration call(List<InterpreterValue> fieldValues) {
712 for (FieldInitializerValue current in fieldValues.reversed) {
713 _currentClass.setProperty(_newObject, current.field, current.value);
714 }
715
716 if (constructor.initializers.isEmpty) {
717 _initializeNullFields(_currentClass, _newObject);
718 return configuration;
719 }
720
721 // Produce next configuration.
722 if (constructor.initializers.first is SuperInitializer) {
723 // SuperInitializer appears last in the initializer list.
724 assert(constructor.initializers.length == 1);
725 SuperInitializer current = constructor.initializers.first;
726 var args = _createArgumentExpressionList(
727 current.arguments, current.target.function);
728
729 var superApp =
730 new SuperConstructorA(current.target, environment, configuration);
731 _initializeNullFields(_currentClass, _newObject);
732 return new EvalListConfiguration(args, environment, superApp);
733 }
734
735 Class class_ = new Class(constructor.enclosingClass.reference);
736 Environment initEnv = new Environment(environment);
737
738 var cont = new InitializerEK(
739 class_, initEnv, constructor.initializers, configuration);
740 return new EvalConfiguration(
741 _getExpression(constructor.initializers.first), initEnv, cont);
742 }
743 }
744
745 /// Represents the expression continuation applied on the list of evaluated
746 /// initializer expressions preceding a super call in the list.
747 class InitializerEK extends ExpressionContinuation {
748 final Class currentClass;
749 final Environment initializerEnvironment;
750 final List<Initializer> initializers;
751 final ExecConfiguration configuration;
752
753 InitializerEK(this.currentClass, this.initializerEnvironment,
754 this.initializers, this.configuration);
755
756 Configuration call(Value v) {
757 ObjectValue newObject = initializerEnvironment.thisInstance;
758 Initializer current = initializers.first;
759 if (current is FieldInitializer) {
760 currentClass.setProperty(newObject, current.field, v);
761 } else if (current is LocalInitializer) {
762 initializerEnvironment.expand(current.variable, v);
763 } else {
764 throw 'Assigning value $v to ${current.runtimeType}';
765 }
766
767 if (initializers.length <= 1) {
768 _initializeNullFields(currentClass, newObject);
769 return configuration;
770 }
771
772 Initializer next = initializers[1];
773
774 if (next is RedirectingInitializer) {
775 // RedirectingInitializer appears last in the initializer list.
776 assert(initializers.length == 2);
777 var app = new RedirectingConstructorA(
778 next.target, initializerEnvironment, configuration);
779 var args =
780 _createArgumentExpressionList(next.arguments, next.target.function);
781 return new EvalListConfiguration(args, initializerEnvironment, app);
782 }
783
784 if (next is SuperInitializer) {
785 // SuperInitializer appears last in the initializer list.
786 assert(initializers.length == 2);
787 var args =
788 _createArgumentExpressionList(next.arguments, next.target.function);
789 var superApp = new SuperConstructorA(
790 next.target, initializerEnvironment, configuration);
791 _initializeNullFields(currentClass, newObject);
792 return new EvalListConfiguration(args, initializerEnvironment, superApp);
793 }
794
795 var cont = new InitializerEK(currentClass, initializerEnvironment,
796 initializers.skip(1).toList(), configuration);
797 return new EvalConfiguration(
798 _getExpression(next), initializerEnvironment, cont);
799 }
800 }
801
802 /// Represents the application continuation called after the evaluation of all
803 /// argument expressions for an invocation.
804 class ValueA extends ApplicationContinuation {
805 final InterpreterValue value;
806 final ApplicationContinuation applicationContinuation;
807
808 ValueA(this.value, this.applicationContinuation);
809
810 Configuration call(List<InterpreterValue> args) {
811 args.add(value);
812 return new ApplicationConfiguration(applicationContinuation, args);
813 } 599 }
814 } 600 }
815 601
816 // ------------------------------------------------------------------------ 602 // ------------------------------------------------------------------------
817 // Expression Continuations 603 // Expression Continuations
818 // ------------------------------------------------------------------------ 604 // ------------------------------------------------------------------------
605
819 /// Represents an expression continuation. 606 /// Represents an expression continuation.
820 /// 607 ///
821 /// There are various kinds of [ExpressionContinuation]s and their names are 608 /// There are various kinds of [ExpressionContinuation]s and their names are
822 /// suffixed with "EK". 609 /// suffixed with "EK".
823 abstract class ExpressionContinuation extends Continuation { 610 abstract class ExpressionContinuation extends Continuation {
824 Configuration call(Value v); 611 Configuration call(Value v);
825 } 612 }
826 613
827 /// Represents a continuation that returns the next [ExecConfiguration] 614 /// Represents a continuation that returns the next [ExecConfiguration]
828 /// to be executed. 615 /// to be executed.
829 class ExpressionEK extends ExpressionContinuation { 616 class ExpressionEK extends ExpressionContinuation {
830 final ExecConfiguration configuration; 617 final StatementContinuation continuation;
618 final Environment environment;
831 619
832 ExpressionEK(this.configuration); 620 ExpressionEK(this.continuation, this.environment);
833 621
834 Configuration call(Value _) { 622 Configuration call(Value _) {
835 return configuration; 623 return new ForwardConfiguration(continuation, environment);
836 } 624 }
837 } 625 }
838 626
839 class PrintEK extends ExpressionContinuation { 627 class PrintEK extends ExpressionContinuation {
840 final ExpressionContinuation continuation; 628 final ExpressionContinuation continuation;
841 629
842 PrintEK(this.continuation); 630 PrintEK(this.continuation);
843 631
844 Configuration call(Value v) { 632 Configuration call(Value v) {
845 log.info('print(${v.value.runtimeType}: ${v.value})\n'); 633 log.info('print(${v.value.runtimeType}: ${v.value})\n');
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
1019 class LetEK extends ExpressionContinuation { 807 class LetEK extends ExpressionContinuation {
1020 final VariableDeclaration variable; 808 final VariableDeclaration variable;
1021 final Expression letBody; 809 final Expression letBody;
1022 final Environment environment; 810 final Environment environment;
1023 final ExpressionContinuation continuation; 811 final ExpressionContinuation continuation;
1024 812
1025 LetEK(this.variable, this.letBody, this.environment, this.continuation); 813 LetEK(this.variable, this.letBody, this.environment, this.continuation);
1026 814
1027 Configuration call(Value value) { 815 Configuration call(Value value) {
1028 var letEnv = new Environment(environment); 816 var letEnv = new Environment(environment);
1029 letEnv.expand(variable, value); 817 letEnv.extend(variable, value);
1030 return new EvalConfiguration(letBody, letEnv, continuation); 818 return new EvalConfiguration(letBody, letEnv, continuation);
1031 } 819 }
1032 } 820 }
1033 821
1034 /// Represents the continuation for the condition expression in [WhileStatement] . 822 /// Represents the continuation for the condition expression in [WhileStatement] .
1035 class WhileConditionEK extends ExpressionContinuation { 823 class WhileConditionEK extends ExpressionContinuation {
1036 final WhileStatement node; 824 final Expression condition;
825 final Statement body;
826 final Environment enclosingEnv;
1037 final State state; 827 final State state;
1038 828
1039 WhileConditionEK(this.node, this.state); 829 WhileConditionEK(this.condition, this.body, this.enclosingEnv, this.state);
1040 830
1041 ExecConfiguration call(Value v) { 831 Configuration call(Value v) {
1042 if (identical(v, Value.trueInstance)) { 832 if (identical(v, Value.falseInstance)) {
1043 // Add configuration for the While statement to the linked list. 833 return new ForwardConfiguration(state.continuation, enclosingEnv);
1044 ExecConfiguration config = new ExecConfiguration(node, state);
1045 // Configuration for the body of the loop.
1046 return new ExecConfiguration(node.body, state.withConfiguration(config));
1047 } 834 }
1048 835 var cont = new WhileConditionSK(condition, body, enclosingEnv, state);
1049 return state.statementConfiguration; 836 return new ExecConfiguration(
837 body, enclosingEnv, state.withContinuation(cont));
1050 } 838 }
1051 } 839 }
1052 840
1053 /// Represents the continuation for the condition expression in [IfStatement]. 841 /// Represents the continuation for the condition expression in [IfStatement].
1054 class IfConditionEK extends ExpressionContinuation { 842 class IfConditionEK extends ExpressionContinuation {
1055 final Statement then; 843 final Statement then;
1056 final Statement otherwise; 844 final Statement otherwise;
845 final Environment environment;
1057 final State state; 846 final State state;
1058 847
1059 IfConditionEK(this.then, this.otherwise, this.state); 848 IfConditionEK(this.then, this.otherwise, this.environment, this.state);
1060 849
1061 ExecConfiguration call(Value v) { 850 Configuration call(Value v) {
1062 if (identical(v, Value.trueInstance)) { 851 if (identical(v, Value.trueInstance)) {
1063 log.info("if-then\n"); 852 log.info("if-then\n");
1064 return new ExecConfiguration(then, state); 853 return new ExecConfiguration(then, environment, state);
1065 } else if (otherwise != null) { 854 } else if (otherwise != null) {
1066 log.info("if-otherwise\n"); 855 log.info("if-otherwise\n");
1067 return new ExecConfiguration(otherwise, state); 856 return new ExecConfiguration(otherwise, environment, state);
1068 } 857 }
1069 return state.statementConfiguration; 858 return new ForwardConfiguration(state.continuation, environment);
1070 } 859 }
1071 } 860 }
1072 861
1073 /// Represents the continuation for the initializer expression in 862 /// Represents the continuation for the initializer expression in
1074 /// [VariableDeclaration]. 863 /// [VariableDeclaration].
1075 class VariableInitializerEK extends ExpressionContinuation { 864 class VariableInitializerEK extends ExpressionContinuation {
1076 final VariableDeclaration variable; 865 final VariableDeclaration variable;
1077 final Environment environment; 866 final Environment environment;
1078 final ExecConfiguration nextConfiguration; 867 final StatementContinuation continuation;
1079 868
1080 VariableInitializerEK( 869 VariableInitializerEK(this.variable, this.environment, this.continuation);
1081 this.variable, this.environment, this.nextConfiguration);
1082 870
1083 ExecConfiguration call(Value v) { 871 Configuration call(Value v) {
1084 environment.expand(variable, v); 872 return new ForwardConfiguration(
1085 return nextConfiguration; 873 continuation, environment.extend(variable, v));
1086 } 874 }
1087 } 875 }
1088 876
1089 /// Executes statements. 877 /// Executes statements.
1090 /// 878 ///
1091 /// Execution of a statement completes in one of the following ways: 879 /// Execution of a statement completes in one of the following ways:
1092 /// - it completes normally, in which case the execution proceeds to applying 880 /// - It completes normally, in which case the execution proceeds to applying
1093 /// the next continuation 881 /// the next continuation.
1094 /// - it breaks with a label, in which case the corresponding continuation is 882 /// - It breaks with a label, in which case the corresponding continuation is
1095 /// returned and applied 883 /// returned and applied.
1096 /// - it returns with or without value, TBD 884 /// - It returns with or without value, in which case the return continuation is
1097 /// - it throws, TBD 885 /// returned and applied accordingly.
1098 class StatementExecuter extends StatementVisitor1<Configuration, State> { 886 /// - It throws, in which case the handler is returned and applied accordingly.
887 class StatementExecuter
888 extends StatementVisitor1<Configuration, ExecConfiguration> {
1099 Evaluator evaluator = new Evaluator(); 889 Evaluator evaluator = new Evaluator();
1100 890
1101 void trampolinedExecution(Configuration configuration) { 891 void trampolinedExecution(Configuration configuration) {
1102 while (configuration != null) { 892 while (configuration != null) {
1103 configuration = configuration.step(this); 893 configuration = configuration.step(this);
1104 } 894 }
1105 } 895 }
1106 896
1107 Configuration exec(Statement statement, State state) => 897 Configuration exec(Statement statement, ExecConfiguration conf) =>
1108 statement.accept1(this, state); 898 statement.accept1(this, conf);
1109 Configuration eval(Expression expression, EvalConfiguration config) => 899 Configuration eval(Expression expression, EvalConfiguration config) =>
1110 evaluator.eval(expression, config); 900 evaluator.eval(expression, config);
1111 Configuration evalList( 901 Configuration evalList(
1112 List<InterpreterExpression> es, Environment env, Continuation cont) => 902 List<InterpreterExpression> es, Environment env, Continuation cont) =>
1113 evaluator.evalList(es, env, cont); 903 evaluator.evalList(es, env, cont);
1114 904
1115 Configuration defaultStatement(Statement node, State state) { 905 Configuration defaultStatement(Statement node, ExecConfiguration conf) {
1116 throw notImplemented( 906 throw notImplemented(
1117 m: "Execution is not implemented for statement:\n$node "); 907 m: "Execution is not implemented for statement:\n$node ");
1118 } 908 }
1119 909
1120 Configuration visitInvalidStatement(InvalidStatement node, State state) { 910 Configuration visitInvalidStatement(
911 InvalidStatement node, ExecConfiguration conf) {
1121 throw "Invalid statement at ${node.location}"; 912 throw "Invalid statement at ${node.location}";
1122 } 913 }
1123 914
1124 Configuration visitExpressionStatement( 915 Configuration visitExpressionStatement(
1125 ExpressionStatement node, State state) { 916 ExpressionStatement node, ExecConfiguration conf) {
1126 var cont = new ExpressionEK(state.statementConfiguration); 917 var cont = new ExpressionEK(conf.state.continuation, conf.environment);
1127 return new EvalConfiguration(node.expression, state.environment, cont); 918 return new EvalConfiguration(node.expression, conf.environment, cont);
1128 } 919 }
1129 920
1130 Configuration visitBlock(Block node, State state) { 921 Configuration visitBlock(Block node, ExecConfiguration conf) {
1131 if (node.statements.isEmpty) { 922 if (node.statements.isEmpty) {
1132 return state.statementConfiguration; 923 return new ForwardConfiguration(
924 conf.state.continuation, conf.environment);
1133 } 925 }
1134 State blockState = 926
1135 state.withEnvironment(new Environment(state.environment)); 927 var env = new Environment(conf.environment);
1136 ExecConfiguration configuration = state.statementConfiguration; 928 var cont = new BlockSK.fromConfig(node.statements.skip(1).toList(), conf);
1137 for (Statement s in node.statements.reversed) { 929 return new ExecConfiguration(
1138 configuration = 930 node.statements.first, env, conf.state.withContinuation(cont));
1139 new ExecConfiguration(s, blockState.withConfiguration(configuration));
1140 }
1141 return configuration;
1142 } 931 }
1143 932
1144 Configuration visitEmptyStatement(EmptyStatement node, State state) { 933 Configuration visitEmptyStatement(
1145 return state.statementConfiguration; 934 EmptyStatement node, ExecConfiguration conf) {
935 return new ForwardConfiguration(conf.state.continuation, conf.environment);
1146 } 936 }
1147 937
1148 Configuration visitIfStatement(IfStatement node, State state) { 938 Configuration visitIfStatement(IfStatement node, ExecConfiguration conf) {
1149 var cont = new IfConditionEK(node.then, node.otherwise, state); 939 var cont = new IfConditionEK(
940 node.then, node.otherwise, conf.environment, conf.state);
1150 941
1151 return new EvalConfiguration(node.condition, state.environment, cont); 942 return new EvalConfiguration(node.condition, conf.environment, cont);
1152 } 943 }
1153 944
1154 Configuration visitLabeledStatement(LabeledStatement node, State state) { 945 Configuration visitLabeledStatement(
1155 return new ExecConfiguration(node.body, state.withBreak(node)); 946 LabeledStatement node, ExecConfiguration conf) {
947 return new ExecConfiguration(node.body, conf.environment,
948 conf.state.withBreak(node, conf.environment));
1156 } 949 }
1157 950
1158 Configuration visitBreakStatement(BreakStatement node, State state) { 951 Configuration visitBreakStatement(
1159 return state.lookupLabel(node.target).configuration; 952 BreakStatement node, ExecConfiguration conf) {
953 Label l = conf.state.lookupLabel(node.target);
954 return new ForwardConfiguration(l.continuation, l.environment);
1160 } 955 }
1161 956
1162 Configuration visitWhileStatement(WhileStatement node, State state) { 957 Configuration visitWhileStatement(
1163 var cont = new WhileConditionEK(node, state); 958 WhileStatement node, ExecConfiguration conf) {
959 var cont = new WhileConditionEK(
960 node.condition, node.body, conf.environment, conf.state);
1164 961
1165 return new EvalConfiguration(node.condition, state.environment, cont); 962 return new EvalConfiguration(node.condition, conf.environment, cont);
1166 } 963 }
1167 964
1168 Configuration visitDoStatement(DoStatement node, State state) { 965 Configuration visitDoStatement(DoStatement node, ExecConfiguration conf) {
1169 WhileStatement whileStatement = 966 var cont = new WhileConditionSK(
1170 new WhileStatement(node.condition, node.body); 967 node.condition, node.body, conf.environment, conf.state);
1171 ExecConfiguration configuration =
1172 new ExecConfiguration(whileStatement, state);
1173 968
1174 return new ExecConfiguration( 969 return new ExecConfiguration(
1175 node.body, state.withConfiguration(configuration)); 970 node.body, conf.environment, conf.state.withContinuation(cont));
1176 } 971 }
1177 972
1178 Configuration visitReturnStatement(ReturnStatement node, State state) { 973 Configuration visitReturnStatement(
1179 assert(state.returnContinuation != null); 974 ReturnStatement node, ExecConfiguration conf) {
975 assert(conf.state.returnContinuation != null);
1180 log.info('return\n'); 976 log.info('return\n');
1181 if (node.expression == null) { 977 if (node.expression == null) {
1182 return new ValuePassingConfiguration( 978 return new ValuePassingConfiguration(
1183 state.returnContinuation, Value.nullInstance); 979 conf.state.returnContinuation, Value.nullInstance);
1184 } 980 }
1185 981
1186 return new EvalConfiguration( 982 return new EvalConfiguration(
1187 node.expression, state.environment, state.returnContinuation); 983 node.expression, conf.environment, conf.state.returnContinuation);
1188 } 984 }
1189 985
1190 Configuration visitVariableDeclaration( 986 Configuration visitVariableDeclaration(
1191 VariableDeclaration node, State state) { 987 VariableDeclaration node, ExecConfiguration conf) {
1192 if (node.initializer != null) { 988 if (node.initializer != null) {
1193 var cont = new VariableInitializerEK( 989 var cont = new VariableInitializerEK(
1194 node, state.environment, state.statementConfiguration); 990 node, conf.environment, conf.state.continuation);
1195 return new EvalConfiguration(node.initializer, state.environment, cont); 991 return new EvalConfiguration(node.initializer, conf.environment, cont);
1196 } 992 }
1197 state.environment.expand(node, Value.nullInstance); 993 return new ForwardConfiguration(conf.state.continuation,
1198 return state.statementConfiguration; 994 conf.environment.extend(node, Value.nullInstance));
1199 } 995 }
1200 } 996 }
1201 997
1202 // ------------------------------------------------------------------------ 998 // ------------------------------------------------------------------------
1203 // VALUES 999 // VALUES
1204 // ------------------------------------------------------------------------ 1000 // ------------------------------------------------------------------------
1205 1001
1206 typedef Value Getter(Value receiver); 1002 typedef Value Getter(Value receiver);
1207 typedef void Setter(Value receiver, Value value); 1003 typedef void Setter(Value receiver, Value value);
1208 1004
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after
1486 void _initializeNullFields(Class class_, ObjectValue newObject) { 1282 void _initializeNullFields(Class class_, ObjectValue newObject) {
1487 int superClassSize = class_.superclass?.instanceSize ?? 0; 1283 int superClassSize = class_.superclass?.instanceSize ?? 0;
1488 for (int i = superClassSize; i < class_.instanceSize; i++) { 1284 for (int i = superClassSize; i < class_.instanceSize; i++) {
1489 Field field = class_.instanceFields[i]; 1285 Field field = class_.instanceFields[i];
1490 if (class_.getProperty(newObject, field) == null) { 1286 if (class_.getProperty(newObject, field) == null) {
1491 assert(field.initializer == null); 1287 assert(field.initializer == null);
1492 class_.setProperty(newObject, field, Value.nullInstance); 1288 class_.setProperty(newObject, field, Value.nullInstance);
1493 } 1289 }
1494 } 1290 }
1495 } 1291 }
OLDNEW
« no previous file with comments | « no previous file | pkg/kernel/test/interpreter/interpreter.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698