From: <ktk...@hi...> - 2003-05-04 16:57:12
|
Hi all, Is this list working? Very quiet, indeed. First of all my BIG thanks for you guys, for making OPL truly open, giving me the opportunity to scratch my long-time itch. I was very pessimistic about this in the past, and you probably cannot even imagine how much a pleasant surprise it was to hear the news. --------------------------------------------------------- OK, so here's my first input. Attached is a small patch for oplt to allow sensible translation-time casting of the OPL constants. Since I'm still in the process of learning the codebase, it might well be that I'm doing something stupid. Anyway please review it and consider merging it to the CVS tree. Currently, the casting functions of OPLT for numerical constants (i.e. TOplConstant::AsWordL() and such) work in such a way that only the "smaller" types can be cast to "larger" types, i.e. 1. Word and Long can be casted to Real. 2. Word can be casted to Long. 3. Anything else Leaves (and is handled by various traps). At the first glance this seems to be logical (and it is logical indeed), but sometimes this can become very awkward. For example the following list causes translation-time error reporting "Bad array size". CONST KSomeConstant&=300 PROC Test: LOCAL a%(KSomeConstant&) ENDP Apart from the embarrasing error message (it's actually not the size of the array), since OPLT knows (on translation-time) the value of KSomeConstant&, there's little point in rejecting the declaration like this on the sole basis that "Long can be larger than 32767". I've just added some sanity check in the casting functions to allow casting from larger types to smaller ONLY WHEN IT MAKES SENSE. Is still haven't found any occasion where this does some harm. Note that this doesn't affect the run-time type/range checking. Regards, Keita http://www.hi-ho.ne.jp/~ktkawabe/densha_e.html ------------------------------------------------------------ *** ./cvs/opl/oplt/stran/OT_UTL.CPP Sun Apr 27 13:21:38 2003 --- ./my/opl/oplt/stran/OT_UTL.CPP Sun May 04 16:15:46 2003 *************** *** 4,10 **** --- 4,15 ---- // #include "ot_std.h" + const TInt16 OPL_WORD_MIN = -32768; + const TInt16 OPL_WORD_MAX = 32767; + const TInt32 OPL_LONG_MIN = -2147483647-1; + const TInt32 OPL_LONG_MAX = 2147483647; + GLDEF_C void Panic(TOpltPanic aPanic) // // Does a Panic from withn the OPL translator *************** *** 48,72 **** // // Returns the 'word' value of a constant // { ! if (Type()!=TOplToken::EWord) ! TypeMismatchL(); ! return TInt16(iInt); } EXPORT_C TInt32 TOplConstant::AsLongL() const // // Returns the 'long' value of a constant // { ! if (Type()==TOplToken::ELong) ! return TInt32(iInt); return TInt32(AsWordL()); } EXPORT_C TReal64 TOplConstant::AsRealL() const // ! // Returns teh value as a Real // { --- 53,103 ---- // // Returns the 'word' value of a constant // + // If it's not 'word' but 'real' or 'long', tries to + // cast to 'word' in a sensible manner. + // { ! switch ( Type() ) ! { ! case TOplToken::EReal: ! if ( iReal < TReal64(OPL_WORD_MIN) || iReal > TReal64(OPL_WORD_MAX) ) ! TypeMismatchL(); ! return (TInt16)(iReal); ! case TOplToken::ELong: ! if ( iInt < OPL_WORD_MIN || iInt > OPL_WORD_MAX ) ! TypeMismatchL(); ! case TOplToken::EWord: ! return TInt16(iInt); ! default: ! TypeMismatchL(); ! } ! return TInt16(0); //Can never be reached. } EXPORT_C TInt32 TOplConstant::AsLongL() const // // Returns the 'long' value of a constant // + // If it's not 'long' but 'real' or 'word', tries to + // cast to 'long' in a sensible manner. + // { ! switch ( Type() ) ! { ! case TOplToken::ELong: ! return TInt32(iInt); ! case TOplToken::EReal: ! if ( iReal < TReal64(OPL_LONG_MIN) || iReal > TReal64(OPL_LONG_MAX) ) ! TypeMismatchL(); ! else ! return (TInt32)(iReal); ! } return TInt32(AsWordL()); } EXPORT_C TReal64 TOplConstant::AsRealL() const // ! // Returns the value as a Real // { |