⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ccalc.cpp

📁 CCALC provides convenient way to for performing calculations. You can use standard infix notation f
💻 CPP
📖 第 1 页 / 共 3 页
字号:
                pos += 2;                return LSR;            } else if (buf[pos+1] == '=') {                 pos += 2;                return SETASR;            } else {                 pos += 1;                return ASR;            }        } else if (buf[pos] == '=') {             pos += 1;            return GE;        }         return GT;      case '=':        if (buf[pos] == '=') {             pos += 1;            return EQ;        }         return SET;      case '&':        if (buf[pos] == '&') {             pos += 1;            return AND;        } else if (buf[pos] == '=') {             pos += 1;            return SETAND;        }        return AND;      case '|':        if (buf[pos] == '|') {             pos += 1;            return OR;        } else if (buf[pos] == '=') {             pos += 1;            return SETOR;        }        return OR;      case '^':        if (buf[pos] == '=') {             pos += 1;            return SETXOR;        }        return XOR;      case ',':        return COMMA;      case '0': case '1': case '2': case '3': case '4':      case '5': case '6': case '7': case '8': case '9':        {            int_t ival;            double fval;                        int ierr, ferr;            char *ipos, *fpos;#ifdef _WIN32            int n = 0;            ierr = sscanf(buf+pos-1, "%" INT_FORMAT "i%n", &ival, &n) != 1;            ipos = buf+pos-1+n;#else            errno = 0;             #if SIZEOF_LONG == 8            ival = strtoul(buf+pos-1, &ipos, 0); #else            ival = strtoull(buf+pos-1, &ipos, 0); #endif            ierr = errno;#endif            errno = 0;             fval = strtod(buf+pos-1, &fpos);             ferr = errno;            if (ierr && ferr) {                 error("bad numeric constant");                return ERROR;            }            if (v_sp == max_stack_size) {                 error("stack overflow");                return ERROR;            }            if (!ierr && ipos >= fpos) {                 v_stack[v_sp].tag = INT;                v_stack[v_sp].ival = ival;                pos = ipos - buf;            } else {                 v_stack[v_sp].tag = FLOAT;                v_stack[v_sp].fval = fval;                pos = fpos - buf;            }             v_stack[v_sp].pos = pos;            v_stack[v_sp++].var = NULL;            return OPERAND;        }      default:        pos -= 1;        np = name;        while (isalnum(buf[pos]) || buf[pos] == '$' || buf[pos] == '_') {            *np++ = buf[pos++];        }        if (np == buf) {             error("Bad character");            return ERROR;        }        *np = '\0';        symbol* sym = symbol::add(VARIABLE, name);        if (v_sp == max_stack_size) {             error("stack overflow");            return ERROR;        }        v_stack[v_sp] = sym->val;        v_stack[v_sp].pos = pos;        v_stack[v_sp++].var = sym;        return (sym->tag == VARIABLE) ? OPERAND : FUNC;    }}static int lpr[TERMINALS] = {    2, 0, 0, 0,       // BEGIN, OPERAND, ERROR, END,     4, 4,             // LPAR, RPAR     5, 98, 98,        // FUNC, POSTINC, POSTDEC,    98, 98, 98, 98, 98, 98, // PREINC, PREDEC, PLUS, MINUS, NOT, COM,    90,               // POW,    80, 80, 80,       // MUL, DIV, MOD,    70, 70,           // ADD, SUB,     60, 60, 60,       // ASL, ASR, LSR,     50, 50, 50, 50,   // GT, GE, LT, LE,         40, 40,           // EQ, NE,     38,               // AND,    36,               // XOR,    34,               // OR,    20, 20, 20, 20, 20, 20, 20, //SET, SETADD, SETSUB, SETMUL, SETDIV, SETMOD,     20, 20, 20, 20, 20, 20, // SETASL, SETASR, SETLSR, SETAND, SETXOR, SETOR,    10               // COMMA};static int rpr[TERMINALS] = {    0, 0, 0, 1,       // BEGIN, OPERAND, ERROR, END,     110, 3,           // LPAR, RPAR     120, 99, 99,      // FUNC, POSTINC, POSTDEC    99, 99, 99, 99, 99, 99, // PREINC, PREDEC, PLUS, MINUS, NOT, COM,    95,               // POW,    80, 80, 80,       // MUL, DIV, MOD,    70, 70,           // ADD, SUB,     60, 60, 60,       // ASL, ASR, LSR,     50, 50, 50, 50,   // GT, GE, LT, LE,         40, 40,           // EQ, NE,     38,               // AND,    36,               // XOR,    34,               // OR,    25, 25, 25, 25, 25, 25, 25, //SET, SETADD, SETSUB, SETMUL, SETDIV, SETMOD,     25, 25, 25, 25, 25, 25, // SETASL, SETASR, SETLSR, SETAND, SETXOR, SETOR,    15               // COMMA};bool calculator::assign() {     value& v = v_stack[v_sp-1];    if (v.var == NULL) {         error(v.pos, "variable expected");        return false;    } else {         v.var->val = v;        return true;    }}void calculator::evaluate(char* expression) {     char var_name[16];    buf = expression;    v_sp = 0;    o_sp = 0;    pos = 0;    o_stack[o_sp++] = BEGIN;    bool operand = true;    int n_args = 0;    while (true) {       next_token:        int op_pos = pos;        int oper = scan(operand);        if (oper == ERROR) {            return;        }        if (!operand) {             if (!BINARY(oper) && oper != END && oper != POSTINC                 && oper != POSTDEC && oper != RPAR)             {                 error(op_pos, "operator expected");                return;            }            if (oper != POSTINC && oper != POSTDEC && oper != RPAR) {                 operand = true;            }        } else {             if (oper == OPERAND) {                 operand = false;                n_args += 1;                continue;            }            if (BINARY(oper) || oper == RPAR) {                error(op_pos, "operand expected");                return;            }        }        int n_args = 1;        while (lpr[o_stack[o_sp-1]] >= rpr[oper]) {             int cop = o_stack[--o_sp];             switch (cop) {               case BEGIN:                if (oper == RPAR) {                     error("Unmatched ')'");                    return;                }                if (oper != END) {                     error("Unexpected end of input");                }                if (v_sp == 1) {                    sprintf(var_name, "$%d", ++tmp_var_count);                    printf("%s = ", var_name);                    symbol::add(VARIABLE, var_name)->val = v_stack[0];                    if (v_stack[0].tag == INT) {                         printf("%" INT_FORMAT "d [%#" INT_FORMAT "x %#" INT_FORMAT "o]\n",                                v_stack[0].ival,  v_stack[0].ival, v_stack[0].ival);                    } else {                         printf("%.10g\n", v_stack[0].fval);                    }                } else if (v_sp != 0) {                     error("Unexpected end of expression");                }                return;              case COMMA:                n_args += 1;                continue;              case ADD:              case SETADD:                if (v_stack[v_sp-1].tag == INT && v_stack[v_sp-2].tag == INT) {                    v_stack[v_sp-2].ival += v_stack[v_sp-1].ival;                } else {                     v_stack[v_sp-2].fval =                         v_stack[v_sp-2].get() + v_stack[v_sp-1].get();                    v_stack[v_sp-2].tag = FLOAT;                }                v_sp -= 1;                if (cop == SETADD) {                     if (!assign()) return;                }                v_stack[v_sp-1].var = NULL;                break;              case SUB:              case SETSUB:                if (v_stack[v_sp-1].tag == INT && v_stack[v_sp-2].tag == INT) {                    v_stack[v_sp-2].ival -= v_stack[v_sp-1].ival;                } else {                     v_stack[v_sp-2].fval =                         v_stack[v_sp-2].get() - v_stack[v_sp-1].get();                    v_stack[v_sp-2].tag = FLOAT;                }                v_sp -= 1;                if (cop == SETSUB) {                     if (!assign()) return;                }                v_stack[v_sp-1].var = NULL;                break;              case MUL:              case SETMUL:                if (v_stack[v_sp-1].tag == INT && v_stack[v_sp-2].tag == INT) {                    v_stack[v_sp-2].ival *= v_stack[v_sp-1].ival;                } else {                     v_stack[v_sp-2].fval =                         v_stack[v_sp-2].get() * v_stack[v_sp-1].get();                    v_stack[v_sp-2].tag = FLOAT;                }                v_sp -= 1;                if (cop == SETMUL) {                     if (!assign()) return;                }                v_stack[v_sp-1].var = NULL;                break;              case DIV:              case SETDIV:                if (v_stack[v_sp-1].get() == 0.0) {                    error(v_stack[v_sp-2].pos, "Division by zero");                    return;                }                if (v_stack[v_sp-1].tag == INT && v_stack[v_sp-2].tag == INT) {                    v_stack[v_sp-2].ival /= v_stack[v_sp-1].ival;                } else {                     v_stack[v_sp-2].fval =                         v_stack[v_sp-2].get() / v_stack[v_sp-1].get();                    v_stack[v_sp-2].tag = FLOAT;                }                v_sp -= 1;                if (cop == SETDIV) {                     if (!assign()) return;                }                v_stack[v_sp-1].var = NULL;                break;              case MOD:              case SETMOD:                if (v_stack[v_sp-1].get() == 0.0) {                    error(v_stack[v_sp-2].pos, "Division by zero");                    return;                }                if (v_stack[v_sp-1].tag == INT && v_stack[v_sp-2].tag == INT) {                    v_stack[v_sp-2].ival %= v_stack[v_sp-1].ival;                } else {                     v_stack[v_sp-2].fval =                         fmod(v_stack[v_sp-2].get(), v_stack[v_sp-1].get());                    v_stack[v_sp-2].tag = FLOAT;                }                v_sp -= 1;                if (cop == SETMOD) {                     if (!assign()) return;                }                v_stack[v_sp-1].var = NULL;                break;              case POW:              case SETPOW:                if (v_stack[v_sp-1].tag == INT && v_stack[v_sp-2].tag == INT) {                    v_stack[v_sp-2].ival =                         (int_t)pow((double)v_stack[v_sp-2].ival,                                    (double)v_stack[v_sp-1].ival);                } else {                     v_stack[v_sp-2].fval =                         pow(v_stack[v_sp-2].get(), v_stack[v_sp-1].get());                    v_stack[v_sp-2].tag = FLOAT;                }                v_sp -= 1;                if (cop == SETPOW) {                     if (!assign()) return;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -