double Evaluator::eval(BinaryOp &e) { double left = e.getLeft()->eval(*this); double right = e.getRight()->eval(*this); if (right == 0 && (e.getType() == Operator::DIV_OP || e.getType() == Operator::MOD_OP)) { LOG_ERROR(e.getLocation() << ": Divide by zero"); return 0; } // NOTE, LinuxCNC handles floating-point equality differently. // See ``Equality and floating-point values``. switch (e.getType()) { case Operator::EXP_OP: return pow(left, right); case Operator::MUL_OP: return left * right; case Operator::DIV_OP: return left / right; case Operator::MOD_OP: return fmod(left, right); case Operator::ADD_OP: return left + right; case Operator::SUB_OP: return left - right; case Operator::EQ_OP: return left == right; case Operator::NE_OP: return left != right; case Operator::GT_OP: return left > right; case Operator::GE_OP: return left >= right; case Operator::LT_OP: return left < right; case Operator::LE_OP: return left <= right; case Operator::AND_OP: return left && right; case Operator::OR_OP: return left || right; case Operator::XOR_OP: return (bool)left ^ (bool)right; default: THROW(e.getLocation() << " Invalid binary operator"); } }
double Evaluator::eval(BinaryOp &e) { double left = e.getLeft()->eval(*this); double right = e.getRight()->eval(*this); if (right == 0 && (e.getType() == Operator::DIV_OP || e.getType() == Operator::MOD_OP)) { LOG_ERROR(e.getLocation() << ": Divide by zero"); return 0; } switch (e.getType()) { case Operator::EXP_OP: return pow(left, right); case Operator::MUL_OP: return left * right; case Operator::DIV_OP: return left / right; case Operator::MOD_OP: return fmod(left, right); case Operator::ADD_OP: return left + right; case Operator::SUB_OP: return left - right; case Operator::EQ_OP: return left == right; case Operator::NE_OP: return left != right; case Operator::GT_OP: return left > right; case Operator::GE_OP: return left >= right; case Operator::LT_OP: return left < right; case Operator::LE_OP: return left <= right; case Operator::AND_OP: return left && right; case Operator::OR_OP: return left || right; case Operator::XOR_OP: return (bool)left ^ (bool)right; default: THROWS(e.getLocation() << " Invalid binary operator"); } }
int Expr::evaluateAsInteger(){ if (isIntExpr()){ return ((IntExpr*)this)->getValue(); } if (isBinaryExpr()){ BinaryExpr* binExpr = (BinaryExpr*)this; int e1 = binExpr->getE1()->evaluateAsInteger(); int e2 = binExpr->getE1()->evaluateAsInteger(); BinaryOp* op = binExpr->getOp(); switch(op->getType()){ case BinaryOp::TIMES: return e1*e2; break; case BinaryOp::MINUS: return e1-e2; break; case BinaryOp::PLUS: return e1+e2; break; default : cerr << "Unsupported binary expression for evaluation" << endl; exit(1); } } cerr << "Can't evaluate this expression"; exit(1); }