⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cmath2.c

📁 Open Watcom 的 C 编译器源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
*               DESCRIBE IT HERE!
*
****************************************************************************/


#include "cvars.h"
#include "cgswitch.h"


#define CHR     TYPE_CHAR
#define UCH     TYPE_UCHAR
#define SHT     TYPE_SHORT
#define USH     TYPE_USHORT
#define INT     TYPE_INT
#define UIN     TYPE_UINT
#define LNG     TYPE_LONG
#define ULN     TYPE_ULONG
#define LN8     TYPE_LONG64
#define UL8     TYPE_ULONG64
#define FLT     TYPE_FLOAT
#define DBL     TYPE_DOUBLE
#define PTR     TYPE_POINTER
#define ARR     TYPE_ARRAY
#define STC     TYPE_STRUCT
#define ERR     255

/* define macros for promoted types */
#if TARGET_INT == 4

    /* Promoted Unsigned Short is Signed Int */
    #define PUS     TYPE_INT
    /* Promoted Unsigned Int is Unsigned Long */
    #define PUI     TYPE_ULONG

#else /* 16-bit ints */

    /* Promoted Unsigned Short is Unsigned Int */
    #define PUS     TYPE_UINT
    /* Promoted Unsigned Int is Signed Long */          /* 20-sep-89 */
    #define PUI     TYPE_LONG

#endif


local  const unsigned char __FAR AddResult[15][15] = {
/*  +       CHR, UCH, SHT, USH, INT, UIN, LNG, ULN, LN8, UL8, FLT, DBL, PTR, ARR, STC  */
/* CHR */ { INT, INT, INT, PUS, INT, UIN, LNG, ULN, LN8, UL8, FLT, DBL, PTR, ERR, ERR },
/* UCH */ { INT, INT, INT, PUS, INT, UIN, LNG, ULN, LN8, UL8, FLT, DBL, PTR, ERR, ERR },
/* SHT */ { INT, INT, INT, PUS, INT, UIN, LNG, ULN, LN8, UL8, FLT, DBL, PTR, ERR, ERR },
/* USH */ { PUS, PUS, PUS, PUS, PUS, UIN, LNG, ULN, LN8, UL8, FLT, DBL, PTR, ERR, ERR },
/* INT */ { INT, INT, INT, PUS, INT, UIN, LNG, ULN, LN8, UL8, FLT, DBL, PTR, ERR, ERR },
/* UIN */ { UIN, UIN, UIN, UIN, UIN, UIN, PUI, ULN, LN8, UL8, FLT, DBL, PTR, ERR, ERR },
/* LNG */ { LNG, LNG, LNG, LNG, LNG, PUI, LNG, ULN, LN8, UL8, FLT, DBL, PTR, ERR, ERR },
/* ULN */ { ULN, ULN, ULN, ULN, ULN, ULN, ULN, ULN, LN8, UL8, FLT, DBL, PTR, ERR, ERR },
/* LN8 */ { LN8, LN8, LN8, LN8, LN8, LN8, LN8, LN8, LN8, UL8, FLT, DBL, PTR, ERR, ERR },
/* UL8 */ { UL8, UL8, UL8, UL8, UL8, UL8, UL8, UL8, UL8, UL8, FLT, DBL, PTR, ERR, ERR },
/* FLT */ { FLT, FLT, FLT, FLT, FLT, FLT, FLT, FLT, FLT, FLT, FLT, DBL, ERR, ERR, ERR },
/* DBL */ { DBL, DBL, DBL, DBL, DBL, DBL, DBL, DBL, DBL, DBL, DBL, DBL, ERR, ERR, ERR },
/* PTR */ { PTR, PTR, PTR, PTR, PTR, PTR, PTR, PTR, PTR, PTR, ERR, ERR, ERR, ERR, ERR },
/* ARR */ { ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR },
/* STC */ { ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR } };


