eval.c

来自「CC386 is a general-purpose 32-bit C comp」· C语言 代码 · 共 1,500 行 · 第 1/4 页

C
1,500
字号
/* 
Copyright 2001-2003 Free Software Foundation, Inc.

This program 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.  

You may contact the author at:

mailto::camille@bluegrass.net

or by snail mail at:

David Lindauer
850 Washburn Ave Apt 99
Louisville, KY 40222

 **********************************************************************

EVAL.c holds routines to do dynamic evaluation of expressions.  This
is used to get expressions for the WATCH and MEMORY address dialogs

 **********************************************************************

 */

#include <windows.h>
#include <commctrl.h>
#include <commdlg.h>
#include <richedit.h>
#include <stdio.h>
#include <limits.h>
#include <float.h>

#include "header.h"
#include "cvinfo.h"
#include <ctype.h>

#define PUSH(xxx) varinfo_list[varinfo_count++] = xxx
#define POP()  varinfo_list[--varinfo_count] 


#define NEW
#ifdef NEW
    static VARINFO *varinfo_list[200];
    static int varinfo_count;
#endif 

extern THREAD *StoppedThread;
extern unsigned bitmask[];

#define NVAL 0
#define IVAL 1
#define IUVAL 2
#define RVAL 4

LLONG_TYPE ival;
long double rval;
int lastst;

