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 = b.inum ? (a.inum % b.inum) : 0; break; case vtDouble: r = fabs(b.dnum) > DBL_EPSILON? fmod((double)a.inum, b.dnum) : 0.0; break; case vtString: { switch (checkTypeString(b.str)) { case tsStr: r = a; break; case tsInt: { __int64 bi=b.i(); r = bi ? a.inum % bi : 0; break; } case tsFloat: { double bd=b.d(); r = fabs(bd) > DBL_EPSILON? fmod((double)a.inum, bd) : 0.0; break; } } break; } } break; } case vtDouble: { switch (b.vType) { case vtUnknown: case vtInteger: r = b.inum ? fmod(a.dnum,(double)b.inum) : 0.0; break; case vtDouble: r = fabs(b.dnum) > DBL_EPSILON? fmod(a.dnum,b.dnum) : 0.0; break; case vtString: { switch (checkTypeString(b.str)) { case tsStr: r = a; break; case tsInt: case tsFloat: { double bd=b.d(); r = fabs(bd) > DBL_EPSILON? fmod(a.dnum, bd) : 0.0; 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 = a; else if (tsA == tsInt && tsB == tsInt) { __int64 bi=b.i(); r = bi ? (a.i() % bi) : 0; } else { double bd=b.d(); r = fabs(bd) > DBL_EPSILON? fmod(a.d() , bd) : 0.0; } break; } } return r; };
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 = a; 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 = a.dnum * (double)b.inum; break; case vtDouble: r = a.dnum * b.dnum; break; case vtString: { switch (checkTypeString(b.str)) { case tsStr: r = a; 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 = a; 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; } }