local  const unsigned char __FAR SubResult[15][15] = {
/*  +       CHR, UCH, SHT, USH, INT, UIN, LNG, ULN, LN8, UL8,  FLT, DBL, PTR, ARR, STC  */
/* CHR */ { INT, INT, INT, PUS, INT, UIN, LNG, ULN, LN8, UL8,  FLT, DBL, PTR, ERR, ERR },
/* UCH */ { INT, INT, INT, PUS, INT, UIN, LNG, ULN, LN8, UL8,  FLT, DBL, PTR, ERR, ERR },
/* SHT */ { INT, INT, INT, PUS, INT, UIN, LNG, ULN, LN8, UL8,  FLT, DBL, PTR, ERR, ERR },
/* USH */ { PUS, PUS, PUS, PUS, PUS, UIN, LNG, ULN, LN8, UL8,  FLT, DBL, PTR, ERR, ERR },
/* INT */ { INT, INT, INT, PUS, INT, UIN, LNG, ULN, LN8, UL8,  FLT, DBL, PTR, ERR, ERR },
/* UIN */ { UIN, UIN, UIN, UIN, UIN, UIN, PUI, ULN, LN8, UL8,  FLT, DBL, PTR, ERR, ERR },
/* LNG */ { LNG, LNG, LNG, LNG, LNG, PUI, LNG, ULN, LN8, UL8,  FLT, DBL, PTR, ERR, ERR },
/* ULN */ { ULN, ULN, ULN, ULN, ULN, ULN, ULN, ULN, LN8, UL8,  FLT, DBL, PTR, ERR, ERR },
/* LN8 */ { LN8, LN8, LN8, LN8, LN8, LN8, LN8, LN8, LN8, UL8,  FLT, DBL, PTR, ERR, ERR },
/* UL8 */ { UL8, UL8, UL8, UL8, UL8, UL8, UL8, UL8, UL8, UL8,  FLT, DBL, PTR, ERR, ERR },
/* FLT */ { FLT, FLT, FLT, FLT, FLT, FLT, FLT, FLT, FLT, FLT,  FLT, DBL, ERR, ERR, ERR },
/* DBL */ { DBL, DBL, DBL, DBL, DBL, DBL, DBL, DBL, DBL, DBL,  DBL, DBL, ERR, ERR, ERR },
/* PTR */ { PTR, PTR, PTR, PTR, PTR, PTR, PTR, PTR, PTR, PTR,  ERR, ERR, INT, ERR, ERR },
/* ARR */ { ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR,  ERR, ERR, ERR, ERR, ERR },
/* STC */ { ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR,  ERR, ERR, ERR, ERR, ERR } };


local  const unsigned char __FAR IntResult[15][15] = {
/*  +       CHR, UCH, SHT, USH, INT, UIN, LNG, ULN, LN8, UL8, FLT, DBL, PTR, ARR, STC  */
/* CHR */ { INT, INT, INT, PUS, INT, UIN, LNG, ULN, LN8, UL8, ERR, ERR, ERR, ERR, ERR },
/* UCH */ { INT, INT, INT, PUS, INT, UIN, LNG, ULN, LN8, UL8, ERR, ERR, ERR, ERR, ERR },
/* SHT */ { INT, INT, INT, PUS, INT, UIN, LNG, ULN, LN8, UL8, ERR, ERR, ERR, ERR, ERR },
/* USH */ { PUS, PUS, PUS, PUS, PUS, UIN, LNG, ULN, LN8, UL8, ERR, ERR, ERR, ERR, ERR },
/* INT */ { INT, INT, INT, PUS, INT, UIN, LNG, ULN, LN8, UL8, ERR, ERR, ERR, ERR, ERR },
/* UIN */ { UIN, UIN, UIN, UIN, UIN, UIN, PUI, ULN, LN8, UL8, ERR, ERR, ERR, ERR, ERR },
/* LNG */ { LNG, LNG, LNG, LNG, LNG, PUI, LNG, ULN, LN8, UL8, ERR, ERR, ERR, ERR, ERR },
/* ULN */ { ULN, ULN, ULN, ULN, ULN, ULN, ULN, ULN, LN8, UL8, ERR, ERR, ERR, ERR, ERR },
/* LN8 */ { LN8, LN8, LN8, LN8, LN8, LN8, LN8, LN8, LN8, UL8, ERR, ERR, ERR, ERR, ERR },
/* UL8 */ { UL8, UL8, UL8, UL8, UL8, UL8, UL8, UL8, UL8, UL8, ERR, ERR, ERR, ERR, ERR },
/* FLT */ { ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR },
/* DBL */ { ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR },
/* PTR */ { ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR },
/* ARR */ { ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR },
/* STC */ { ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR } };


