| Index: pkg/kernel/lib/interpreter/interpreter.dart
|
| diff --git a/pkg/kernel/lib/interpreter/interpreter.dart b/pkg/kernel/lib/interpreter/interpreter.dart
|
| index 46453f221a2d8c94fe3797fd4801e3a70650a5ba..b61da18fa505d16957082fe1f153cd96fb45323b 100644
|
| --- a/pkg/kernel/lib/interpreter/interpreter.dart
|
| +++ b/pkg/kernel/lib/interpreter/interpreter.dart
|
| @@ -15,7 +15,8 @@ class NotImplemented {
|
|
|
| class Interpreter {
|
| Program program;
|
| - Evaluator evaluator = new Evaluator();
|
| + StatementExecuter visitor = new StatementExecuter();
|
| + Environment env = new Environment.empty();
|
|
|
| Interpreter(this.program);
|
|
|
| @@ -23,26 +24,7 @@ class Interpreter {
|
| assert(program.libraries.isEmpty);
|
| Procedure mainMethod = program.mainMethod;
|
| Statement statementBlock = mainMethod.function.body;
|
| - // Executes only ExpressionStatements and VariableDeclarations in the top
|
| - // BlockStatement.
|
| - if (statementBlock is Block) {
|
| - var env = new Environment.empty();
|
| -
|
| - for (Statement s in statementBlock.statements) {
|
| - if (s is ExpressionStatement) {
|
| - evaluator.eval(s.expression, env);
|
| - } else if (s is VariableDeclaration) {
|
| - var value = evaluator.eval(s.initializer ?? new NullLiteral(), env);
|
| - env.expand(s, value);
|
| - } else {
|
| - throw new NotImplemented('Evaluation for statement type '
|
| - '${s.runtimeType} is not implemented.');
|
| - }
|
| - }
|
| - } else {
|
| - throw new NotImplemented('Evaluation for statement type '
|
| - '${statementBlock.runtimeType} is not implemented.');
|
| - }
|
| + visitor.exec(statementBlock, env);
|
| }
|
| }
|
|
|
| @@ -241,6 +223,52 @@ class Evaluator extends ExpressionVisitor1<Value> {
|
| }
|
| }
|
|
|
| +/// Executes statements.
|
| +class StatementExecuter extends StatementVisitor1 {
|
| + Evaluator evaluator = new Evaluator();
|
| +
|
| + exec(Statement statement, env) => statement.accept1(this, env);
|
| + eval(Expression expression, env) => evaluator.eval(expression, env);
|
| +
|
| + defaultStatement(Statement node, env) {
|
| + throw notImplemented(
|
| + m: "Execution is not implemented for statement:\n$node ");
|
| + }
|
| +
|
| + visitInvalidStatement(InvalidStatement node, env) {
|
| + throw "Invalid statement at ${node.location}";
|
| + }
|
| +
|
| + visitExpressionStatement(ExpressionStatement node, env) {
|
| + return eval(node.expression, env);
|
| + }
|
| +
|
| + visitBlock(Block node, env) {
|
| + Environment blockEnv = new Environment(env);
|
| + for (Statement s in node.statements) {
|
| + exec(s, blockEnv);
|
| + }
|
| + }
|
| +
|
| + visitEmptyStatement(EmptyStatement node, env) {}
|
| +
|
| + visitIfStatement(IfStatement node, env) {
|
| + Value condition = eval(node.condition, env).toBoolean();
|
| + if (identical(Value.trueInstance, condition)) {
|
| + exec(node.then, env);
|
| + } else {
|
| + exec(node.otherwise, env);
|
| + }
|
| + }
|
| +
|
| + visitVariableDeclaration(VariableDeclaration node, env) {
|
| + Value value = node.initializer != null
|
| + ? eval(node.initializer, env)
|
| + : Value.nullInstance;
|
| + env.expand(node, value);
|
| + }
|
| +}
|
| +
|
| typedef Value Getter(Value receiver);
|
| typedef void Setter(Value receiver, Value value);
|
|
|
|
|