eval.c
来自「CC386 is a general-purpose 32-bit C comp」· C语言 代码 · 共 1,500 行 · 第 1/4 页
C
1,500 行
skipspace(&p);
}
*text = p;
if (*(*text)++ != ')')
return ieerr(text, var1, 0, "Missing ')'");
// if we got here we have a valid cast
var1 = calloc(sizeof(VARINFO), 1);
if (!var1)
return 0;
var1->type = tp;
if (s)
{
if (!indir)
return ieerr(text, var1, 0,
"struct/union cast must have pointer");
indir--;
DeclType(*typetab, var1);
}
while (indir)
{
VARINFO *var2 = calloc(sizeof(VARINFO), 1);
if (!var2)
{
FreeVarInfo(var1);
return 0;
}
var2->subtype = var1;
var2->pointer = TRUE;
var1 = var2;
indir--;
}
return var1;
}
static VARINFO *sizeofop(char **text, char **typetab, char **symtab,
DEBUG_INFO **dbg, int offset1, int *offset)
{
return ieerr(text, 0, 0, "sizeof not implemented");
}
static VARINFO *ieprimary(char **text, char **typetab, char **symtab,
DEBUG_INFO *dbg, int offset1, int *offset)
/*
* PRimary integer
* id
* iconst
* (cast )intexpr
* (intexpr)
* intexpr.id
* intexpr->id
*/
{
VARINFO *var1 = 0, *var2, **var3;
char buf[256], *p;
int needclose;
skipspace(text);
var1 = regnode(text);
if (var1)
return var1;
if (isdigit(**text) || **text == '.')
var1 = constnode(text);
else if (isalpha(**text) || **text == '_')
var1 = lookupsym(text, typetab, symtab, dbg, offset1, offset);
else if (!memcmp(*text, "sizeof", 6))
return sizeofop(text, typetab, symtab, dbg, offset1, offset);
else if (**text == '(')
{
var1 = castnode(text, typetab, symtab, dbg, offset1, offset);
if (var1)
{
PUSH(var1);
var2 = ieprimary(text, typetab, symtab, dbg, offset1, offset);
if (!var2)
return 0;
var1 = POP();
if (var2->constant)
{
var1->constant = TRUE;
var1->ival = var2->ival;
var1->fval = var2->fval;
}
else
var1->address = var2->address;
FreeVarInfo(var2);
}
else
{
(*text)++;
var1 = iecondop(text, typetab, symtab, dbg, offset1, offset);
if (**text != ')')
return ieerr(text, var1, 0, "Missing ')'");
(*text)++;
}
}
skipspace(text);
if (!var1)
return var1;
do
{
while (**text == '.' || **text == '-' && *(*text + 1) == '>')
{
int address;
if (**text == '.')
{
if (!var1->structure && !var1->unionx)return ieerr(text,
var1, 0, "Structure or union type expected")
;
if (var1->pointer)
return ieerr(text, var1, 0,
"Address of structure expected");
(*text)++;
address = var1->address;
}
else
{
if (!var1->pointer)
return ieerr(text, var1, 0, "Pointer type expected");
(*text) += 2;
GetPointerInfo(*typetab, var1);
var2 = var1->subtype;
var1->subtype = 0;
ReadValue(var1->address, &var2->address, 4, &var1->thread
->regs);
FreeVarInfo(var1);
var1 = var2;
if (!var1->structure && !var1->unionx)
return ieerr(text, var1, 0,
"Structure or union type expected");
}
skipspace(text);
if (!isalpha(**text) && **text != '_')
return ieerr(text, var1, 0, "Identifier Expected");
p = buf;
while (isalnum(**text) || **text == '_')
*p++ = *(*text)++;
*p = 0;
var2 = var1->subtype;
var3 = &var1->subtype;
while (var2 && strcmp(buf, var2->membername))
{
var3 = &var2->link;
var2 = var2->link;
}
if (!var2)
return ieerr(text, var1, 0, "Unknown member name");
(*var3) = var2->link;
var2->address = var1->address + var2->offset;
var2->offset = 0;
FreeVarInfo(var1);
var1 = var2;
var1->link = 0;
skipspace(text);
}
while (**text == '[')
{
(*text)++;
if (!var1->array)
return ieerr(text, var1, 0, "Array expected");
skipspace(text);
if (!isdigit(**text))
return ieerr(text, var1, 0, "Integer value expected");
getnum(text);
if (lastst != IVAL && lastst != IUVAL)
return ieerr(text, var1, 0, "Invalid array index");
skipspace(text);
if (**text != ']')
return ieerr(text, var1, 0, "Missing ']'");
(*text)++;
skipspace(text);
var2 = var1->subtype;
var1->subtype = var2->link;
var2->link = 0;
var2->address = var1->address + var1->itemsize *ival;
FreeVarInfo(var1);
var1 = var2;
}
}
while (**text == '.' || **text == '-' && *(*text + 1) == '>')
;
return var1;
}
/*
* Integer unary
* - unary
* ! unary
* ~unary
* primary
*/
static VARINFO *ieunary(char **text, char **typetab, char **symtab,
DEBUG_INFO *dbg, int offset1, int *offset)
{
VARINFO *val1, *val2;
switch (**text)
{
case '-':
if (*(*text + 1) != '>')
{
(*text)++;
val1 = ieunary(text, typetab, symtab, dbg, offset1, offset);
val1 = makeconst(val1);
if (CV_TYP_IS_REAL(val1->type) || CV_TYP_IS_IMAGINARY(val1->type))
val1->fval = - val1->fval;
else
val1->ival = - val1->ival;
truncateconst(val1, 0);
}
else
val1 = ieprimary(text, typetab, symtab, dbg, offset1,
offset);
break;
case '!':
(*text)++;
val1 = ieunary(text, typetab, symtab, dbg, offset1, offset);
val1 = makeconst(val1);
if (CV_TYP_IS_REAL(val1->type) || CV_TYP_IS_IMAGINARY(val1->type))
val1->fval = !val1->fval;
else
val1->ival = !val1->ival;
break;
case '~':
(*text)++;
val1 = ieunary(text, typetab, symtab, dbg, offset1, offset);
val1 = makeconst(val1);
if (CV_TYP_IS_REAL(val1->type) || CV_TYP_IS_IMAGINARY(val1->type))
return ieerr(text, 0, 0, "Invalid Floating Operation");
else
val1->ival = ~val1->ival;
truncateconst(val1, 0);
break;
case '+':
(*text)++;
val1 = ieunary(text, typetab, symtab, dbg, offset1, offset);
val1 = makeconst(val1);
break;
case '*':
(*text)++;
val1 = ieunary(text, typetab, symtab, dbg, offset1, offset);
if (!val1->pointer)
return ieerr(text, val1, 0, "Pointer Type Expected");
if (CV_IS_PRIMITIVE(val1->type))
{
val1->type &= ~CV_MMASK;
ReadValue(val1->address, &val1->address, 4, &val1->thread
->regs);
}
else
{
GetPointerInfo(*typetab, val1);
val2 = val1->subtype;
ReadValue(val1->address, &val2->address, 4, &val1->thread
->regs);
val1->subtype = 0;
FreeVarInfo(val1);
val1 = val2;
}
break;
case '&':
// & operation is the default, this is a nop
(*text)++;
val1 = ieunary(text, typetab, symtab, dbg, offset1, offset);
break;
default:
val1 = ieprimary(text, typetab, symtab, dbg, offset1, offset);
break;
}
return (val1);
}
static VARINFO *iemultops(char **text, char **typetab, char **symtab,
DEBUG_INFO *dbg, int offset1, int *offset)
/* Multiply ops */
{
VARINFO *val1, *val2;
PUSH(val1 = ieunary(text, typetab, symtab, dbg, offset1, offset));
skipspace(text);
while (val1 && (*(*text) == '*' || *(*text) == '%' || *(*text) == '\\'))
{
int ch = *(*text)++;
val2 = ieunary(text, typetab, symtab, dbg, offset1, offset);
if (!val2)
return 0;
val1 = makeconst(POP());
val2 = makeconst(val2);
switch (ch)
{
case '*':
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->fval = val1->fval *val2->fval;
else
val1->fval = val1->fval *val2->ival;
else
if (CV_TYP_IS_REAL(val2->type) || CV_TYP_IS_IMAGINARY(val2->type))
val1->fval = val1->ival *val2->fval;
else
val1->ival = val1->ival *val2->ival;
break;
case '/':
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->fval = val1->fval / val2->fval;
else
val1->fval = val1->fval / val2->ival;
else
if (CV_TYP_IS_REAL(val2->type) || CV_TYP_IS_IMAGINARY(val2->type))
val1->fval = val1->ival / val2->fval;
else
val1->ival = val1->ival / val2->ival;
break;
case '%':
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, 0, 0, "Invalid Floating Operation");
val1->ival = val1->ival % val2->ival;
break;
}
truncateconst(val1, val2);
FreeVarInfo(val2);
PUSH(val1);
skipspace(text);
}
return (POP());
}
static VARINFO *ieaddops(char **text, char **typetab, char **symtab,
DEBUG_INFO *dbg, int offset1, int *offset)
/* Add ops */
{
VARINFO *val1, *val2;
int mul1 = 1, mul2 = 1;
PUSH(val1 = iemultops(text, typetab, symtab, dbg, offset1, offset));
skipspace(text);
while (val1 && (*(*text) == '+' || *(*text) == '-') && *(*text + 1) !=
'>')
{
int ch = *(*text);
(*text)++;
val2 = iemultops(text, typetab, symtab, dbg, offset1, offset);
if (!val2)
return 0;
val1 = POP();
if (val1->structure || val1->unionx)
mul1 = val1->arraysize;
else if (val2->structure || val2->unionx)
mul2 = val2->arraysize;
else if (val1->array)
{
mul1 = val1->itemsize;
}
else if (val2->array)
{
mul2 = val2->itemsize;
}
val1 = makeconst(val1);
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->fval = val1->fval *mul2 + val2->fval *mul1;
else
val1->fval = val1->fval *mul2 + val2->ival *mul1;
else
if (CV_TYP_IS_REAL(val2->type) || CV_TYP_IS_IMAGINARY(val2->type))
val1->fval = val1->ival *mul2 + val2->fval *mul1;
else
val1->ival = val1->ival *mul2 + val2->ival *mul1;
}
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->fval = val1->fval *mul2 - val2->fval *mul1;
else
val1->fval = val1->fval *mul2 - val2->ival *mul1;
else
if (CV_TYP_IS_REAL(val2->type) || CV_TYP_IS_IMAGINARY(val2->type))
val1->fval = val1->ival *mul2 - val2->fval *mul1;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?