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