示例#1
0
文件: Expression.cpp 项目: orcc/jade
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);
}
示例#2
0
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");
  }
}
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");
  }
}
std::string BinopToString(std::ostream &os, const BinaryOp &x) {
  std::string left = RvalueToString(os, x.left());
  std::string right = RvalueToString(os, x.right());
  std::string op;
  switch (x.op()) {
  case BinaryOp::PLUS:
    op = "add";
    break;
  case BinaryOp::MINUS:
    op = "sub";
    break;
  case BinaryOp::MUL:
    op = "mul";
    break;
  case BinaryOp::XOR:
    op = "xor";
    break;
  case BinaryOp::AND:
    op = "and";
    break;
  case BinaryOp::OR:
    op = "or";
    break;
  // Support for Boolean operators will be added later
  case BinaryOp::EQ:
  case BinaryOp::NE:
  case BinaryOp::LE:
  case BinaryOp::GE:
  case BinaryOp::LT:
  case BinaryOp::GT:
    op = "add";
    break;
  }
  std::string val_var = get_var();
  os << val_var << " = " << op << " i32 " << left << ", " << right << "\n";
  return val_var;
}