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

Unified Diff: pkg/kernel/lib/interpreter/interpreter.dart

Issue 2764823002: Add representation for object values (Closed)
Patch Set: Add TODO for class representation naming Created 3 years, 9 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/kernel/lib/interpreter/interpreter.dart
diff --git a/pkg/kernel/lib/interpreter/interpreter.dart b/pkg/kernel/lib/interpreter/interpreter.dart
index c6c5881a1a2c8591e210b371ed056ebbc6343a8f..ea8f0186d1caf2ce425e50666a9d2a3f7bbae838 100644
--- a/pkg/kernel/lib/interpreter/interpreter.dart
+++ b/pkg/kernel/lib/interpreter/interpreter.dart
@@ -1,7 +1,7 @@
// 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;
+library kernel.interpreter;
import '../ast.dart';
@@ -124,38 +124,55 @@ class Evaluator extends ExpressionVisitor1<Value> {
// Special evaluation of print.
var res = eval(node.arguments.positional[0], env);
print(res.value);
- return new NullValue();
+ return Value.nullInstance;
} else {
throw new NotImplemented('Support for statement type '
'${node.runtimeType} is not implemented');
}
}
+ Value visitMethodInvocation(MethodInvocation node, env) {
+ // Currently supports only method invocation with <2 arguments and is used
+ // to evaluate implemented operators for int, double and String values.
+ var receiver = eval(node.receiver, env);
+ if (node.arguments.positional.isNotEmpty) {
+ var argValue = eval(node.arguments.positional.first, env);
+ return receiver.invokeMethod(node.name.name, argValue);
+ } else {
+ return receiver.invokeMethod(node.name.name);
+ }
+ }
+
+ Value visitConstructorInvocation(ConstructorInvocation node, env) =>
+ defaultExpression(node, env);
+
Value visitNot(Not node, env) {
- return new BoolValue(!eval(node.operand, env).asBool);
+ Value operand = eval(node.operand, env).toBoolean();
+ return identical(operand, Value.trueInstance)
+ ? Value.falseInstance
+ : Value.trueInstance;
}
Value visitLogicalExpression(LogicalExpression node, env) {
if ('||' == node.operator) {
- bool left = eval(node.left, env).asBool;
- return left
- ? new BoolValue(true)
- : new BoolValue(eval(node.right, env).asBool);
+ BoolValue left = eval(node.left, env).toBoolean();
+ return identical(left, Value.trueInstance)
+ ? Value.trueInstance
+ : eval(node.right, env).toBoolean();
} else {
assert('&&' == node.operator);
- bool left = eval(node.left, env).asBool;
- return !left
- ? new BoolValue(false)
- : new BoolValue(eval(node.right, env).asBool);
+ BoolValue left = eval(node.left, env).toBoolean();
+ return identical(left, Value.falseInstance)
+ ? Value.falseInstance
+ : eval(node.right, env).toBoolean();
}
}
Value visitConditionalExpression(ConditionalExpression node, env) {
- if (eval(node.condition, env).asBool) {
- return eval(node.then, env);
- } else {
- return eval(node.otherwise, env);
- }
+ var condition = eval(node.condition, env).toBoolean();
+ return identical(condition, Value.trueInstance)
+ ? eval(node.then, env)
+ : eval(node.otherwise, env);
}
Value visitStringConcatenation(StringConcatenation node, env) {
@@ -172,8 +189,9 @@ class Evaluator extends ExpressionVisitor1<Value> {
Value visitIntLiteral(IntLiteral node, env) => new IntValue(node.value);
Value visitDoubleLiteral(DoubleLiteral node, env) =>
new DoubleValue(node.value);
- Value visitBoolLiteral(BoolLiteral node, env) => new BoolValue(node.value);
- Value visitNullLiteral(NullLiteral node, env) => new NullValue();
+ Value visitBoolLiteral(BoolLiteral node, env) =>
+ node.value ? Value.trueInstance : Value.falseInstance;
+ Value visitNullLiteral(NullLiteral node, env) => Value.nullInstance;
Value visitLet(Let node, env) {
var value = eval(node.variable.initializer, env);
@@ -183,49 +201,161 @@ class Evaluator extends ExpressionVisitor1<Value> {
}
}
+// TODO(zhivkag): Change misleading name.
+// This is representation of a class in the interpreter, not a declaration.
+class ClassDeclaration {
+ static final Map<Reference, ClassDeclaration> _classes =
+ <Reference, ClassDeclaration>{};
+
+ Class currentClass;
+ ClassDeclaration superClass;
+ // The initializers of static fields are evaluated the first time the field
+ // is accessed.
+ List<Value> staticFields = <Value>[];
+ List<Procedure> getters = <Procedure>[];
+ List<Procedure> setters = <Procedure>[];
+ List<Procedure> methods = <Procedure>[];
+
+ factory ClassDeclaration(Reference classRef) {
+ if (_classes.containsKey(classRef)) {
+ return _classes[classRef];
+ }
+ _classes[classRef] = new ClassDeclaration._internal(classRef.asClass);
+ return _classes[classRef];
+ }
+
+ ClassDeclaration._internal(this.currentClass) {
+ if (currentClass.superclass != null) {
+ superClass = new ClassDeclaration(currentClass.superclass.reference);
+ }
+ // TODO: Populate getters, setters and methods.
+ }
+}
+
abstract class Value {
Object get value;
- bool get asBool;
+
+ static final NullValue nullInstance = const NullValue();
+ static final BoolValue trueInstance = const BoolValue(true);
+ static final BoolValue falseInstance = const BoolValue(false);
+
+ const Value();
+
+ BoolValue toBoolean() {
+ return identical(this, Value.trueInstance)
+ ? Value.trueInstance
+ : Value.falseInstance;
+ }
+
+ BoolValue equals(Value other) =>
+ value == other.value ? Value.trueInstance : Value.falseInstance;
+
+ Value invokeMethod(String name, [Value arg]) {
+ throw notImplemented(obj: name);
+ }
+}
+
+class ObjectValue extends Value {
+ List<Value> fields;
+ ClassDeclaration classDeclaration;
+
+ Object get value => this;
+
+ ObjectValue(Constructor constructor, Environment env) {
+ // TODO: Init fields and eval initializers, repeat the same with super.
+ // TODO: Eval the Function body of the constructor, with env expanded with
+ // {VariableDeclaration("this") => this}
+ notImplemented(obj: constructor.name);
+ }
}
class StringValue extends Value {
- String value;
+ final String value;
- bool get asBool => false;
+ static final operators = <String, Function>{
+ '[]': (StringValue v1, Value v2) => v1[v2],
+ '==': (StringValue v1, Value v2) => v1.equals(v2)
+ };
StringValue(this.value);
+
+ Value invokeMethod(String name, [Value arg]) {
+ if (!operators.containsKey(name)) {
+ return notImplemented(obj: name);
+ }
+ return operators[name](this, arg);
+ }
+
+ // Operators
+ Value operator [](Value index) => new StringValue(value[index.value]);
}
-class IntValue extends Value {
- int value;
+abstract class NumValue extends Value {
+ num get value;
- bool get asBool => false;
+ NumValue();
- IntValue(this.value);
+ factory NumValue.fromValue(num value) {
+ if (value is int) {
+ return new IntValue(value);
+ } else {
+ assert(value is double);
+ return new DoubleValue(value);
+ }
+ }
+
+ static final operators = <String, Function>{
+ '+': (NumValue v1, Value v2) => v1 + v2,
+ '-': (NumValue v1, Value v2) => v1 - v2,
+ '>': (NumValue v1, Value v2) => v1 > v2,
+ '<': (NumValue v1, Value v2) => v1 < v2,
+ '==': (NumValue v1, Value v2) => v1.equals(v2),
+ 'unary-': (NumValue v1) => -v1,
+ };
+
+ Value invokeMethod(String name, [Value arg]) {
+ if (!operators.containsKey(name)) return notImplemented(obj: name);
+ if (arg == null) return operators[name](this);
+ return operators[name](this, arg);
+ }
+
+ // Operators
+ NumValue operator +(Value other) =>
+ new NumValue.fromValue(value + other.value);
+ NumValue operator -(Value other) =>
+ new NumValue.fromValue(value - other.value);
+ NumValue operator -() => new NumValue.fromValue(-value);
+
+ BoolValue operator >(Value other) =>
+ value > other.value ? Value.trueInstance : Value.falseInstance;
+ BoolValue operator <(Value other) =>
+ value < other.value ? Value.trueInstance : Value.falseInstance;
}
-class DoubleValue extends Value {
- double value;
+class IntValue extends NumValue {
+ final int value;
- bool get asBool => false;
+ IntValue(this.value);
+}
+
+class DoubleValue extends NumValue {
+ final double value;
DoubleValue(this.value);
}
class BoolValue extends Value {
- bool value;
+ final bool value;
- bool get asBool => value;
-
- BoolValue(this.value);
+ const BoolValue(this.value);
}
class NullValue extends Value {
Object get value => null;
- bool get asBool => false;
+
+ const NullValue();
}
-Object error(obj) {
- // TODO: Implement accordingly with support for error handling.
- throw new ArgumentError(obj);
+notImplemented({String m, Object obj}) {
+ throw new NotImplemented(m ?? 'Evaluation for $obj is not implemented');
}
« 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