#ifndef _LITERAL_H_ #define _LITERAL_H_ #include "config.h" #include #include "common.h" // Java constants, and operations for constant folding #ifdef HAVE_INTTYPES_H # include #if defined(hpux) && defined(__STDC_32_MODE__) /* HPUX inttypes.h stupidly omits these in some cases */ typedef long long int64_t; typedef unsigned long long uint64_t; #endif typedef int64_t int64; // a 64 bit type, substitute your favourite typedef uint64_t uint64; // a 64 bit type, substitute your favourite typedef int32_t int32; // a 32 bit type, substitute your favourite typedef uint32_t uint32;// a 32 bit type, substitute your favourite typedef int16_t int16; // a 16 bit type, substitute your favourite typedef uint16_t uint16; // a java character, i.e. 16 bits unsigned typedef int8_t int8; typedef uint8_t uint8; #else /* Guess at types */ // a 64 bit type, substitute your favourite # if SIZEOF_INT == 8 typedef int int64; # elif SIZEOF_LONG == 8 typedef long int64; # elif SIZEOF_LONG_LONG == 8 typedef long long int64; # else # error no 64-bit integer type # endif // a 32 bit type, substitute your favourite # if SIZEOF_INT == 4 typedef int int32; typedef unsigned int uint32; # elif SIZEOF_SHORT == 4 typedef short int32; typedef unsigned short uint32; # else # typedef int64 int32; // better too big than too small # ?? typedef uint64 int32; // better too big than too small # endif // for these last few, we really don't have much choice typedef short int16; // a 16 bit type, substitute your favourite typedef unsigned short uint16; // a java character, i.e. 16 bits unsigned typedef signed char int8; // an 8 bit type, substitute your favorite #endif /* HAVE_INTTYPES_H */ class Literal { public: Literal() { _kind = (Common::Kind) 0; } Literal(uint16 x) { _kind = Common::CharKind; value.i = x; } Literal(int32 x) { _kind = Common::IntKind; value.i = x; } Literal(int64 x) { _kind = Common::LongKind; value.i = x; } Literal(float x) { _kind = Common::FloatKind; value.f = x; } //Literal(double x) { _kind = Common::DoubleKind; d = x; } Literal(double x, string o) { _kind = Common::DoubleKind; value.d = x; orig = o; } Literal(bool x) { _kind = Common::BoolKind; value.b = x; } Common::Kind kind() const { return _kind; } Literal cast(Common::Kind to); Literal operator~(); Literal operator!(); Literal operator-(); Literal operator*(Literal arg); Literal operator/(Literal arg); Literal operator%(Literal arg); Literal operator+(Literal arg); Literal operator-(Literal arg); Literal lsl(Literal arg); // logical shift left Literal rsl(Literal arg); // logical shift right Literal rsa(Literal arg); // arighmetic shift right // the damn g++ compiler feels like instantiating function.h on // Literal, and gets silly errors for <, <=, >, >= (in fold.cc) Literal lt(Literal arg); Literal le(Literal arg); Literal gt(Literal arg); Literal ge(Literal arg); Literal eq(Literal arg); Literal ne(Literal arg); Literal operator&(Literal arg); Literal operator|(Literal arg); Literal operator^(Literal arg); Literal operator&&(Literal arg); Literal operator||(Literal arg); // operators to extract info on the types of nodes bool boolValue() const { return value.b; } int64 intValue() const; double doubleValue() const { return kind() == Common::FloatKind ? value.f : value.d; } // Return a printed representation of this literal const string asString() const; bool isNd() const; protected: Literal arithPromote(); Literal arithPromote(Common::Kind to); Common::Kind _kind; union { int64 i; float f; double d; bool b; } value; string orig; }; ostream& operator<<(ostream& os, Literal l); // make literal from java token Literal intLiteral(const string &); Literal longLiteral(const string &); Literal floatLiteral(const string &); Literal doubleLiteral(const string &); #define IntegerKind Common::ByteKind: case Common::ShortKind: case Common::CharKind: case Common::IntKind: case Common::LongKind #endif