idlexpr.cc

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

CC
1,234
字号
// -*- c++ -*-//                          Package   : omniidl// idlexpr.cc               Created on: 1999/10/18//			    Author    : Duncan Grisby (dpg1)////    Copyright (C) 1999 AT&T Laboratories Cambridge////  This file is part of omniidl.////  omniidl is free software; you can redistribute it and/or modify it//  under the terms of the GNU General Public License as published by//  the Free Software Foundation; either version 2 of the License, or//  (at your option) any later version.////  This program is distributed in the hope that it will be useful,//  but WITHOUT ANY WARRANTY; without even the implied warranty of//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU//  General Public License for more details.////  You should have received a copy of the GNU General Public License//  along with this program; if not, write to the Free Software//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA//  02111-1307, USA.//// Description://   //   Expression evaluation functions// $Id: idlexpr.cc,v 1.6.2.6 2001/10/17 16:48:33 dpg1 Exp $// $Log: idlexpr.cc,v $// Revision 1.6.2.6  2001/10/17 16:48:33  dpg1// Minor error message tweaks//// Revision 1.6.2.5  2001/08/29 11:54:20  dpg1// Clean up const handling in IDL compiler.//// Revision 1.6.2.4  2001/03/13 10:32:11  dpg1// Fixed point support.//// Revision 1.6.2.3  2000/10/27 16:31:09  dpg1// Clean up of omniidl dependencies and types, from omni3_develop.//// Revision 1.6.2.2  2000/10/10 10:18:50  dpg1// Update omniidl front-end from omni3_develop.//// Revision 1.4.2.2  2000/08/07 15:34:36  dpg1// Partial back-port of long long from omni3_1_develop.//// Revision 1.4.2.1  2000/06/27 16:00:17  sll// Fixes to WIN 32 related build and compiler issues.//// Revision 1.4  2000/02/04 12:17:09  dpg1// Support for VMS.//// Revision 1.3  1999/11/02 17:07:26  dpg1// Changes to compile on Solaris.//// Revision 1.2  1999/10/29 10:01:31  dpg1// Nicer error reporting.//// Revision 1.1  1999/10/27 14:05:57  dpg1// *** empty log message ***//#include <idlexpr.h>#include <idlerr.h>#include <idlmath.h>#include <idlast.h>const IDL_WChar EMPTY_WSTRING[] = {'!', 0};#define EXPR_ERR(rt, fn, str, rv) \rt IdlExpr::fn() { \  IdlError(file(), line(), "Cannot interpret %s as " str, errText()); \  return rv; \}// Error functionsEXPR_ERR(IdlLongVal, evalAsLongV, "an integer", IdlLongVal((IDL_ULong)1))#ifdef HAS_LongLongEXPR_ERR(IdlLongLongVal, evalAsLongLongV, "an integer",         IdlLongLongVal((IDL_ULongLong)1))#endifEXPR_ERR(IDL_Float,        evalAsFloat,      "a float",               1.0)EXPR_ERR(IDL_Double,       evalAsDouble,     "a double",              1.0)EXPR_ERR(IDL_Boolean,      evalAsBoolean,    "a boolean",             0)EXPR_ERR(IDL_Char,         evalAsChar,       "a character",           '!')EXPR_ERR(const char*,      evalAsString,     "a string",              "!")#ifdef HAS_LongDoubleEXPR_ERR(IDL_LongDouble,   evalAsLongDouble, "a long double",         1.0)#endifEXPR_ERR(IDL_WChar,        evalAsWChar,      "a wide character",      '!')EXPR_ERR(const IDL_WChar*, evalAsWString,    "a wide string", EMPTY_WSTRING)EXPR_ERR(IDL_Fixed*,       evalAsFixed,      "fixed point", new IDL_Fixed("1"))Enumerator*IdlExpr::evalAsEnumerator(const Enum* target){  IdlError(file(), line(), "Cannot interpret %s as enumerator", errText());  return 0;}//// Conversions to IDL integer typesIDL_Short IdlExpr::evalAsShort(){  IdlLongVal v = evalAsLongV();  if (v.negative) {    if (v.s < -0x8000)      IdlError(file(), line(), "Value too small for short");    return v.s;  }  else {    if (v.u > 0x7fff)      IdlError(file(), line(), "Value too large for short");    return v.u;  }}IDL_Long IdlExpr::evalAsLong(){  IdlLongVal v = evalAsLongV();  if (v.negative) {    return v.s;  }  else {    if (v.u > 0x7fffffff)      IdlError(file(), line(), "Value too large for long");    return v.u;  }}IDL_UShort IdlExpr::evalAsUShort(){  IdlLongVal v = evalAsLongV();  if (v.negative) {    IdlError(file(), line(), "Value too small for unsigned short");  }  else if (v.u > 0xffff) {    IdlError(file(), line(), "Value too large for unsigned short");  }  return v.u;}IDL_ULong IdlExpr::evalAsULong(){  IdlLongVal v = evalAsLongV();  if (v.negative) {    IdlError(file(), line(), "Value too small for unsigned long");  }  return v.u;}IDL_Octet IdlExpr::evalAsOctet(){  IdlLongVal v = evalAsLongV();  if (v.negative) {    IdlError(file(), line(), "Value too small for octet");  }  else if (v.u > 0xff) {    IdlError(file(), line(), "Value too large for octet");  }  return v.u;}#ifdef HAS_LongLongIDL_LongLong IdlExpr::evalAsLongLong(){  IdlLongLongVal v = evalAsLongLongV();  if (v.negative) {    return v.s;  }  else {    if (v.u > _CORBA_LONGLONG_CONST(0x7fffffffffffffff))      IdlError(file(), line(), "Value too large for long long");    return v.u;  }}IDL_ULongLong IdlExpr::evalAsULongLong(){  IdlLongLongVal v = evalAsLongLongV();  if (v.negative) {    IdlError(file(), line(), "Value too small for unsigned long long");  }  return v.u;}#endif// ScopedName handlingIdlExpr*IdlExpr::scopedNameToExpr(const char* file, int line, ScopedName* sn){  const Scope::Entry* se = Scope::current()->findForUse(sn, file, line);  if (se) {    if (se->kind() == Scope::Entry::E_DECL &&	se->decl()->kind() == Decl::D_ENUMERATOR) {      return new EnumExpr(file, line, (Enumerator*)se->decl(), sn);    }    else if (se->kind() == Scope::Entry::E_DECL &&	se->decl()->kind() == Decl::D_CONST) {      return new ConstExpr(file, line, (Const*)se->decl(), sn);    }    else {      char* ssn = sn->toString();      IdlError(file, line, "'%s' is not valid in an expression", ssn);      IdlErrorCont(se->file(), se->line(), "('%s' declared here)", ssn);      delete [] ssn;    }  }  // If entry was not found, findScopedName() will have reported the error  return new DummyExpr(file, line);}const IDL_WChar* DummyExpr::evalAsWString() { return EMPTY_WSTRING; }// LiteralsIdlLongVal IntegerExpr::evalAsLongV() {#ifdef HAS_LongLong  if (value_ > 0xffffffff) {    IdlError(file(), line(), "Integer literal is too large for unsigned long");    return IdlLongVal((IDL_ULong)1);  }#endif  return IdlLongVal((IDL_ULong)value_);}#ifdef HAS_LongLongIdlLongLongVal IntegerExpr::evalAsLongLongV() {  return IdlLongLongVal((IDL_ULongLong)value_);}#endifconst char* StringExpr::evalAsString() {  return value_;}const IDL_WChar* WStringExpr::evalAsWString() {  return value_;}IDL_Char CharExpr::evalAsChar() {  return value_;}IDL_WChar WCharExpr::evalAsWChar() {  return value_;}IDL_Fixed* FixedExpr::evalAsFixed() {  return value_;}// FloatIDL_Float FloatExpr::evalAsFloat() {#ifndef _MSC_VER  // Use direct initialisation except for MS Visual C++, which allegedly  // does not work properly with types involving built-in types. To  // play it safe, use copy initialisation instead.  IDL_Float    f(value_);  IdlFloatLiteral g(f);#else  IDL_Float    f = value_;  IdlFloatLiteral g = f;#endif  if (f != g)    IdlWarning(file(), line(), "Loss of precision converting literal "	       "floating point value to float");  return f;}IDL_Double FloatExpr::evalAsDouble() {  IDL_Double   f = value_;#ifdef HAS_LongDouble  IdlFloatLiteral g = f;  if (f != g)    IdlWarning(file(), line(), "Loss of precision converting literal "	       "floating point value to double");#endif  return f;}#ifdef HAS_LongDoubleIDL_LongDouble FloatExpr::evalAsLongDouble() {  return value_;}#endif// BooleanIDL_Boolean BooleanExpr::evalAsBoolean() {  return value_;}// EnumeratorEnumerator* EnumExpr::evalAsEnumerator(const Enum* target) {  if (value_->container() != target) {    char* vssn = value_->scopedName()->toString();    char* essn  = target->scopedName()->toString();    IdlError(file(), line(), "Enumerator '%s' does not belong to enum '%s'",	     vssn, essn);    delete [] essn;    essn = value_->container()->scopedName()->toString();    IdlErrorCont(value_->file(), value_->line(),		 "(Enumerator '%s' declared in '%s' here)",		 vssn, essn);    delete [] essn;    delete [] vssn;  }  return value_;}// ConstantIdlLongVal ConstExpr::evalAsLongV() {  switch (c_->constKind()) {  case IdlType::tk_short:  return IdlLongVal(IDL_Long (c_->constAsShort()));  case IdlType::tk_long:   return IdlLongVal(IDL_Long (c_->constAsLong()));  case IdlType::tk_ushort: return IdlLongVal(IDL_ULong(c_->constAsUShort()));  case IdlType::tk_ulong:  return IdlLongVal(IDL_ULong(c_->constAsULong()));  case IdlType::tk_octet:  return IdlLongVal(IDL_ULong(c_->constAsOctet()));#ifdef HAS_LongLong  case IdlType::tk_longlong:    {      IDL_LongLong v = c_->constAsLongLong();      if (v < -0x80000000 || v > 0xffffffff) goto precision_error;      if (v >= 0)	return IdlLongVal(IDL_ULong(v));      else	return IdlLongVal(IDL_Long(v));    }  case IdlType::tk_ulonglong:    {      IDL_ULongLong v = c_->constAsULongLong();      if (v > 0xffffffff) goto precision_error;      return IdlLongVal(IDL_ULong(v));    }#endif  default:    {      char* ssn = scopedName_->toString();      IdlError(file(), line(),	       "Cannot interpret constant '%s' as an integer", ssn);      IdlErrorCont(c_->file(), c_->line(), "(%s declared here)", ssn);      delete [] ssn;      return IdlLongVal((IDL_ULong)1);    }  } precision_error:  char* ssn = scopedName_->toString();  IdlError(file(), line(),	   "Value of constant '%s' exceeds precision of target", ssn);  IdlErrorCont(c_->file(), c_->line(), "(%s declared here)", ssn);  delete [] ssn;  return IdlLongVal(IDL_ULong(1));}#ifdef HAS_LongLongIdlLongLongVal ConstExpr::evalAsLongLongV() {  switch (c_->constKind()) {  case IdlType::tk_short:    return IdlLongLongVal(IDL_LongLong(c_->constAsShort()));  case IdlType::tk_long:    return IdlLongLongVal(IDL_LongLong(c_->constAsLong()));  case IdlType::tk_ushort:    return IdlLongLongVal(IDL_ULongLong(c_->constAsUShort()));  case IdlType::tk_ulong:    return IdlLongLongVal(IDL_ULongLong(c_->constAsULong()));  case IdlType::tk_octet:    return IdlLongLongVal(IDL_ULongLong(c_->constAsOctet()));  case IdlType::tk_longlong:    return IdlLongLongVal(c_->constAsLongLong());  case IdlType::tk_ulonglong:    return IdlLongLongVal(c_->constAsULongLong());  default:    {      char* ssn = scopedName_->toString();      IdlError(file(), line(),	       "Cannot interpret constant '%s' as an integer", ssn);      IdlErrorCont(c_->file(), c_->line(), "(%s declared here)", ssn);      delete [] ssn;      return IdlLongLongVal((IDL_ULongLong)1);    }  }}#endif // HAS_LongLongIDL_Float ConstExpr::evalAsFloat() {  IDL_Float r;  switch (c_->constKind()) {  case IdlType::tk_float:      r = c_->constAsFloat();      break;#ifndef __VMS  case IdlType::tk_double:     r = c_->constAsDouble();     break;#else  case IdlType::tk_double:     r = (float)(double)c_->constAsDouble(); break;#endif#ifdef HAS_LongDouble  case IdlType::tk_longdouble: r = c_->constAsLongDouble(); break;

⌨️ 快捷键说明

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