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