idlexpr.cc

来自「编译工具」· CC 代码 · 共 1,234 行 · 第 1/3 页

CC
1,234
字号
#endif  default:    r = 1.0;    char* ssn = scopedName_->toString();    IdlError(file(), line(), "Cannot interpret constant '%s' as float", ssn);    IdlErrorCont(c_->file(), c_->line(), "(%s declared here)", ssn);    delete [] ssn;  }  if (IdlFPOverflow(r)) {    char* ssn = scopedName_->toString();    IdlError(file(), line(), "Value of constant '%s' overflows float", ssn);    IdlErrorCont(c_->file(), c_->line(), "(%s declared here)", ssn);    delete [] ssn;  }  return r;}IDL_Double ConstExpr::evalAsDouble() {  IDL_Double r;  switch (c_->constKind()) {#ifndef __VMS  case IdlType::tk_float:      r = c_->constAsFloat();      break;#else  case IdlType::tk_float:      r = (double)(float)c_->constAsFloat(); break;#endif  case IdlType::tk_double:     r = c_->constAsDouble();     break;#ifdef HAS_LongDouble  case IdlType::tk_longdouble: r = c_->constAsLongDouble(); break;#endif  default:    r = 1.0;    char* ssn = scopedName_->toString();    IdlError(file(), line(), "Cannot interpret constant '%s' as double", ssn);    IdlErrorCont(c_->file(), c_->line(), "(%s declared here)", ssn);    delete [] ssn;  }  if (IdlFPOverflow(r)) {    char* ssn = scopedName_->toString();    IdlError(file(), line(), "Value of constant '%s' overflows double", ssn);    IdlErrorCont(c_->file(), c_->line(), "(%s declared here)", ssn);    delete [] ssn;  }  return r;}#ifdef HAS_LongDoubleIDL_LongDouble ConstExpr::evalAsLongDouble() {  IDL_LongDouble r;  switch (c_->constKind()) {  case IdlType::tk_float:      r = c_->constAsFloat();      break;  case IdlType::tk_double:     r = c_->constAsDouble();     break;  case IdlType::tk_longdouble: r = c_->constAsLongDouble(); break;  default:    r = 1.0;    char* ssn = scopedName_->toString();    IdlError(file(), line(),	     "Cannot interpret constant '%s' as long double", ssn);    IdlErrorCont(c_->file(), c_->line(), "(%s declared here)", ssn);    delete [] ssn;  }  if (IdlFPOverflow(r)) { // Don't see how this could happen...    char* ssn = scopedName_->toString();    IdlError(file(), line(),	     "Value of constant '%s' overflows long double", ssn);    IdlErrorCont(c_->file(), c_->line(), "(%s declared here)", ssn);    delete [] ssn;  }  return r;}#endif // HAS_LongDouble#define CONST_EXPR_EVAL(rt, eop, tk, cop, str, rv) \rt ConstExpr::eop() { \  if (c_->constKind() == IdlType::tk) \    return c_->cop(); \  else { \    char* ssn = scopedName_->toString(); \    IdlError(file(), line(), \	     "Cannot interpret constant '%s' as " str, ssn); \    IdlErrorCont(c_->file(), c_->line(), "(%s declared here)", ssn); \    delete [] ssn; \  } \  return rv; \}CONST_EXPR_EVAL(IDL_Boolean, evalAsBoolean, tk_boolean,		constAsBoolean, "boolean", 0)CONST_EXPR_EVAL(IDL_Char, evalAsChar, tk_char,		constAsChar, "character", '!')CONST_EXPR_EVAL(const char*, evalAsString, tk_string,		constAsString, "string", "!")CONST_EXPR_EVAL(IDL_WChar, evalAsWChar, tk_wchar,		constAsWChar, "wide character", '!')CONST_EXPR_EVAL(const IDL_WChar*, evalAsWString, tk_wstring,		constAsWString, "wide string", EMPTY_WSTRING)CONST_EXPR_EVAL(IDL_Fixed*, evalAsFixed, tk_fixed,		constAsFixed, "fixed", new IDL_Fixed("1"))Enumerator* ConstExpr::evalAsEnumerator(const Enum* target) {  if (c_->constKind() == IdlType::tk_enum) {    Enumerator* e = c_->constAsEnumerator();    if (e->container() != target) {      char* ssn = target->scopedName()->toString();      IdlError(file(), line(), "Enumerator '%s' does not belong to enum '%s'",	       e->identifier(), ssn);      delete [] ssn;      ssn = e->container()->scopedName()->toString();      IdlErrorCont(e->file(), e->line(),		   "(Enumerator '%s' declared in '%s' here)",		   e->identifier(), ssn);      delete [] ssn;    }    return c_->constAsEnumerator();  }  else {    char* ssn = scopedName_->toString();    IdlError(file(), line(),	     "Cannot interpret constant '%s' as enumerator", ssn);    IdlErrorCont(c_->file(), c_->line(), "(%s declared here)", ssn);    delete [] ssn;  }  return 0;}// Binary expressions// OrIdlLongVal OrExpr::evalAsLongV() {  IdlLongVal a = a_->evalAsLongV();  IdlLongVal b = b_->evalAsLongV();  if (a.negative)    return IdlLongVal(IDL_Long(a.s | b.s));  else    return IdlLongVal(IDL_ULong(a.u | b.u));}#ifdef HAS_LongLongIdlLongLongVal OrExpr::evalAsLongLongV() {  IdlLongLongVal a = a_->evalAsLongLongV();  IdlLongLongVal b = b_->evalAsLongLongV();  if (a.negative)    return IdlLongLongVal(IDL_LongLong(a.s | b.s));  else    return IdlLongLongVal(IDL_ULongLong(a.u | b.u));}#endif// XorIdlLongVal XorExpr::evalAsLongV() {  IdlLongVal a = a_->evalAsLongV();  IdlLongVal b = b_->evalAsLongV();  if (a.negative)    return IdlLongVal(IDL_Long(a.s ^ b.s));  else    return IdlLongVal(IDL_ULong(a.u ^ b.u));}#ifdef HAS_LongLongIdlLongLongVal XorExpr::evalAsLongLongV() {  IdlLongLongVal a = a_->evalAsLongLongV();  IdlLongLongVal b = b_->evalAsLongLongV();  if (a.negative)    return IdlLongLongVal(IDL_LongLong(a.s ^ b.s));  else    return IdlLongLongVal(IDL_ULongLong(a.u ^ b.u));}#endif// AndIdlLongVal AndExpr::evalAsLongV() {  IdlLongVal a = a_->evalAsLongV();  IdlLongVal b = b_->evalAsLongV();  if (a.negative)    return IdlLongVal(IDL_Long(a.s & b.s));  else    return IdlLongVal(IDL_ULong(a.u & b.u));}#ifdef HAS_LongLongIdlLongLongVal AndExpr::evalAsLongLongV() {  IdlLongLongVal a = a_->evalAsLongLongV();  IdlLongLongVal b = b_->evalAsLongLongV();  if (a.negative)    return IdlLongLongVal(IDL_LongLong(a.s & b.s));  else    return IdlLongLongVal(IDL_ULongLong(a.u & b.u));}#endif// Right shiftIdlLongVal RShiftExpr::evalAsLongV() {  IdlLongVal a = a_->evalAsLongV();  IdlLongVal b = b_->evalAsLongV();  // Assume two's complement, and treat b as unsigned. If it's  // actually signed and negative, its unsigned value will be much >  // 64.  if (b.u >= 64) {    IdlError(file(), line(),	     "Right operand of shift operation must be >= 0 and < 64");    return a;  }  if (a.negative)    return IdlLongVal(IDL_Long(a.s >> b.u));  else    return IdlLongVal(IDL_ULong(a.u >> b.u));}#ifdef HAS_LongLongIdlLongLongVal RShiftExpr::evalAsLongLongV() {  IdlLongLongVal a = a_->evalAsLongLongV();  IdlLongLongVal b = b_->evalAsLongLongV();  if (b.u >= 64) {    IdlError(file(), line(),	     "Right operand of shift operation must be >= 0 and < 64");    return a;  }  if (a.negative)    return IdlLongLongVal(IDL_LongLong(a.s >> b.u));  else    return IdlLongLongVal(IDL_ULongLong(a.u >> b.u));}#endif// Left shiftIdlLongVal LShiftExpr::evalAsLongV() {  IdlLongVal a = a_->evalAsLongV();  IdlLongVal b = b_->evalAsLongV();  if (b.u >= 64) {    IdlError(file(), line(),	     "Right operand of shift operation must be >= 0 and < 64");    return a;  }  if (a.negative)    return IdlLongVal(IDL_Long(a.s << b.u));  else    return IdlLongVal(IDL_ULong(a.u << b.u));}#ifdef HAS_LongLongIdlLongLongVal LShiftExpr::evalAsLongLongV() {  IdlLongLongVal a = a_->evalAsLongLongV();  IdlLongLongVal b = b_->evalAsLongLongV();  if (b.u >= 64) {    IdlError(file(), line(),	     "Right operand of shift operation must be >= 0 and < 64");    return a;  }  if (a.negative)    return IdlLongLongVal(IDL_LongLong(a.s << b.u));  else    return IdlLongLongVal(IDL_ULongLong(a.u << b.u));}#endif// %IdlLongVal ModExpr::evalAsLongV() {  IdlLongVal a = a_->evalAsLongV();  IdlLongVal b = b_->evalAsLongV();  if (b.u == 0) {    IdlError(file(), line(), "Remainder of division by 0 is undefined");    return a;  }  if (a.negative || b.negative)    IdlWarning(file(), line(), "Result of %% operator involving negative "	       "operands is implementation dependent");  switch ((a.negative ? 1:0) + (b.negative ? 2:0)) {  case 0: return IdlLongVal(IDL_ULong(a.u % b.u));  case 1: return IdlLongVal(-IDL_Long((-a.s) % b.u));  case 2: return IdlLongVal(IDL_ULong(a.u % IDL_ULong(-b.s)));  case 3: return IdlLongVal(-IDL_Long((-a.s) % (-b.s)));  }  return IdlLongVal(IDL_ULong(0)); // Never reach here}#ifdef HAS_LongLongIdlLongLongVal ModExpr::evalAsLongLongV() {  IdlLongLongVal a = a_->evalAsLongLongV();  IdlLongLongVal b = b_->evalAsLongLongV();  if (b.u == 0) {    IdlError(file(), line(), "Remainder of division by 0 is undefined");    return a;  }  if (a.negative || b.negative)    IdlWarning(file(), line(), "Result of %% operator involving negative "	       "operands is platform dependent");  switch ((a.negative ? 1:0) + (b.negative ? 2:0)) {  case 0: return IdlLongLongVal(IDL_ULongLong(a.u % b.u));  case 1: return IdlLongLongVal(IDL_LongLong (a.s % b.u));  case 2: return IdlLongLongVal(IDL_LongLong (a.u % b.s));  case 3: return IdlLongLongVal(IDL_LongLong (a.s % b.s));  }  return IdlLongLongVal(IDL_ULongLong(0)); // Never reach here}#endif// AddIdlLongVal AddExpr::evalAsLongV() {  IdlLongVal a = a_->evalAsLongV();  IdlLongVal b = b_->evalAsLongV();  switch ((a.negative ? 1:0) + (b.negative ? 2:0)) {  case 0:    {      IDL_ULong r = a.u + b.u;      if (r < a.u) goto overflow;      return IdlLongVal(r);    }  case 1:    {      if (IDL_ULong(-a.s) < b.u)	return IdlLongVal(b.u - IDL_ULong(-a.s));      else	return IdlLongVal(a.s + IDL_Long(b.u));    }  case 2:    {      if (IDL_ULong(-b.s) < a.u)	return IdlLongVal(a.u - IDL_ULong(-b.s));      else	return IdlLongVal(IDL_Long(a.u) + b.s);    }  case 3:    {      IDL_Long r = a.s + b.s;      if (r > a.s) goto overflow;      return IdlLongVal(r);    }  } overflow:  IdlError(file(), line(), "Result of addition overflows");  return a;}#ifdef HAS_LongLongIdlLongLongVal AddExpr::evalAsLongLongV() {  IdlLongLongVal a = a_->evalAsLongLongV();  IdlLongLongVal b = b_->evalAsLongLongV();  switch ((a.negative ? 1:0) + (b.negative ? 2:0)) {  case 0:    {      IDL_ULongLong r = a.u + b.u;      if (r < a.u) goto overflow;      return IdlLongLongVal(r);    }  case 1:    {      if (IDL_ULongLong(-a.s) < b.u)	return IdlLongLongVal(b.u - IDL_ULongLong(-a.s));      else	return IdlLongLongVal(a.s + IDL_LongLong(b.u));    }  case 2:    {      if (IDL_ULongLong(-b.s) < a.u)	return IdlLongLongVal(a.u - IDL_ULongLong(-b.s));      else	return IdlLongLongVal(IDL_LongLong(a.u) + b.s);    }  case 3:    {      IDL_LongLong r = a.s + b.s;      if (r > a.s) goto overflow;      return IdlLongLongVal(r);    }  } overflow:  IdlError(file(), line(), "Result of addition overflows");  return a;}#endif#define ADD_EXPR_EVAL_F(ret, op, str) \ret AddExpr::op() { \  ret a, b, r; \  a = a_->op(); b = b_->op(); \  r = a+b; \  if (IdlFPOverflow(r)) { \    IdlError(file(), line(), "Result of addition overflows " str); \    r = 1.0; \  } \  return r; \}ADD_EXPR_EVAL_F(IDL_Float,      evalAsFloat,      "float")ADD_EXPR_EVAL_F(IDL_Double,     evalAsDouble,     "double")#ifdef HAS_LongDoubleADD_EXPR_EVAL_F(IDL_LongDouble, evalAsLongDouble, "long double")#endifIDL_Fixed* AddExpr::evalAsFixed() {  IDL_Fixed *a, *b, *r;  a = a_->evalAsFixed(); b = b_->evalAsFixed();  try {    r = new IDL_Fixed(*a + *b);  }  catch (IDL_Fixed::Overflow&) {    IdlError(file(), line(), "Result of addition overflows fixed digits");

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?