anchor.diff:    }
   }
   
  +// 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;
  -
  -  bool get asBool => false;
  +  final String value;
  +
  +  static final operators = <String, Function>{
  +    '[]': (StringValue v1, Value v2) => v1[v2],
  +    '==': (StringValue v1, Value v2) => v1.equals(v2)
  +  };
   
     StringValue(this.value);
  -}
  -
  -class IntValue extends Value {
  -  int value;
  -
  -  bool get asBool => false;
  +
  +  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]);
  +}
  +
  +abstract class NumValue extends Value {
  +  num get value;
  +
  +  NumValue();
  +
  +  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 IntValue extends NumValue {
  +  final int value;
   
     IntValue(this.value);
   }
   
  -class DoubleValue extends Value {
  -  double value;
  -
  -  bool get asBool => false;
  +class DoubleValue extends NumValue {
  +  final double value;
   
     DoubleValue(this.value);
   }
   
   class BoolValue extends Value {
  -  bool value;
  -
  -  bool get asBool => value;
  -
  -  BoolValue(this.value);
  +  final bool value;
  +
  +  const BoolValue(this.value);
   }
   
   class NullValue extends Value {
     Object get value => null;
  -  bool get asBool => false;
  -}
  -
  -Object error(obj) {
  -  // TODO: Implement accordingly with support for error handling.
  -  throw new ArgumentError(obj);
  -}
  +
  +  const NullValue();
  +}
  +
  +notImplemented({String m, Object obj}) {
  +  throw new NotImplemented(m ?? 'Evaluation for $obj is not implemented');
  +}
  
positive.code: // 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 '../ast.dart';
  
  
negative.code:   Value visitIntLiteral(IntLiteral node, env) => new IntValue(node.value);
    Value visitDoubleLiteral(DoubleLiteral node, env) =>
        new DoubleValue(node.value);
    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);
  