local char ShiftResult[15] = {
/* >>      op2 */
/* CHR */  INT,
/* UCH */  INT,         /* 20-may-88 AFS (used to be UIN) */
/* SHT */  INT,
/* USH */  PUS,
/* INT */  INT,
/* UIN */  UIN,
/* LNG */  LNG,
/* ULN */  ULN,
/* LN8 */  LN8,
/* UL8 */  UL8,
/* FLT */  ERR,
/* DBL */  ERR,
/* PTR */  ERR,
/* ARR */  ERR,
/* STC */  ERR  };


local  const unsigned char __FAR BinResult[15][15] = {
/*  +       CHR, UCH, SHT, USH, INT, UIN, LNG, ULN, LN8, UL8, FLT, DBL, PTR, ARR, STC  */
/* CHR */ { CHR, UCH, INT, PUS, INT, UIN, LNG, ULN, LN8, UL8, FLT, DBL, ERR, ERR, ERR },
/* UCH */ { UCH, UCH, INT, PUS, INT, UIN, LNG, ULN, LN8, UL8, FLT, DBL, ERR, ERR, ERR },
/* SHT */ { INT, INT, INT, PUS, INT, UIN, LNG, ULN, LN8, UL8, FLT, DBL, ERR, ERR, ERR },
/* USH */ { PUS, PUS, PUS, PUS, PUS, UIN, LNG, ULN, LN8, UL8, FLT, DBL, ERR, ERR, ERR },
/* INT */ { INT, INT, INT, PUS, INT, UIN, LNG, ULN, LN8, UL8, FLT, DBL, ERR, ERR, ERR },
/* UIN */ { UIN, UIN, UIN, UIN, UIN, UIN, PUI, ULN, LN8, UL8, FLT, DBL, ERR, ERR, ERR },
/* LNG */ { LNG, LNG, LNG, LNG, LNG, PUI, LNG, ULN, LN8, UL8, FLT, DBL, ERR, ERR, ERR },
/* ULN */ { ULN, ULN, ULN, ULN, ULN, ULN, ULN, ULN, LN8, UL8, FLT, DBL, ERR, ERR, ERR },
/* LN8 */ { LN8, LN8, LN8, LN8, LN8, LN8, LN8, LN8, LN8, UL8, FLT, DBL, ERR, ERR, ERR },
/* UL8 */ { UL8, UL8, UL8, UL8, UL8, UL8, UL8, UL8, UL8, UL8, FLT, DBL, ERR, ERR, ERR },
/* FLT */ { FLT, FLT, FLT, FLT, FLT, FLT, FLT, FLT, FLT, FLT, FLT, DBL, ERR, ERR, ERR },
/* DBL */ { DBL, DBL, DBL, DBL, DBL, DBL, DBL, DBL, DBL, DBL, DBL, DBL, ERR, ERR, ERR },
/* PTR */ { ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR },
/* ARR */ { ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR },
/* STC */ { ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR } };


enum    conv_types {
        NIL = 0,
        C2S,    /* char to short    */
        C2I,    /* char to int      */
        C2L,    /* char to long     */
        C2M,    /* char to long64   */
        C2U,    /* char to unsigned */
        C2F,    /* char to float    */
        C2D,    /* char to double   */
        S2C,    /* short to char    */
        S2I,    /* short to int     */
        S2L,    /* short to long    */
        S2M,    /* short to long64  */
        S2U,    /* short to unsigned*/
        S2F,    /* short to float   */
        S2D,    /* short to double  */
        I2C,    /* int to char      */
        I2S,    /* int to short     */
        I2U,    /* int to unsigned  */
        I2L,    /* int to long      */
        I2M,    /* int to long64    */
        I2F,    /* int to float     */
        I2D,    /* int to double    */
        L2C,    /* long to char     */
        L2S,    /* long to short    */
        L2I,    /* long to integer  */
        L2M,    /* long to long64   */
        L2U,    /* long to unsigned */
        L2F,    /* long to float    */
        L2D,    /* long to double   */
        M2C,    /* long64 to char   */
        M2S,    /* long64 to short  */
        M2I,    /* long64 to integer*/
        M2L,    /* long64 to long   */
        M2U,    /* long64 to unsigned*/
        M2F,    /* long64 to float  */
        M2D,    /* long64 to double */
        U2C,    /* unsigned to char */
        U2L,    /* unsigned to long */
        U2M,    /* unsigned to long64*/
        U2F,    /* unsigned to float*/
        U2D,    /* unsigned to double */
        F2C,    /* float to char    */
        F2S,    /* float to short   */
        F2I,    /* float to int     */
        F2L,    /* float to long    */
        F2M,    /* float to long64  */
        F2D,    /* float to double  */
        D2C,    /* double to char   */
        D2S,    /* double to short  */
        D2I,    /* double to int    */
        D2L,    /* double to long   */
        D2M,    /* double to long64 */
        D2F,    /* double to float  */
        P2P,    /* pointer to pointer*/
        A2P,    /* arithmetic to pointer*/
        P2A,    /* pointer to arithmetic*/
        CER,    /* conversion error  */
 };

