int TVar::CompAB(const TVar& a, const TVar& b, TVarFuncCmp fcmp) { int r = 1; __int64 bi; double bd; switch (a.vType) { case vtUnknown: case vtInteger: switch (b.vType) { case vtUnknown: case vtInteger: r = fcmp(vtInteger,&a.inum,&b.inum); break; case vtDouble: r = fcmp(vtDouble,&a.inum,&b.dnum); break; case vtString: { switch (checkTypeString(b.s())) { case tsStr: r = fcmp(vtString,a.s(),b.str); break; case tsInt: bi=b.i(); r = fcmp(vtInteger,&a.inum,&bi); break; case tsFloat: bd=b.d(); r = fcmp(vtDouble,&a.inum,&bd); break; } break; } } break; case vtDouble: switch (b.vType) { case vtUnknown: case vtInteger: r = fcmp(vtInteger,&a.dnum,&b.inum); break; case vtDouble: r = fcmp(vtDouble,&a.dnum,&b.dnum); break; case vtString: { switch (checkTypeString(b.str)) { case tsStr: r = fcmp(vtString,a.s(),b.str); break; case tsInt: case tsFloat: bd=b.d(); r = fcmp(vtDouble,&a.inum,&bd); break; } break; } } break; case vtString: { #if defined(TVAR_USE_STRMUN) __int64 bi; double bd; TypeString tsA=checkTypeString(a.str), tsB; if (b.vType == vtInteger || b.vType == vtUnknown) tsB=tsInt; else if (b.vType == vtDouble) tsB=tsFloat; else tsB=checkTypeString(b.str); if ((tsA == tsStr && tsB == tsStr) || (tsA != tsStr && tsB == tsStr) || (tsA == tsStr && tsB != tsStr)) r = fcmp(vtString,a.s(),b.s()); else if (tsA == tsInt && tsB == tsInt) { ai=a.i(); bi=b.i(); r = fcmp(vtInteger,&ai,&bi); } else { ad=a.d(); bd=b.d(); r = fcmp(vtDouble,&ad,&bd); } #else r = fcmp(vtString,a.s(),b.s()); #endif break; } } return r; };
TVar operator+(const TVar& a, const TVar& b) { TVar r; switch (a.vType) { case vtUnknown: case vtInteger: { switch (b.vType) { case vtUnknown: case vtInteger: r = a.inum + b.inum; break; case vtDouble: r = (double)a.inum + b.dnum; break; case vtString: { switch (checkTypeString(b.str)) { case tsStr: r = addStr(::toString(a.inum), b.s()); break; case tsInt: r = a.inum + b.i(); break; case tsFloat: r = (double)a.inum + b.d(); break; } break; } } break; } case vtDouble: { switch (b.vType) { case vtUnknown: case vtInteger: r = (double)a.inum + b.dnum; break; case vtDouble: r = a.dnum + b.dnum; break; case vtString: { switch (checkTypeString(b.str)) { case tsStr: r = addStr(::toString(a.dnum), b.s()); break; case tsInt: case tsFloat: r = a.dnum * b.d(); break; } break; } } break; } case vtString: { TypeString tsA=checkTypeString(a.str),tsB; if (b.vType == vtInteger || b.vType == vtUnknown) tsB=tsInt; else if (b.vType == vtDouble) tsB=tsFloat; else tsA=tsB=tsStr; if ((tsA == tsStr && tsB == tsStr) || (tsA != tsStr && tsB == tsStr) || (tsA == tsStr && tsB != tsStr)) r = addStr(a.s(), b.s()); else if (tsA == tsInt && tsB == tsInt) r = a.i() + b.i(); else r = a.d() + b.d(); break; } } return r; };
static void prim() { switch (currTok) { case tEnd: break; case tFunc: calcFunc(); getToken(); break; case tVar: put(MCODE_OP_PUSHVAR); putstr(nameString); getToken(); break; case tConst: put(MCODE_OP_PUSHCONST); putstr(nameString); getToken(); break; case tInt: put(MCODE_OP_PUSHINT); put64(currVar.i()); getToken(); break; case tFloat: put(MCODE_OP_PUSHFLOAT); putDouble(currVar.d()); getToken(); break; case tFARVar: put(FARVar); // nFARVar получаем в getToken() getToken(); break; case tStr: put(MCODE_OP_PUSHSTR); putstr(currVar.s()); getToken(); break; case tMinus: getToken(); prim(); put(MCODE_OP_NEGATE); break; case tBitNot: getToken(); prim(); put(MCODE_OP_BITNOT); break; case tNot: getToken(); prim(); put(MCODE_OP_NOT); break; case tLp: getToken(); expr(); if (currTok != tRp) keyMacroParseError(err_Expected_Token, L")"); getToken(); break; case tRp: //??? break; default: keyMacroParseError(err_Expr_Expected); break; } }