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