static enum  conv_types const CnvTable[16][16] = {
/*          CHR,UCH,SHT,USH,INT,UIN,LNG,ULN,LN8,UL8,FLT,DBL,PTR,ARR,STC,UNI  */
/* CHR */ { NIL,C2U,C2S,C2S,C2I,C2U,C2L,C2L,C2M,C2M,C2F,C2D,P2A,CER,CER,CER },
/* UCH */ { U2C,NIL,C2S,C2S,C2I,C2U,C2L,C2L,C2M,C2M,C2F,C2D,P2A,CER,CER,CER },
/* SHT */ { S2C,S2C,NIL,S2U,S2I,S2U,S2L,S2L,S2M,S2M,S2F,S2D,P2A,CER,CER,CER },
/* USH */ { S2C,S2C,S2U,NIL,S2I,S2U,S2L,S2L,S2M,S2M,S2F,S2D,P2A,CER,CER,CER },
/* INT */ { I2C,I2C,I2S,I2S,NIL,I2U,I2L,I2L,I2M,I2M,I2F,I2D,P2A,CER,CER,CER },
/* UIN */ { I2C,I2C,I2S,I2S,I2U,NIL,U2L,U2L,U2M,U2M,U2F,U2D,P2A,CER,CER,CER },
/* LNG */ { L2C,L2C,L2S,L2S,L2I,L2U,NIL,L2U,L2M,L2M,L2F,L2D,P2A,CER,CER,CER },
/* ULN */ { L2C,L2C,L2S,L2S,L2I,L2U,L2U,NIL,L2M,L2M,L2F,L2D,P2A,CER,CER,CER },
/* LN8 */ { M2C,M2C,M2S,M2S,M2I,M2U,M2L,M2L,NIL,M2U,M2F,M2D,P2A,CER,CER,CER },
/* UL8 */ { M2C,M2C,M2S,M2S,M2I,M2U,M2L,M2L,M2U,NIL,M2F,M2D,P2A,CER,CER,CER },
/* FLT */ { F2C,F2C,F2S,F2S,F2I,F2I,F2L,F2L,F2M,F2M,NIL,F2D,CER,CER,CER,CER },
/* DBL */ { D2C,D2C,D2S,D2S,D2I,D2I,D2L,D2L,D2M,D2M,D2F,NIL,CER,CER,CER,CER },
/* PTR */ { A2P,A2P,A2P,A2P,A2P,A2P,A2P,A2P,A2P,A2P,CER,CER,P2P,CER,CER,CER },
/* ARR */ { CER,CER,CER,CER,CER,CER,CER,CER,CER,CER,CER,CER,CER,CER,CER,CER },
/* STC */ { CER,CER,CER,CER,CER,CER,CER,CER,CER,CER,CER,CER,CER,CER,CER,CER },
/* UNI */ { CER,CER,CER,CER,CER,CER,CER,CER,CER,CER,CER,CER,CER,CER,CER,CER } };

