public override HeronValue Eval(VM vm) { HeronValue a = operand1.Eval(vm); HeronValue b = operand2.Eval(vm); switch (opcode) { case OpCode.opEq: return(new BoolValue(a.Equals(b))); case OpCode.opNEq: return(new BoolValue(!a.Equals(b))); case OpCode.opIs: { TypeValue tv = b as TypeValue; if (tv == null) { throw new Exception("The second argument of the 'is' operator must be a type"); } return(new BoolValue(a.Is(tv.Type))); } case OpCode.opAs: { HeronType t = b as HeronType; if (t == null) { throw new Exception("The 'as' operator expects a type as a right hand argument"); } HeronValue r = a.As(t); if (r != null) { return(r); } if (t is InterfaceDefn && a is ClassInstance) { DuckValue dv = new DuckValue(a as ClassInstance, t as InterfaceDefn); return(dv); } throw new Exception("Failed to convert " + a.Type.name + " to a " + t.name); }; } return(a.InvokeBinaryOperator(vm, opcode, b)); }