Initial implementation of interpreter for Kernel

Basic framework, evaluation of BasicLiterals and dummy evaluation
of print.

BUG=
R=kmillikin@google.com

Review-Url: https://codereview.chromium.org/2722283003 .
This commit is contained in:
Zhivka Gucevska 2017-03-02 13:19:27 +01:00
parent 6176847e36
commit 1b82e0c3a0
4 changed files with 209 additions and 0 deletions

22
pkg/kernel/bin/eval.dart Executable file
View file

@ -0,0 +1,22 @@
#!/usr/bin/env dart
// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:kernel/kernel.dart';
import 'package:kernel/interpreter/interpreter.dart';
import 'dart:io';
fail(String message) {
stderr.writeln(message);
exit(1);
}
main(List<String> args) {
if (args.length == 1 && args[0].endsWith('.dill')) {
var program = loadProgramFromBinary(args[0]);
new Interpreter(program).evalProgram();
} else {
return fail('One input binary file should be specified.');
}
}

View file

@ -1407,6 +1407,7 @@ abstract class Expression extends TreeNode {
}
accept(ExpressionVisitor v);
accept1(ExpressionVisitor1 v, arg);
}
/// An expression containing compile-time errors.
@ -1416,6 +1417,7 @@ class InvalidExpression extends Expression {
DartType getStaticType(TypeEnvironment types) => const BottomType();
accept(ExpressionVisitor v) => v.visitInvalidExpression(this);
accept1(ExpressionVisitor1 v, arg) => v.visitInvalidExpression(this, arg);
visitChildren(Visitor v) {}
transformChildren(Transformer v) {}
@ -1433,6 +1435,7 @@ class VariableGet extends Expression {
}
accept(ExpressionVisitor v) => v.visitVariableGet(this);
accept1(ExpressionVisitor1 v, arg) => v.visitVariableGet(this, arg);
visitChildren(Visitor v) {
promotedType?.accept(v);
@ -1459,6 +1462,7 @@ class VariableSet extends Expression {
DartType getStaticType(TypeEnvironment types) => value.getStaticType(types);
accept(ExpressionVisitor v) => v.visitVariableSet(this);
accept1(ExpressionVisitor1 v, arg) => v.visitVariableSet(this, arg);
visitChildren(Visitor v) {
value?.accept(v);
@ -1515,6 +1519,7 @@ class PropertyGet extends Expression {
}
accept(ExpressionVisitor v) => v.visitPropertyGet(this);
accept1(ExpressionVisitor1 v, arg) => v.visitPropertyGet(this, arg);
visitChildren(Visitor v) {
receiver?.accept(v);
@ -1561,6 +1566,7 @@ class PropertySet extends Expression {
DartType getStaticType(TypeEnvironment types) => value.getStaticType(types);
accept(ExpressionVisitor v) => v.visitPropertySet(this);
accept1(ExpressionVisitor1 v, arg) => v.visitPropertySet(this, arg);
visitChildren(Visitor v) {
receiver?.accept(v);
@ -1611,6 +1617,7 @@ class DirectPropertyGet extends Expression {
}
accept(ExpressionVisitor v) => v.visitDirectPropertyGet(this);
accept1(ExpressionVisitor1 v, arg) => v.visitDirectPropertyGet(this, arg);
DartType getStaticType(TypeEnvironment types) {
Class superclass = target.enclosingClass;
@ -1662,6 +1669,7 @@ class DirectPropertySet extends Expression {
}
accept(ExpressionVisitor v) => v.visitDirectPropertySet(this);
accept1(ExpressionVisitor1 v, arg) => v.visitDirectPropertySet(this, arg);
DartType getStaticType(TypeEnvironment types) => value.getStaticType(types);
}
@ -1708,6 +1716,8 @@ class DirectMethodInvocation extends InvocationExpression {
}
accept(ExpressionVisitor v) => v.visitDirectMethodInvocation(this);
accept1(ExpressionVisitor1 v, arg) =>
v.visitDirectMethodInvocation(this, arg);
DartType getStaticType(TypeEnvironment types) {
if (types.isOverloadedArithmeticOperator(target)) {
@ -1756,6 +1766,7 @@ class SuperPropertyGet extends Expression {
}
accept(ExpressionVisitor v) => v.visitSuperPropertyGet(this);
accept1(ExpressionVisitor1 v, arg) => v.visitSuperPropertyGet(this, arg);
visitChildren(Visitor v) {
name?.accept(v);
@ -1791,6 +1802,7 @@ class SuperPropertySet extends Expression {
DartType getStaticType(TypeEnvironment types) => value.getStaticType(types);
accept(ExpressionVisitor v) => v.visitSuperPropertySet(this);
accept1(ExpressionVisitor1 v, arg) => v.visitSuperPropertySet(this, arg);
visitChildren(Visitor v) {
name?.accept(v);
@ -1823,6 +1835,7 @@ class StaticGet extends Expression {
DartType getStaticType(TypeEnvironment types) => target.getterType;
accept(ExpressionVisitor v) => v.visitStaticGet(this);
accept1(ExpressionVisitor1 v, arg) => v.visitStaticGet(this, arg);
visitChildren(Visitor v) {
target?.acceptReference(v);
@ -1855,6 +1868,7 @@ class StaticSet extends Expression {
DartType getStaticType(TypeEnvironment types) => value.getStaticType(types);
accept(ExpressionVisitor v) => v.visitStaticSet(this);
accept1(ExpressionVisitor1 v, arg) => v.visitStaticSet(this, arg);
visitChildren(Visitor v) {
target?.acceptReference(v);
@ -1999,6 +2013,7 @@ class MethodInvocation extends InvocationExpression {
}
accept(ExpressionVisitor v) => v.visitMethodInvocation(this);
accept1(ExpressionVisitor1 v, arg) => v.visitMethodInvocation(this, arg);
visitChildren(Visitor v) {
receiver?.accept(v);
@ -2056,6 +2071,7 @@ class SuperMethodInvocation extends InvocationExpression {
}
accept(ExpressionVisitor v) => v.visitSuperMethodInvocation(this);
accept1(ExpressionVisitor1 v, arg) => v.visitSuperMethodInvocation(this, arg);
visitChildren(Visitor v) {
name?.accept(v);
@ -2105,6 +2121,7 @@ class StaticInvocation extends InvocationExpression {
}
accept(ExpressionVisitor v) => v.visitStaticInvocation(this);
accept1(ExpressionVisitor1 v, arg) => v.visitStaticInvocation(this, arg);
visitChildren(Visitor v) {
target?.acceptReference(v);
@ -2156,6 +2173,7 @@ class ConstructorInvocation extends InvocationExpression {
}
accept(ExpressionVisitor v) => v.visitConstructorInvocation(this);
accept1(ExpressionVisitor1 v, arg) => v.visitConstructorInvocation(this, arg);
visitChildren(Visitor v) {
target?.acceptReference(v);
@ -2190,6 +2208,7 @@ class Not extends Expression {
DartType getStaticType(TypeEnvironment types) => types.boolType;
accept(ExpressionVisitor v) => v.visitNot(this);
accept1(ExpressionVisitor1 v, arg) => v.visitNot(this, arg);
visitChildren(Visitor v) {
operand?.accept(v);
@ -2217,6 +2236,7 @@ class LogicalExpression extends Expression {
DartType getStaticType(TypeEnvironment types) => types.boolType;
accept(ExpressionVisitor v) => v.visitLogicalExpression(this);
accept1(ExpressionVisitor1 v, arg) => v.visitLogicalExpression(this, arg);
visitChildren(Visitor v) {
left?.accept(v);
@ -2254,6 +2274,7 @@ class ConditionalExpression extends Expression {
DartType getStaticType(TypeEnvironment types) => staticType;
accept(ExpressionVisitor v) => v.visitConditionalExpression(this);
accept1(ExpressionVisitor1 v, arg) => v.visitConditionalExpression(this, arg);
visitChildren(Visitor v) {
condition?.accept(v);
@ -2298,6 +2319,7 @@ class StringConcatenation extends Expression {
DartType getStaticType(TypeEnvironment types) => types.stringType;
accept(ExpressionVisitor v) => v.visitStringConcatenation(this);
accept1(ExpressionVisitor1 v, arg) => v.visitStringConcatenation(this, arg);
visitChildren(Visitor v) {
visitList(expressions, v);
@ -2320,6 +2342,7 @@ class IsExpression extends Expression {
DartType getStaticType(TypeEnvironment types) => types.boolType;
accept(ExpressionVisitor v) => v.visitIsExpression(this);
accept1(ExpressionVisitor1 v, arg) => v.visitIsExpression(this, arg);
visitChildren(Visitor v) {
operand?.accept(v);
@ -2347,6 +2370,7 @@ class AsExpression extends Expression {
DartType getStaticType(TypeEnvironment types) => type;
accept(ExpressionVisitor v) => v.visitAsExpression(this);
accept1(ExpressionVisitor1 v, arg) => v.visitAsExpression(this, arg);
visitChildren(Visitor v) {
operand?.accept(v);
@ -2378,6 +2402,7 @@ class StringLiteral extends BasicLiteral {
DartType getStaticType(TypeEnvironment types) => types.stringType;
accept(ExpressionVisitor v) => v.visitStringLiteral(this);
accept1(ExpressionVisitor1 v, arg) => v.visitStringLiteral(this, arg);
}
class IntLiteral extends BasicLiteral {
@ -2388,6 +2413,7 @@ class IntLiteral extends BasicLiteral {
DartType getStaticType(TypeEnvironment types) => types.intType;
accept(ExpressionVisitor v) => v.visitIntLiteral(this);
accept1(ExpressionVisitor1 v, arg) => v.visitIntLiteral(this, arg);
}
class DoubleLiteral extends BasicLiteral {
@ -2398,6 +2424,7 @@ class DoubleLiteral extends BasicLiteral {
DartType getStaticType(TypeEnvironment types) => types.doubleType;
accept(ExpressionVisitor v) => v.visitDoubleLiteral(this);
accept1(ExpressionVisitor1 v, arg) => v.visitDoubleLiteral(this, arg);
}
class BoolLiteral extends BasicLiteral {
@ -2408,6 +2435,7 @@ class BoolLiteral extends BasicLiteral {
DartType getStaticType(TypeEnvironment types) => types.boolType;
accept(ExpressionVisitor v) => v.visitBoolLiteral(this);
accept1(ExpressionVisitor1 v, arg) => v.visitBoolLiteral(this, arg);
}
class NullLiteral extends BasicLiteral {
@ -2416,6 +2444,7 @@ class NullLiteral extends BasicLiteral {
DartType getStaticType(TypeEnvironment types) => const BottomType();
accept(ExpressionVisitor v) => v.visitNullLiteral(this);
accept1(ExpressionVisitor1 v, arg) => v.visitNullLiteral(this, arg);
}
class SymbolLiteral extends Expression {
@ -2426,6 +2455,7 @@ class SymbolLiteral extends Expression {
DartType getStaticType(TypeEnvironment types) => types.symbolType;
accept(ExpressionVisitor v) => v.visitSymbolLiteral(this);
accept1(ExpressionVisitor1 v, arg) => v.visitSymbolLiteral(this, arg);
visitChildren(Visitor v) {}
transformChildren(Transformer v) {}
@ -2439,6 +2469,7 @@ class TypeLiteral extends Expression {
DartType getStaticType(TypeEnvironment types) => types.typeType;
accept(ExpressionVisitor v) => v.visitTypeLiteral(this);
accept1(ExpressionVisitor1 v, arg) => v.visitTypeLiteral(this, arg);
visitChildren(Visitor v) {
type?.accept(v);
@ -2453,6 +2484,7 @@ class ThisExpression extends Expression {
DartType getStaticType(TypeEnvironment types) => types.thisType;
accept(ExpressionVisitor v) => v.visitThisExpression(this);
accept1(ExpressionVisitor1 v, arg) => v.visitThisExpression(this, arg);
visitChildren(Visitor v) {}
transformChildren(Transformer v) {}
@ -2462,6 +2494,7 @@ class Rethrow extends Expression {
DartType getStaticType(TypeEnvironment types) => const BottomType();
accept(ExpressionVisitor v) => v.visitRethrow(this);
accept1(ExpressionVisitor1 v, arg) => v.visitRethrow(this, arg);
visitChildren(Visitor v) {}
transformChildren(Transformer v) {}
@ -2477,6 +2510,7 @@ class Throw extends Expression {
DartType getStaticType(TypeEnvironment types) => const BottomType();
accept(ExpressionVisitor v) => v.visitThrow(this);
accept1(ExpressionVisitor1 v, arg) => v.visitThrow(this, arg);
visitChildren(Visitor v) {
expression?.accept(v);
@ -2506,6 +2540,7 @@ class ListLiteral extends Expression {
}
accept(ExpressionVisitor v) => v.visitListLiteral(this);
accept1(ExpressionVisitor1 v, arg) => v.visitListLiteral(this, arg);
visitChildren(Visitor v) {
typeArgument?.accept(v);
@ -2538,6 +2573,7 @@ class MapLiteral extends Expression {
}
accept(ExpressionVisitor v) => v.visitMapLiteral(this);
accept1(ExpressionVisitor1 v, arg) => v.visitMapLiteral(this, arg);
visitChildren(Visitor v) {
keyType?.accept(v);
@ -2593,6 +2629,7 @@ class AwaitExpression extends Expression {
}
accept(ExpressionVisitor v) => v.visitAwaitExpression(this);
accept1(ExpressionVisitor1 v, arg) => v.visitAwaitExpression(this, arg);
visitChildren(Visitor v) {
operand?.accept(v);
@ -2619,6 +2656,7 @@ class FunctionExpression extends Expression {
DartType getStaticType(TypeEnvironment types) => function.functionType;
accept(ExpressionVisitor v) => v.visitFunctionExpression(this);
accept1(ExpressionVisitor1 v, arg) => v.visitFunctionExpression(this, arg);
visitChildren(Visitor v) {
function?.accept(v);
@ -2645,6 +2683,7 @@ class Let extends Expression {
DartType getStaticType(TypeEnvironment types) => body.getStaticType(types);
accept(ExpressionVisitor v) => v.visitLet(this);
accept1(ExpressionVisitor1 v, arg) => v.visitLet(this, arg);
visitChildren(Visitor v) {
variable?.accept(v);
@ -2686,6 +2725,7 @@ class LoadLibrary extends Expression {
}
accept(ExpressionVisitor v) => v.visitLoadLibrary(this);
accept1(ExpressionVisitor1 v, arg) => v.visitLoadLibrary(this, arg);
visitChildren(Visitor v) {}
transformChildren(Transformer v) {}
@ -2703,6 +2743,7 @@ class CheckLibraryIsLoaded extends Expression {
}
accept(ExpressionVisitor v) => v.visitCheckLibraryIsLoaded(this);
accept1(ExpressionVisitor1 v, arg) => v.visitCheckLibraryIsLoaded(this, arg);
visitChildren(Visitor v) {}
transformChildren(Transformer v) {}

View file

@ -0,0 +1,83 @@
// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library kernerl.interpreter;
import 'dart:collection';
import '../ast.dart';
class NotImplemented {
String message;
NotImplemented(this.message);
String toString() => message;
}
class Interpreter {
Program program;
Interpreter(this.program);
void evalProgram() {
assert(program.libraries.isEmpty);
Procedure mainMethod = program.mainMethod;
Statement statementBlock = mainMethod.function.body;
// Evaluate only statement with one expression, ExpressionStatement, which
// is StaticInvocation of the method print.
if (statementBlock is Block) {
Statement statement = statementBlock.statements.first;
if (statement is ExpressionStatement) {
statement.expression.accept1(new ExpressionEval1(),
new ExpressionState(new HashMap<String, Object>()));
}
} else {
throw new NotImplemented('Evaluation for statement type '
'${statementBlock.runtimeType} is not implemented');
}
}
}
class InvalidExpressionError {
InvalidExpression expression;
InvalidExpressionError(this.expression);
String toString() => 'Invalid expression at '
'${expression.location.toString()}';
}
class ExpressionState {
Map<String, Object> environment;
ExpressionState(this.environment);
}
class ExpressionEval1 extends ExpressionVisitor1<Object> {
@override
Object defaultExpression(Expression node, arg) {
throw new NotImplemented('Evaluation for expressions of type '
'${node.runtimeType} is not implemented.');
}
Object visitInvalidExpression1(InvalidExpression node, arg) =>
throw new InvalidExpressionError(node);
Object visitStaticInvocation(StaticInvocation node, arg) {
if ('print' == node.name.toString()) {
// Special evaluation of print.
var res = node.arguments.positional[0].accept1(this, arg);
print(res);
} else {
throw new NotImplemented('Support for statement type '
'${node.runtimeType} is not implemented');
}
}
// Evaluation of BasicLiterals.
Object visitStringLiteral(StringLiteral node, arg) => node.value;
Object visitIntLiteral(IntLiteral node, arg) => node.value;
Object visitDoubleLiteral(DoubleLiteral node, arg) => node.value;
Object visitBoolLiteral(BoolLiteral node, arg) => node.value;
Object visitNullLiteral(NullLiteral node, arg) => node.value;
}

View file

@ -318,3 +318,66 @@ class Transformer extends TreeVisitor<TreeNode> {
return node;
}
}
abstract class ExpressionVisitor1<R> {
R defaultExpression(Expression node, arg) => null;
R defaultBasicLiteral(BasicLiteral node, arg) => defaultExpression(node, arg);
R visitInvalidExpression(InvalidExpression node, arg) =>
defaultExpression(node, arg);
R visitVariableGet(VariableGet node, arg) => defaultExpression(node, arg);
R visitVariableSet(VariableSet node, arg) => defaultExpression(node, arg);
R visitPropertyGet(PropertyGet node, arg) => defaultExpression(node, arg);
R visitPropertySet(PropertySet node, arg) => defaultExpression(node, arg);
R visitDirectPropertyGet(DirectPropertyGet node, arg) =>
defaultExpression(node, arg);
R visitDirectPropertySet(DirectPropertySet node, arg) =>
defaultExpression(node, arg);
R visitSuperPropertyGet(SuperPropertyGet node, arg) =>
defaultExpression(node, arg);
R visitSuperPropertySet(SuperPropertySet node, arg) =>
defaultExpression(node, arg);
R visitStaticGet(StaticGet node, arg) => defaultExpression(node, arg);
R visitStaticSet(StaticSet node, arg) => defaultExpression(node, arg);
R visitMethodInvocation(MethodInvocation node, arg) =>
defaultExpression(node, arg);
R visitDirectMethodInvocation(DirectMethodInvocation node, arg) =>
defaultExpression(node, arg);
R visitSuperMethodInvocation(SuperMethodInvocation node, arg) =>
defaultExpression(node, arg);
R visitStaticInvocation(StaticInvocation node, arg) =>
defaultExpression(node, arg);
R visitConstructorInvocation(ConstructorInvocation node, arg) =>
defaultExpression(node, arg);
R visitNot(Not node, arg) => defaultExpression(node, arg);
R visitLogicalExpression(LogicalExpression node, arg) =>
defaultExpression(node, arg);
R visitConditionalExpression(ConditionalExpression node, arg) =>
defaultExpression(node, arg);
R visitStringConcatenation(StringConcatenation node, arg) =>
defaultExpression(node, arg);
R visitIsExpression(IsExpression node, arg) => defaultExpression(node, arg);
R visitAsExpression(AsExpression node, arg) => defaultExpression(node, arg);
R visitSymbolLiteral(SymbolLiteral node, arg) => defaultExpression(node, arg);
R visitTypeLiteral(TypeLiteral node, arg) => defaultExpression(node, arg);
R visitThisExpression(ThisExpression node, arg) =>
defaultExpression(node, arg);
R visitRethrow(Rethrow node, arg) => defaultExpression(node, arg);
R visitThrow(Throw node, arg) => defaultExpression(node, arg);
R visitListLiteral(ListLiteral node, arg) => defaultExpression(node, arg);
R visitMapLiteral(MapLiteral node, arg) => defaultExpression(node, arg);
R visitAwaitExpression(AwaitExpression node, arg) =>
defaultExpression(node, arg);
R visitFunctionExpression(FunctionExpression node, arg) =>
defaultExpression(node, arg);
R visitStringLiteral(StringLiteral node, arg) =>
defaultBasicLiteral(node, arg);
R visitIntLiteral(IntLiteral node, arg) => defaultBasicLiteral(node, arg);
R visitDoubleLiteral(DoubleLiteral node, arg) =>
defaultBasicLiteral(node, arg);
R visitBoolLiteral(BoolLiteral node, arg) => defaultBasicLiteral(node, arg);
R visitNullLiteral(NullLiteral node, arg) => defaultBasicLiteral(node, arg);
R visitLet(Let node, arg) => defaultExpression(node, arg);
R visitLoadLibrary(LoadLibrary node, arg) => defaultExpression(node, arg);
R visitCheckLibraryIsLoaded(CheckLibraryIsLoaded node, arg) =>
defaultExpression(node, arg);
}