static  char    Operator[] = {
        T_NULL,
        T_EOF,
    OPR_COMMA,          // T_COMMA
    OPR_QUESTION,       // T_QUESTION
    OPR_COLON,          // T_COLON
        T_SEMI_COLON,
        T_LEFT_PAREN,
        T_RIGHT_PAREN,
        T_LEFT_BRACKET,
        T_RIGHT_BRACKET,
        T_LEFT_BRACE,
        T_RIGHT_BRACE,
        T_DOT,
        T_TILDE,
    OPR_EQUALS,         // T_EQUAL,
        T_EQ,
    OPR_NOT,            // T_EXCLAMATION
        T_NE,
    OPR_OR,             /* T_OR,    */
    OPR_OR_EQUAL,       /* T_OR_EQUAL */
    OPR_OR_OR,          /* T_OR_OR, */
    OPR_XOR,            /* T_XOR,   */
    OPR_XOR_EQUAL,      /* T_XOR_EQUAL, */
    OPR_AND,            /* T_AND,   */
    OPR_AND_EQUAL,      /* T_AND_EQUAL, */
    OPR_AND_AND,        /* T_AND_AND, */
        T_GT,
        T_GE,
    OPR_RSHIFT,         /* T_RSHIFT,*/
    OPR_RSHIFT_EQUAL,   /* T_RSHIFT_EQUAL, */
        T_LT,
        T_LE,
    OPR_LSHIFT,         /* T_LSHIFT,*/
    OPR_LSHIFT_EQUAL,   /* T_LSHIFT_EQUAL, */
    OPR_ADD,            /* T_PLUS,  */
    OPR_PLUS_EQUAL,     /* T_PLUS_EQUAL, */
    OPR_POSTINC,        /* T_PLUS_PLUS, */
    OPR_SUB,            /* T_MINUS, */
    OPR_MINUS_EQUAL,    /* T_MINUS_EQUAL, */
    OPR_POSTDEC,        /* T_MINUS_MINUS, */
    OPR_MUL,            /* T_TIMES, */
    OPR_TIMES_EQUAL,    /* T_TIMES_EQUAL, */
    OPR_DIV,            /* T_DIVIDE,*/
    OPR_DIV_EQUAL,      /* T_DIVIDE_EQUAL, */
    OPR_MOD,            /* T_PERCENT,*/
    OPR_MOD_EQUAL,      /* T_PERCENT_EQUAL, */
};

int TokenToOperator( TOKEN token )
{
    return( Operator[ token ] );
}

TYPEPTR TypeOf( TREEPTR node )
{
    TYPEPTR     typ;

    typ = node->expr_type;
    while( typ->decl_type == TYPE_TYPEDEF ) typ = typ->object;
    return( typ );
}

DATA_TYPE DataTypeOf( DATA_TYPE data_type )
{
    switch( data_type ) {
    case TYPE_FIELD:
    case TYPE_ENUM:
        return( TYPE_INT );
    case TYPE_UFIELD:
        return( TYPE_UINT );
    }
    return( data_type );
}

#define PTR_FLAGS (FLAG_NEAR|FLAG_FAR|FLAG_HUGE|FLAG_BASED|FLAG_FAR16)

// 0 - near data
// 1 - based data
// 2 - far data
// 3 - far16 data
// 4 - huge data
// 5 - near func
// 6 - based func
// 7 - far func
// 8 - far16 func
// 9 - interrupt func

pointer_class PointerClass( TYPEPTR typ )
{
    type_modifiers    flags;
    pointer_class     class;

    flags = typ->u.p.decl_flags & PTR_FLAGS;;
    typ = typ->object;
    while( typ->decl_type == TYPE_TYPEDEF )  typ = typ->object;
    class = PTR_NEAR;                   // assume NEAR
    if( (flags & FLAG_INTERRUPT) == FLAG_INTERRUPT ) {
        class = PTR_INTERRUPT;          // can't have huge functions
    } else if( flags & FLAG_BASED ) {
        class = PTR_BASED;
    } else if( flags & FLAG_FAR ) {
        class = PTR_FAR;
    } else if( flags & FLAG_FAR16 ) {
        class = PTR_FAR16;
    } else if( flags & FLAG_HUGE ) {
        class = PTR_HUGE;
    }
    if( typ->decl_type == TYPE_FUNCTION )  class += PTR_FUNC;
    return( class );
}

pointer_class ExprTypeClass( TYPEPTR typ )
{
    TYPEPTR     savtyp;

    savtyp = typ;

⌨️ 快捷键说明

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