#ifdef NEW

    static VARINFO *iecondop(char **text, char **typetab, char **symtab,
        DEBUG_INFO *dbg, int offset1, int *offset);
    static void freeall(void)
    {
        int i;
        for (i = 0; i < varinfo_count; i++)
            FreeVarInfo(varinfo_list[i]);
        varinfo_count = 0;
    }
    static void skipspace(char **text)
    {
        while (**text && isspace(**text))
            (*text)++;
    }
    static VARINFO *ieerr(char **text, VARINFO *v1, VARINFO *v2, char *msg)
    {
        if (v1)
            FreeVarInfo(v1);
        if (v2)
            FreeVarInfo(v2);
        freeall();
        if (text)
            (*text) += strlen(*text);
        ExtendedMessageBox("Invalid Expression", MB_SETFOREGROUND |
            MB_SYSTEMMODAL, "%s", msg);
        return 0;
    }
    static int radix36(char c)
    {
        if (isdigit(c))
            return c - '0';
        if (c >= 'a' && c <= 'z')
            return c - 'a' + 10;
        if (c >= 'A' && c <= 'Z')
            return c - 'A' + 10;
        return INT_MAX;
    }

    /*
     *      getbase - get an integer in any base.
     */
    static void getbase(int b, char **ptr)
    {
        LLONG_TYPE i;
        int j;
        int errd = 0;
        i = 0;
        while ((j = radix36(**ptr)) < b)
        {
            (*ptr)++;
            if (i > (unsigned LLONG_TYPE)(((LLONG_TYPE) - 1) - j) / b)
            if (!errd)
            {
                ieerr(0, 0, 0, "Constant too large");
                errd++;
            }
            i = i * b + j;
        }
        ival = i;
        lastst = IVAL;
    }

    /*
     *      getfrac - get fraction part of a floating number.
     */
    static void getfrac(int radix, char **ptr)
    {
        long double frmul;
        frmul = 1.0 / radix;
        while (radix36(**ptr) < radix)
        {
            rval += frmul * radix36(*(*ptr)++);
            frmul /= radix;
        }
        lastst = RVAL;
    }

    /*
     *      getexp - get exponent part of floating number.
     *
     *      this algorithm is primative but usefull.  Floating
     *      exponents are limited to +/-255 but most hardware
     *      won't support more anyway.
     */
    static void getexp(int radix, char **ptr)
    {
        int neg = FALSE;
        if (**ptr == '-')
        {
            neg = TRUE;
            (*ptr)++;
        }
        else
        {
            if (**ptr == '+')
                (*ptr)++;
        }
        getbase(10, ptr);
        if (ival > LDBL_MAX_10_EXP)
        {
            ieerr(0, 0, 0, "Exponent too large");
            ival = 0;
        };
        if (neg)
            ival =  - ival;
        if (radix == 10)
            rval *= pow10l((long double)ival);
        else
        {
            rval *= powl(2.0, (long double)ival);
        }
        lastst = RVAL;
    }

    /*
     *      getnum - get a number from input.
     *
     *      getnum handles all of the numeric input. it accepts
     *      decimal, octal, hexidecimal, and floating point numbers.
     */
    static void getnum(char **text)
    {
        char buf[200],  *ptr = buf;
        int hasdot = FALSE;
        int radix = 10;
        int floatradix = 0;

        lastst = NVAL;
        if (**text == '0')
        {
            (*text)++;
            if (**text == 'x' ||  **text == 'X')
            {
                (*text)++;
                radix = 16;
            }
            else
                radix = 8;
        }
        else
        {
            char *t =  *text;
            while (isxdigit(*t))
                t++;
            if (*t == 'H' ||  *t == 'h')
                radix = 16;
        }
        while (radix36(**text) < radix)
        {
            *ptr++ =  * * text;
            (*text)++;

        }
        if (radix == 16 &&  **text == 'H' ||  **text == 'h')
            (*text)++;
        if (**text == '.')
        {
            if (radix == 8)
                radix = 10;
            *ptr++ =  * * text;
            (*text)++;
            while (radix36(**text) < radix)
            {
                *ptr++ =  * * text;
                (*text)++;
            }
        }
        if ((**text == 'e' ||  **text == 'E') && radix != 16)
            radix = floatradix = 10;
        else if ((**text == 'p' ||  **text == 'P') && radix == 16)
            floatradix = 2;

        if (floatradix)
        {
            *ptr++ =  * * text;
            (*text)++;
            if (**text == '-' ||  **text == '+')
            {
                *ptr++ =  * * text;
                (*text)++;
            }
            while (radix36(**text) < 10)
            {
                *ptr++ =  * * text;
                (*text)++;
            }
        }

        *ptr = 0;
        ptr = buf;
        // at this point the next char is any qualifier after the number

        if (radix36(*ptr) < radix)
            getbase(radix, &ptr);
        else
        {
            ival = 0;
            lastst = IVAL;
        }
        if (*ptr == '.')
        {
            ptr++;
            rval = ival;
            getfrac(radix, &ptr);
        }
        if (*ptr == 'e' ||  *ptr == 'E' ||  *ptr == 'p' ||  *ptr == 'P')
        {
            if (lastst != RVAL)
            {
                rval = ival;
            }
            ptr++;
            getexp(floatradix, &ptr);
        }
        if (lastst != RVAL)
        {
            if (**text == 'i')
            {
                if (**text == '6' && *(*text + 1) == '4')
                {
                    (*text)++;
                    (*text)++;
                    (*text)++;
                }
            }
            else if (**text == 'U' ||  **text == 'u')
            {
                lastst = IUVAL;
                (*text)++;
                if (**text == 'L' ||  **text == 'l')
                {
                    if (**text == 'L' ||  **text == 'l')
                    {
                        (*text)++;
                    }
                }
            }
            else if (**text == 'L' ||  **text == 'l')
            {
                (*text)++;
                if (**text == 'L' ||  **text == 'l')
                {
                    (*text)++;
                    if (**text == 'U' ||  **text == 'u')
                    {
                        (*text)++;
                        lastst = IUVAL;
                    }
                }

                else if (**text == 'U' ||  **text == 'u')
                {
                    lastst = IUVAL;
                    (*text)++;
                }
            }
        }
        else
        {
            if (**text == 'F' ||  **text == 'f')
            {
                if (lastst != RVAL)
                {
                    rval = ival;
                }
                lastst = RVAL;
                (*text)++;
            }
            else if (**text == 'L' ||  **text == 'l')
            {
                if (lastst != RVAL)
                {
                    rval = ival;
                }
                lastst = RVAL;
                (*text)++;
            }
        }
        if (isalnum(**text) || (**text) == '_')
        {
            lastst = NVAL;
        }
    }
    static VARINFO *constnode(char **text)
    {
        getnum(text);
        if (lastst == NVAL)
            return ieerr(text, 0, 0, "Invalid constant");
        if (lastst == RVAL)
        {
            VARINFO *v = calloc(sizeof(VARINFO), 1);
            if (!v)
                return 0;
            v->constant = 1;
            v->fval = rval;
            v->type = T_REAL80;
            return v;
        }
        else if (lastst == IVAL || lastst == IUVAL)
        {
            VARINFO *v = calloc(sizeof(VARINFO), 1);
            if (!v)

⌨️ 快捷键说明

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