Value Compiler::ExeNeg::Eval(ExeContext& x) const { Value v = a->Eval(x); if(IsNumber(v)) return -(double)v; return TypeMismatch("unary -"); }
Value Compiler::ExeDiv::Eval(ExeContext& x) const { Value v1 = a->Eval(x); Value v2 = b->Eval(x); if(IsNumber(v1) && IsNumber(v2)) return (double)v1 / (double)v2; return TypeMismatch("/"); }
Value Compiler::ExeOr::Eval(ExeContext& x) const { Value v1 = a->Eval(x); Value v2 = b->Eval(x); if(IsNumber(v1) && IsNumber(v2)) return (int)v1 | (int)v2; return TypeMismatch("|"); }
Value Compiler::ExeSra::Eval(ExeContext& x) const { Value v1 = a->Eval(x); Value v2 = b->Eval(x); if(IsNumber(v1) && IsNumber(v2)) return (int)v1 >> min(32, (int)v2); return TypeMismatch(">>"); }
Value Compiler::ExeMod::Eval(ExeContext& x) const { Value v1 = a->Eval(x); Value v2 = b->Eval(x); if(IsNumber(v1) && IsNumber(v2)) { int m = v2; if(m == 0) return Null; return (int)v1 % m; } return TypeMismatch("%"); }
static TypeMismatch make(const std::string& msg = "") { return TypeMismatch(msg + "::" + ecto::name_of<T1>() + " != " + ecto::name_of<T2>()); }