| OLD | NEW |
| 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 library kernel.interpreter; | 4 library kernel.interpreter; |
| 5 | 5 |
| 6 import '../ast.dart'; | 6 import '../ast.dart'; |
| 7 | 7 |
| 8 class NotImplemented { | 8 class NotImplemented { |
| 9 String message; | 9 String message; |
| 10 | 10 |
| 11 NotImplemented(this.message); | 11 NotImplemented(this.message); |
| 12 | 12 |
| 13 String toString() => message; | 13 String toString() => message; |
| 14 } | 14 } |
| 15 | 15 |
| 16 class Interpreter { | 16 class Interpreter { |
| 17 Program program; | 17 Program program; |
| 18 Evaluator evaluator = new Evaluator(); | 18 StatementExecuter visitor = new StatementExecuter(); |
| 19 Environment env = new Environment.empty(); |
| 19 | 20 |
| 20 Interpreter(this.program); | 21 Interpreter(this.program); |
| 21 | 22 |
| 22 void run() { | 23 void run() { |
| 23 assert(program.libraries.isEmpty); | 24 assert(program.libraries.isEmpty); |
| 24 Procedure mainMethod = program.mainMethod; | 25 Procedure mainMethod = program.mainMethod; |
| 25 Statement statementBlock = mainMethod.function.body; | 26 Statement statementBlock = mainMethod.function.body; |
| 26 // Executes only ExpressionStatements and VariableDeclarations in the top | 27 visitor.exec(statementBlock, env); |
| 27 // BlockStatement. | |
| 28 if (statementBlock is Block) { | |
| 29 var env = new Environment.empty(); | |
| 30 | |
| 31 for (Statement s in statementBlock.statements) { | |
| 32 if (s is ExpressionStatement) { | |
| 33 evaluator.eval(s.expression, env); | |
| 34 } else if (s is VariableDeclaration) { | |
| 35 var value = evaluator.eval(s.initializer ?? new NullLiteral(), env); | |
| 36 env.expand(s, value); | |
| 37 } else { | |
| 38 throw new NotImplemented('Evaluation for statement type ' | |
| 39 '${s.runtimeType} is not implemented.'); | |
| 40 } | |
| 41 } | |
| 42 } else { | |
| 43 throw new NotImplemented('Evaluation for statement type ' | |
| 44 '${statementBlock.runtimeType} is not implemented.'); | |
| 45 } | |
| 46 } | 28 } |
| 47 } | 29 } |
| 48 | 30 |
| 49 class InvalidExpressionError { | 31 class InvalidExpressionError { |
| 50 InvalidExpression expression; | 32 InvalidExpression expression; |
| 51 | 33 |
| 52 InvalidExpressionError(this.expression); | 34 InvalidExpressionError(this.expression); |
| 53 | 35 |
| 54 String toString() => | 36 String toString() => |
| 55 'Invalid expression at ${expression.location.toString()}'; | 37 'Invalid expression at ${expression.location.toString()}'; |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 234 Value visitNullLiteral(NullLiteral node, env) => Value.nullInstance; | 216 Value visitNullLiteral(NullLiteral node, env) => Value.nullInstance; |
| 235 | 217 |
| 236 Value visitLet(Let node, env) { | 218 Value visitLet(Let node, env) { |
| 237 var value = eval(node.variable.initializer, env); | 219 var value = eval(node.variable.initializer, env); |
| 238 var letEnv = new Environment(env); | 220 var letEnv = new Environment(env); |
| 239 letEnv.expand(node.variable, value); | 221 letEnv.expand(node.variable, value); |
| 240 return eval(node.body, letEnv); | 222 return eval(node.body, letEnv); |
| 241 } | 223 } |
| 242 } | 224 } |
| 243 | 225 |
| 226 /// Executes statements. |
| 227 class StatementExecuter extends StatementVisitor1 { |
| 228 Evaluator evaluator = new Evaluator(); |
| 229 |
| 230 exec(Statement statement, env) => statement.accept1(this, env); |
| 231 eval(Expression expression, env) => evaluator.eval(expression, env); |
| 232 |
| 233 defaultStatement(Statement node, env) { |
| 234 throw notImplemented( |
| 235 m: "Execution is not implemented for statement:\n$node "); |
| 236 } |
| 237 |
| 238 visitInvalidStatement(InvalidStatement node, env) { |
| 239 throw "Invalid statement at ${node.location}"; |
| 240 } |
| 241 |
| 242 visitExpressionStatement(ExpressionStatement node, env) { |
| 243 return eval(node.expression, env); |
| 244 } |
| 245 |
| 246 visitBlock(Block node, env) { |
| 247 Environment blockEnv = new Environment(env); |
| 248 for (Statement s in node.statements) { |
| 249 exec(s, blockEnv); |
| 250 } |
| 251 } |
| 252 |
| 253 visitEmptyStatement(EmptyStatement node, env) {} |
| 254 |
| 255 visitIfStatement(IfStatement node, env) { |
| 256 Value condition = eval(node.condition, env).toBoolean(); |
| 257 if (identical(Value.trueInstance, condition)) { |
| 258 exec(node.then, env); |
| 259 } else { |
| 260 exec(node.otherwise, env); |
| 261 } |
| 262 } |
| 263 |
| 264 visitVariableDeclaration(VariableDeclaration node, env) { |
| 265 Value value = node.initializer != null |
| 266 ? eval(node.initializer, env) |
| 267 : Value.nullInstance; |
| 268 env.expand(node, value); |
| 269 } |
| 270 } |
| 271 |
| 244 typedef Value Getter(Value receiver); | 272 typedef Value Getter(Value receiver); |
| 245 typedef void Setter(Value receiver, Value value); | 273 typedef void Setter(Value receiver, Value value); |
| 246 | 274 |
| 247 // TODO(zhivkag): Change misleading name. | 275 // TODO(zhivkag): Change misleading name. |
| 248 // This is representation of a class in the interpreter, not a declaration. | 276 // This is representation of a class in the interpreter, not a declaration. |
| 249 class ClassDeclaration { | 277 class ClassDeclaration { |
| 250 static final Map<Reference, ClassDeclaration> _classes = | 278 static final Map<Reference, ClassDeclaration> _classes = |
| 251 <Reference, ClassDeclaration>{}; | 279 <Reference, ClassDeclaration>{}; |
| 252 | 280 |
| 253 ClassDeclaration superclass; | 281 ClassDeclaration superclass; |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 465 | 493 |
| 466 class NullValue extends LiteralValue { | 494 class NullValue extends LiteralValue { |
| 467 Object get value => null; | 495 Object get value => null; |
| 468 | 496 |
| 469 const NullValue(); | 497 const NullValue(); |
| 470 } | 498 } |
| 471 | 499 |
| 472 notImplemented({String m, Object obj}) { | 500 notImplemented({String m, Object obj}) { |
| 473 throw new NotImplemented(m ?? 'Evaluation for $obj is not implemented'); | 501 throw new NotImplemented(m ?? 'Evaluation for $obj is not implemented'); |
| 474 } | 502 } |
| OLD | NEW |