eval.c
来自「CC386 is a general-purpose 32-bit C comp」· C语言 代码 · 共 1,500 行 · 第 1/4 页
C
1,500 行
else
val1->ival = val1->ival *mul2 - val2->ival *mul1;
}
truncateconst(val1, val2);
FreeVarInfo(val2);
PUSH(val1);
skipspace(text);
}
return POP();
}
static VARINFO *ieshiftops(char **text, char **typetab, char **symtab,
DEBUG_INFO *dbg, int offset1, int *offset)
/* Shift ops */
{
VARINFO *val1, *val2;
PUSH(val1 = ieaddops(text, typetab, symtab, dbg, offset1, offset));
skipspace(text);
while (val1 && ((*(*text) == '<' || *(*text) == '>') && *(*text) == *
(*text + 1)))
{
long oper = *(*text) == '<';
(*text) += 2;
val2 = ieaddops(text, typetab, symtab, dbg, offset1, offset);
if (!val2)
return 0;
val1 = POP();
val1 = makeconst(POP());
val2 = makeconst(val2);
if (CV_TYP_IS_REAL(val1->type) || CV_TYP_IS_IMAGINARY(val1->type) || CV_TYP_IS_REAL(val2->type) || CV_TYP_IS_IMAGINARY(val2->type))
return ieerr(text, val1, val2, "Invalid floating operation");
if (oper)
{
val1->ival = val1->ival << val2->ival;
}
else
val1->ival = val1->ival >> val2->ival;
truncateconst(val1, val2);
FreeVarInfo(val2);
PUSH(val1);
skipspace(text);
}
return POP();
}
static VARINFO *ierelation(char **text, char **typetab, char **symtab,
DEBUG_INFO *dbg, int offset1, int *offset)
/* non-eq relations */
{
VARINFO *val1, *val2;
PUSH(val1 = ieshiftops(text, typetab, symtab, dbg, offset1, offset));
skipspace(text);
while (val1 && (*(*text) == '<' && *(*text) == '>' && (*(*text + 1) !=
*(*text))))
{
int oper = *(*text) == '<';
(*text)++;
if (**text == '=')
{
(*text)++;
oper |= 2;
}
val2 = ieshiftops(text, typetab, symtab, dbg, offset1, offset);
if (!val2)
return 0;
val1 = makeconst(POP());
val2 = makeconst(val2);
switch (oper)
{
case 0:
if (CV_TYP_IS_REAL(val1->type) || CV_TYP_IS_IMAGINARY(val1->type))
if (CV_TYP_IS_REAL(val2->type) || CV_TYP_IS_IMAGINARY(val2->type))
val1->ival = val1->fval < val2->fval;
else
val1->ival = val1->fval < val2->ival;
else
if (CV_TYP_IS_REAL(val2->type) || CV_TYP_IS_IMAGINARY(val2->type))
val1->ival = val1->ival < val2->fval;
else
val1->ival = val1->ival < val2->ival;
break;
case 1:
if (CV_TYP_IS_REAL(val1->type) || CV_TYP_IS_IMAGINARY(val1->type))
if (CV_TYP_IS_REAL(val2->type) || CV_TYP_IS_IMAGINARY(val2->type))
val1->ival = val1->fval > val2->fval;
else
val1->ival = val1->fval > val2->ival;
else
if (CV_TYP_IS_REAL(val2->type) || CV_TYP_IS_IMAGINARY(val2->type))
val1->ival = val1->ival > val2->fval;
else
val1->ival = val1->ival > val2->ival;
break;
case 2:
if (CV_TYP_IS_REAL(val1->type) || CV_TYP_IS_IMAGINARY(val1->type))
if (CV_TYP_IS_REAL(val2->type) || CV_TYP_IS_IMAGINARY(val2->type))
val1->ival = val1->fval <= val2->fval;
else
val1->ival = val1->fval <= val2->ival;
else
if (CV_TYP_IS_REAL(val2->type) || CV_TYP_IS_IMAGINARY(val2->type))
val1->ival = val1->ival <= val2->fval;
else
val1->ival = val1->ival <= val2->ival;
break;
case 3:
if (CV_TYP_IS_REAL(val1->type) || CV_TYP_IS_IMAGINARY(val1->type))
if (CV_TYP_IS_REAL(val2->type) || CV_TYP_IS_IMAGINARY(val2->type))
val1->ival = val1->fval >= val2->fval;
else
val1->ival = val1->fval >= val2->ival;
else
if (CV_TYP_IS_REAL(val2->type) || CV_TYP_IS_IMAGINARY(val2->type))
val1->ival = val1->ival >= val2->fval;
else
val1->ival = val1->ival >= val2->ival;
break;
}
val1->type = T_UINT4;
FreeVarInfo(val2);
PUSH(val1);
skipspace(text);
}
return POP();
}
static VARINFO *ieequalops(char **text, char **typetab, char **symtab,
DEBUG_INFO *dbg, int offset1, int *offset)
/* eq relations */
{
VARINFO *val1, *val2;
PUSH(val1 = ierelation(text, typetab, symtab, dbg, offset1, offset));
skipspace(text);
while (val1 && (*(*text + 1) == '=' && (*(*text) == '=' || *(*text) ==
'!')))
{
int ch = *(*text);
*(*text) += 2;
val2 = ierelation(text, typetab, symtab, dbg, offset1, offset);
if (!val2)
return 0;
val1 = makeconst(POP());
val2 = makeconst(val2);
if (ch == '!')
{
if (CV_TYP_IS_REAL(val1->type) || CV_TYP_IS_IMAGINARY(val1->type))
if (CV_TYP_IS_REAL(val2->type) || CV_TYP_IS_IMAGINARY(val2->type))
val1->ival = val1->fval != val2->fval;
else
val1->ival = val1->fval != val2->ival;
else
if (CV_TYP_IS_REAL(val2->type) || CV_TYP_IS_IMAGINARY(val2->type))
val1->ival = val1->ival != val2->fval;
else
val1->ival = val1->ival != val2->ival;
}
else
{
if (CV_TYP_IS_REAL(val1->type) || CV_TYP_IS_IMAGINARY(val1->type))
if (CV_TYP_IS_REAL(val2->type) || CV_TYP_IS_IMAGINARY(val2->type))
val1->ival = val1->fval == val2->fval;
else
val1->ival = val1->fval == val2->ival;
else
if (CV_TYP_IS_REAL(val2->type) || CV_TYP_IS_IMAGINARY(val2->type))
val1->ival = val1->ival == val2->fval;
else
val1->ival = val1->ival == val2->ival;
}
val1->type = T_UINT4;
FreeVarInfo(val2);
PUSH(val1);
skipspace(text);
}
return POP();
}
static VARINFO *ieandop(char **text, char **typetab, char **symtab,
DEBUG_INFO *dbg, int offset1, int *offset)
/* and op */
{
VARINFO *val1, *val2;
PUSH(val1 = ieequalops(text, typetab, symtab, dbg, offset1, offset));
skipspace(text);
while (val1 && *(*text) == '&')
{
(*text)++;
val2 = ieequalops(text, typetab, symtab, dbg, offset1, offset);
if (!val2)
return 0;
val1 = POP();
val1 = makeconst(POP());
val2 = makeconst(val2);
if (CV_TYP_IS_REAL(val1->type) || CV_TYP_IS_IMAGINARY(val1->type) || CV_TYP_IS_REAL(val2->type) || CV_TYP_IS_IMAGINARY(val2->type))
return ieerr(text, val1, val2, "Invalid floating operation");
val1->ival = val1->ival &val2->ival;
truncateconst(val1, val2);
FreeVarInfo(val2);
PUSH(val1);
skipspace(text);
}
return POP();
}
static VARINFO *iexorop(char **text, char **typetab, char **symtab,
DEBUG_INFO *dbg, int offset1, int *offset)
/* xor op */
{
VARINFO *val1, *val2;
PUSH(val1 = ieandop(text, typetab, symtab, dbg, offset1, offset));
skipspace(text);
while (val1 && *(*text) == '^')
{
(*text)++;
val2 = ieandop(text, typetab, symtab, dbg, offset1, offset);
if (!val2)
return 0;
val1 = POP();
val1 = makeconst(POP());
val2 = makeconst(val2);
if (CV_TYP_IS_REAL(val1->type) || CV_TYP_IS_IMAGINARY(val1->type) || CV_TYP_IS_REAL(val2->type) || CV_TYP_IS_IMAGINARY(val2->type))
return ieerr(text, val1, val2, "Invalid floating operation");
val1->ival = val1->ival ^ val2->ival;
truncateconst(val1, val2);
FreeVarInfo(val2);
PUSH(val1);
skipspace(text);
}
return POP();
}
static VARINFO *ieorop(char **text, char **typetab, char **symtab,
DEBUG_INFO *dbg, int offset1, int *offset)
/* or op */
{
VARINFO *val1, *val2;
PUSH(val1 = iexorop(text, typetab, symtab, dbg, offset1, offset));
skipspace(text);
while (val1 && *(*text) == '|')
{
(*text)++;
val2 = iexorop(text, typetab, symtab, dbg, offset1, offset);
if (!val2)
return 0;
val1 = POP();
val1 = makeconst(POP());
val2 = makeconst(val2);
if (CV_TYP_IS_REAL(val1->type) || CV_TYP_IS_IMAGINARY(val1->type) || CV_TYP_IS_REAL(val2->type) || CV_TYP_IS_IMAGINARY(val2->type))
return ieerr(text, val1, val2, "Invalid floating operation");
val1->ival = val1->ival | val2->ival;
truncateconst(val1, val2);
FreeVarInfo(val2);
PUSH(val1);
skipspace(text);
}
return POP();
}
static VARINFO *ielandop(char **text, char **typetab, char **symtab,
DEBUG_INFO *dbg, int offset1, int *offset)
/* logical and op */
{
VARINFO *val1, *val2;
PUSH(val1 = ieorop(text, typetab, symtab, dbg, offset1, offset));
skipspace(text);
while (val1 && (**text == '&' && *(*text + 1) == '&'))
{
(*text) += 2;
val2 = ieorop(text, typetab, symtab, dbg, offset1, offset);
if (!val2)
return 0;
val1 = POP();
val1 = makeconst(POP());
val2 = makeconst(val2);
if (CV_TYP_IS_REAL(val1->type) || CV_TYP_IS_IMAGINARY(val1->type) || CV_TYP_IS_REAL(val2->type) || CV_TYP_IS_IMAGINARY(val2->type))
return ieerr(text, val1, val2, "Invalid floating operation");
val1->ival = val1->ival && val2->ival;
truncateconst(val1, val2);
FreeVarInfo(val2);
PUSH(val1);
skipspace(text);
}
return POP();
}
static VARINFO *ielorop(char **text, char **typetab, char **symtab,
DEBUG_INFO *dbg, int offset1, int *offset)
/* logical or op */
{
VARINFO *val1, *val2;
PUSH(val1 = ielandop(text, typetab, symtab, dbg, offset1, offset));
skipspace(text);
while (val1 && (**text == '|' && *(*text + 1) == '|'))
{
(*text) += 2;
val2 = ielandop(text, typetab, symtab, dbg, offset1, offset);
if (!val2)
return 0;
val1 = POP();
val1 = makeconst(POP());
val2 = makeconst(val2);
if (CV_TYP_IS_REAL(val1->type) || CV_TYP_IS_IMAGINARY(val1->type) || CV_TYP_IS_REAL(val2->type) || CV_TYP_IS_IMAGINARY(val2->type))
return ieerr(text, val1, val2, "Invalid floating operation");
val1->ival = val1->ival || val2->ival;
truncateconst(val1, val2);
FreeVarInfo(val2);
PUSH(val1);
skipspace(text);
}
return POP();
}
static VARINFO *iecondop(char **text, char **typetab, char **symtab,
DEBUG_INFO *dbg, int offset1, int *offset)
/* Hook op */
{
VARINFO *val1, *val2, *val3, *val4;
PUSH(val1 = ielorop(text, typetab, symtab, dbg, offset1, offset));
skipspace(text);
if (val1 && **text == '?')
{
(*text)++;
PUSH(iecondop(text, typetab, symtab, dbg, offset1, offset));
skipspace(text);
if (**text != ':')
return ieerr(text, 0, 0, "Expected ':'");
(*text)++;
val3 = iecondop(text, typetab, symtab, dbg, offset1, offset);
val2 = POP();
val1 = POP();
val1 = makeconst(val1);
if (CV_TYP_IS_REAL(val1->type) || CV_TYP_IS_IMAGINARY(val1->type))
if (val1->fval)
val4 = val2;
else
val4 = val3;
else
if (val1->ival)
val4 = val2;
else
val4 = val3;
FreeVarInfo(val1);
if (val4 == val2)
FreeVarInfo(val3);
else
FreeVarInfo(val2);
PUSH(val4);
}
return POP();
}
#endif
VARINFO *EvalExpr(char **types, char **syms, DEBUG_INFO **dbg, int offset1, int
*offset, char *text)
{
#ifdef NEW
VARINFO *var;
char *p = text;
if (! *text)
return ieerr(&text, 0, 0, "Malformed Expression");
varinfo_count = 0;
var = iecondop(&text, types, syms, dbg, offset1, offset);
if (varinfo_count || *text != 0)
return ieerr(&text, var, 0, "Malformed Expression");
if (!var)
return var;
if (var->constant)
if (!CV_IS_PRIMITIVE(var->type) || var->array)
{
var->constant = FALSE;
var->address = var->ival;
}
strcpy(var->membername, p);
return var;
#else
if (FindSymbol(dbg, types, syms, offset, StoppedThread->regs.Eip,
*offset, (char*)text))
{
return GetVarInfo(*dbg, *types, *syms, *offset, (char*)text);
}
return 0;
#endif
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?