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 + -
显示快捷键?