SNAP Library , Developer Reference
2013-01-07 14:03:36
SNAP, a general purpose, high performance system for analysis and manipulation of large networks
|
00001 00002 // Expression-Value 00003 PExpVal TExpVal::UndefExpVal=NULL; 00004 PExpVal TExpVal::ZeroExpVal=NULL; 00005 00006 bool TExpVal::operator==(const TExpVal& ExpVal) const { 00007 if (ValType!=ExpVal.ValType){return false;} 00008 switch (ValType){ 00009 case evtUndef: return true; 00010 case evtFlt: return Flt==ExpVal.Flt; 00011 case evtStr: return Str==ExpVal.Str; 00012 case evtVec:{ 00013 if (ValV.Len()!=ExpVal.ValV.Len()){return false;} 00014 for (int VecValN=0; VecValN<ExpVal.ValV.Len(); VecValN++){ 00015 if (*ValV[VecValN]!=*ExpVal.ValV[VecValN]){return false;}} 00016 return true;} 00017 case evtLst:{ 00018 if (ValL.Len()!=ExpVal.ValL.Len()){return false;} 00019 TExpValLN ValLN=ValL.First(); 00020 TExpValLN ExpValLN=ExpVal.ValL.First(); 00021 while (ValLN!=NULL){ 00022 if (*ValLN->GetVal()!=*ExpValLN->GetVal()){return false;} 00023 ValLN=ValLN->Next(); 00024 ExpValLN=ExpValLN->Next(); 00025 } 00026 return true;} 00027 default: Fail; return false; 00028 } 00029 } 00030 00031 bool TExpVal::operator<(const TExpVal& ExpVal) const { 00032 if (ValType!=ExpVal.ValType){ 00033 return ValType<ExpVal.ValType;} 00034 switch (ValType){ 00035 case evtUndef: return false; 00036 case evtFlt: return Flt<ExpVal.Flt; 00037 case evtStr: return Str<ExpVal.Str; 00038 case evtVec:{ 00039 int VecValN=0; 00040 while ((VecValN<ValV.Len())&&(VecValN<ExpVal.ValV.Len())){ 00041 if (*ValV[VecValN]<*ExpVal.ValV[VecValN]){return true;} 00042 else if (*ValV[VecValN]==*ExpVal.ValV[VecValN]){VecValN++;} 00043 else {return false;} 00044 } 00045 return ValV.Len()<ExpVal.ValV.Len();} 00046 case evtLst:{ 00047 if (ValL.Len()!=ExpVal.ValL.Len()){return false;} 00048 TExpValLN ValLN=ValL.First(); 00049 TExpValLN ExpValLN=ExpVal.ValL.First(); 00050 while ((ValLN!=NULL)&&(ExpValLN!=NULL)){ 00051 if (*ValLN->GetVal()<*ExpValLN->GetVal()){ 00052 return true;} 00053 else if (*ValLN->GetVal()==*ExpValLN->GetVal()){ 00054 ValLN=ValLN->Next(); ExpValLN=ExpValLN->Next();} 00055 else {return false;} 00056 } 00057 return ValLN==NULL;} 00058 default: Fail; return false; 00059 } 00060 } 00061 00062 int TExpVal::GetFltValAsInt(const bool& ThrowExceptP) const { 00063 double Flt=GetFltVal(); 00064 if ((Flt<double(TInt::Mn))&&(double(TInt::Mx)<Flt)){ 00065 if (ThrowExceptP){TExcept::Throw("Float too big for integer.");} 00066 else {Flt=0;} 00067 } 00068 return int(Flt); 00069 } 00070 00071 void TExpVal::SaveTxt(TOLx& Lx) const { 00072 TExpValType _ValType=TExpValType(int(ValType)); 00073 switch (_ValType){ 00074 case evtUndef: Lx.PutIdStr("Undef"); break; 00075 case evtFlt: Lx.PutFlt(Flt); break; 00076 case evtStr: Lx.PutQStr(Str); break; 00077 case evtVec:{ 00078 Lx.PutSym(syLBrace); 00079 for (int ValN=0; ValN<ValV.Len(); ValN++){ 00080 ValV[ValN]->SaveTxt(Lx);} 00081 Lx.PutSym(syRBrace); 00082 break;} 00083 case evtLst:{ 00084 Lx.PutSym(syLBracket); 00085 TExpValLN ValLN=ValL.First(); 00086 for (int ValN=0; ValN<ValL.Len(); ValN++){ 00087 ValLN->GetVal()->SaveTxt(Lx); ValLN=ValLN->Next();} 00088 Lx.PutSym(syRBracket); 00089 break;} 00090 default: Fail; 00091 } 00092 } 00093 00094 void TExpVal::SaveTxt(const PSOut& SOut) const { 00095 TOLx Lx(SOut, TFSet()|oloCmtAlw|oloSigNum|oloCsSens); 00096 SaveTxt(Lx); 00097 } 00098 00099 TStr TExpVal::GetStr() const { 00100 PSOut SOut=TMOut::New(); TMOut& MOut=*(TMOut*)SOut(); 00101 SaveTxt(SOut); 00102 TStr ExpValStr=TStr::LoadTxt(MOut.GetSIn()); 00103 return ExpValStr; 00104 } 00105 00106 PExpVal TExpVal::MkClone(const PExpVal& ExpVal){ 00107 PExpVal CloneExpVal=TExpVal::New(); 00108 CloneExpVal->ValType=ExpVal->ValType; 00109 CloneExpVal->Flt=ExpVal->Flt; 00110 CloneExpVal->Str=ExpVal->Str; 00111 CloneExpVal->ValV.Gen(ExpVal->ValV.Len(), 0); 00112 for (int VecValN=0; VecValN<ExpVal->ValV.Len(); VecValN++){ 00113 CloneExpVal->ValV.Add(MkClone(ExpVal->ValV[VecValN])); 00114 } 00115 TExpValLN ExpValLN=ExpVal->ValL.First(); 00116 while (ExpValLN!=NULL){ 00117 CloneExpVal->ValL.AddBack(MkClone(ExpValLN->GetVal())); 00118 ExpValLN=ExpValLN->Next(); 00119 } 00120 return CloneExpVal; 00121 } 00122 00123 PExpVal TExpVal::GetUndefExpVal(){ 00124 if (UndefExpVal.Empty()){ 00125 UndefExpVal=TExpVal::New();} 00126 return UndefExpVal; 00127 } 00128 00129 PExpVal TExpVal::GetZeroExpVal(){ 00130 if (ZeroExpVal.Empty()){ 00131 ZeroExpVal=TExpVal::New(double(0));} 00132 return ZeroExpVal; 00133 } 00134 00136 // Expression-Environment 00137 bool TExpEnv::IsFuncOk( 00138 const TStr& RqFuncNm, const TExpFuncArgType& RqFuncArgType, 00139 const TStr& FuncNm, const TExpValV& ArgValV){ 00140 if (RqFuncNm.GetUc()!=FuncNm.GetUc()){return false;} 00141 switch (RqFuncArgType){ 00142 case efatVoid: return ArgValV.Len()==0; 00143 case efatFlt: 00144 if (ArgValV.Len()!=1){return false;} 00145 if (ArgValV[0]->GetValType()!=evtFlt){return false;} 00146 return true; 00147 case efatStr: 00148 if (ArgValV.Len()!=1){return false;} 00149 if (ArgValV[0]->GetValType()!=evtStr){return false;} 00150 return true; 00151 case efatFltFlt: 00152 if (ArgValV.Len()!=2){return false;} 00153 if (ArgValV[0]->GetValType()!=evtFlt){return false;} 00154 if (ArgValV[1]->GetValType()!=evtFlt){return false;} 00155 return true; 00156 case efatFltStr: 00157 if (ArgValV.Len()!=2){return false;} 00158 if (ArgValV[0]->GetValType()!=evtFlt){return false;} 00159 if (ArgValV[1]->GetValType()!=evtStr){return false;} 00160 return true; 00161 case efatStrFlt: 00162 if (ArgValV.Len()!=2){return false;} 00163 if (ArgValV[0]->GetValType()!=evtStr){return false;} 00164 if (ArgValV[1]->GetValType()!=evtFlt){return false;} 00165 return true; 00166 case efatStrStr: 00167 if (ArgValV.Len()!=2){return false;} 00168 if (ArgValV[0]->GetValType()!=evtStr){return false;} 00169 if (ArgValV[1]->GetValType()!=evtStr){return false;} 00170 return true; 00171 case efatStrAny: 00172 if (ArgValV.Len()!=2){return false;} 00173 if (ArgValV[0]->GetValType()!=evtStr){return false;} 00174 return true; 00175 default: Fail; return false; 00176 } 00177 } 00178 00179 PExpEnv TExpEnv::DfExpEnv=PExpEnv(new TExpEnv()); 00180 00182 // Expression-Built-Ins 00183 TExpBi::TExpBi(): 00184 ExpBiNmToIdH(100), ExpBiIdToArgTypeH(100){ 00185 // constants 00186 AddBi("Undef", ebi_Undef); 00187 AddBi("True", ebi_True); 00188 AddBi("False", ebi_False); 00189 AddBi("E", ebi_E); 00190 AddBi("Pi", ebi_Pi); 00191 00192 // trigonometric funcions 00193 AddBi("Sin", ebi_Sin, ebatFlt); 00194 AddBi("Cos", ebi_Cos, ebatFlt); 00195 AddBi("Tan", ebi_Tan, ebatFlt); 00196 AddBi("ASin", ebi_ASin, ebatFlt); 00197 AddBi("ACos", ebi_ACos, ebatFlt); 00198 AddBi("ATan", ebi_ATan, ebatFlt); 00199 AddBi("SinH", ebi_SinH, ebatFlt); 00200 AddBi("CosH", ebi_CosH, ebatFlt); 00201 AddBi("TanH", ebi_TanH, ebatFlt); 00202 00203 // exponential functions 00204 AddBi("Pow", ebi_Pow, ebatFltFlt); 00205 AddBi("Exp", ebi_Exp, ebatFlt); 00206 AddBi("Sqr", ebi_Sqr, ebatFlt); 00207 AddBi("Sqrt", ebi_Sqrt, ebatFlt); 00208 AddBi("Log", ebi_Log, ebatFlt); 00209 AddBi("Log10", ebi_Log10, ebatFlt); 00210 00211 // number manipulation functions 00212 AddBi("Ceil", ebi_Ceil, ebatFlt); 00213 AddBi("Floor", ebi_Floor, ebatFlt); 00214 AddBi("Int", ebi_Int, ebatFlt); 00215 AddBi("Frac", ebi_Frac, ebatFlt); 00216 AddBi("Abs", ebi_Abs, ebatFlt); 00217 00218 // random deviates 00219 AddBi("UniDev", ebi_UniDev, ebatVoid); 00220 AddBi("NrmDev", ebi_NrmDev, ebatVoid); 00221 AddBi("ExpDev", ebi_ExpDev, ebatVoid); 00222 AddBi("GamDev", ebi_GamDev, ebatFlt); 00223 AddBi("PoiDev", ebi_PoiDev, ebatFlt); 00224 AddBi("BinDev", ebi_BinDev, ebatFltFlt); 00225 AddBi("UniDevStep", ebi_UniDevStep, ebatFltFlt); 00226 00227 // assign values to constants 00228 Val_Undef=TExpVal::GetUndefExpVal(); 00229 Val_True=TExpVal::New(double(1)); 00230 Val_False=TExpVal::New(double(0)); 00231 Val_E=TExpVal::New(TMath::E); 00232 Val_Pi=TExpVal::New(TMath::Pi); 00233 } 00234 00235 void TExpBi::AddBi(const TStr& ExpBiNm, const TExpBiId& ExpBiId, 00236 const TExpBiArgType& ExpBiArgType){ 00237 ExpBiNmToIdH.AddDat(ExpBiNm.GetUc(), TInt(int(ExpBiId))); 00238 ExpBiIdToArgTypeH.AddDat(TInt(int(ExpBiId)), TInt(int(ExpBiArgType))); 00239 } 00240 00241 bool TExpBi::IsExpBiId(const TStr& ExpBiNm, TExpBiId& ExpBiId){ 00242 int ExpBiIdP; 00243 if (ExpBiNmToIdH.IsKey(ExpBiNm.GetUc(), ExpBiIdP)){ 00244 ExpBiId=TExpBiId(int(ExpBiNmToIdH[ExpBiIdP])); return true; 00245 } else { 00246 ExpBiId=ebi_Undef; return false; 00247 } 00248 } 00249 00250 TExpBiArgType TExpBi::GetExpBiArgType(const TExpBiId& ExpBiId){ 00251 TInt ExpBiArgType=ExpBiIdToArgTypeH.GetDat(TInt(int(ExpBiId))); 00252 return TExpBiArgType(int(ExpBiArgType)); 00253 } 00254 00255 void TExpBi::AssertArgs(const int& RqArgs, const int& ActArgs){ 00256 if (RqArgs!=ActArgs){ 00257 TExcept::Throw("Invalid number of arguments."); 00258 } 00259 } 00260 00261 void TExpBi::AssertArgValType( 00262 const TExpValType& ExpValType, const PExpVal& ExpVal){ 00263 if (ExpValType!=ExpVal->GetValType()){ 00264 TExcept::Throw("Invalid type of argument."); 00265 } 00266 } 00267 00268 PExpVal TExpBi::GetBiConstVal(const TExpBiId& ExpBiId){ 00269 switch (ExpBiId){ 00270 case ebi_Undef: return Val_Undef; 00271 case ebi_True: return Val_True; 00272 case ebi_False: return Val_False; 00273 case ebi_E: return Val_E; 00274 case ebi_Pi: return Val_Pi; 00275 default: TExcept::Throw("Invalid constant."); return Val_Undef; 00276 } 00277 } 00278 00279 PExpVal TExpBi::GetBiFuncVal( 00280 const TExpBiId& ExpBiId, const TExpValV& ArgValV, const PExpEnv& ExpEnv){ 00281 TExpBiArgType ExpBiArgType=TExpBi::GetExpBiArgType(ExpBiId); 00282 int Args=ArgValV.Len(); 00283 double ArgFlt1=0; double ArgFlt2=0; 00284 switch (ExpBiArgType){ 00285 case ebatUndef: Fail; break; 00286 case ebatVoid: 00287 AssertArgs(0, Args); break; 00288 case ebatFlt: 00289 AssertArgs(1, Args); 00290 AssertArgValType(evtFlt, ArgValV[0]); 00291 ArgFlt1=ArgValV[0]->GetFltVal(); break; 00292 case ebatFltFlt: 00293 AssertArgs(2, Args); 00294 AssertArgValType(evtFlt, ArgValV[0]); 00295 AssertArgValType(evtFlt, ArgValV[1]); 00296 ArgFlt1=ArgValV[0]->GetFltVal(); 00297 ArgFlt2=ArgValV[1]->GetFltVal(); break; 00298 default: Fail; 00299 } 00300 PExpVal ExpVal; 00301 switch (ExpBiId){ 00302 // trigonometric funcions 00303 case ebi_Sin: ExpVal=TExpVal::New(sin(ArgFlt1)); break; 00304 case ebi_Cos: ExpVal=TExpVal::New(cos(ArgFlt1)); break; 00305 case ebi_Tan: ExpVal=TExpVal::New(tan(ArgFlt1)); break; 00306 case ebi_ASin: ExpVal=TExpVal::New(asin(ArgFlt1)); break; 00307 case ebi_ACos: ExpVal=TExpVal::New(acos(ArgFlt1)); break; 00308 case ebi_ATan: ExpVal=TExpVal::New(atan(ArgFlt1)); break; 00309 case ebi_SinH: ExpVal=TExpVal::New(sinh(ArgFlt1)); break; 00310 case ebi_CosH: ExpVal=TExpVal::New(cosh(ArgFlt1)); break; 00311 case ebi_TanH: ExpVal=TExpVal::New(tanh(ArgFlt1)); break; 00312 00313 // exponential functions 00314 case ebi_Pow: ExpVal=TExpVal::New(pow(ArgFlt1, ArgFlt2)); break; 00315 case ebi_Exp: ExpVal=TExpVal::New(exp(ArgFlt1)); break; 00316 case ebi_Sqr: ExpVal=TExpVal::New(TMath::Sqr(ArgFlt1)); break; 00317 case ebi_Sqrt: ExpVal=TExpVal::New(sqrt(ArgFlt1)); break; 00318 case ebi_Log: ExpVal=TExpVal::New(log(ArgFlt1)); break; 00319 case ebi_Log10: ExpVal=TExpVal::New(log10(ArgFlt1)); break; 00320 00321 // number manipulation functions 00322 case ebi_Ceil: ExpVal=TExpVal::New(ceil(ArgFlt1)); break; 00323 case ebi_Floor: ExpVal=TExpVal::New(floor(ArgFlt1)); break; 00324 case ebi_Int:{ 00325 double Int; modf(ArgFlt1, &Int); 00326 ExpVal=TExpVal::New(Int); break;} 00327 case ebi_Frac:{ 00328 double Frac, Int; Frac=modf(ArgFlt1, &Int); 00329 ExpVal=TExpVal::New(Frac); break;} 00330 case ebi_Abs: ExpVal=TExpVal::New(fabs(ArgFlt1)); break; 00331 00332 // random deviates 00333 case ebi_UniDev: ExpVal=TExpVal::New(ExpEnv->GetRnd().GetUniDev()); break; 00334 case ebi_NrmDev: ExpVal=TExpVal::New(ExpEnv->GetRnd().GetNrmDev()); break; 00335 case ebi_ExpDev: ExpVal=TExpVal::New(ExpEnv->GetRnd().GetExpDev()); break; 00336 case ebi_GamDev:{ 00337 int ArgInt1=int(ArgFlt1); 00338 ExpVal=TExpVal::New(ExpEnv->GetRnd().GetGammaDev(ArgInt1)); break;} 00339 case ebi_PoiDev:{ 00340 ExpVal=TExpVal::New(ExpEnv->GetRnd().GetPoissonDev(ArgFlt1)); break;} 00341 case ebi_BinDev:{ 00342 int ArgInt2=int(ArgFlt2); 00343 ExpVal=TExpVal::New(ExpEnv->GetRnd().GetBinomialDev(ArgFlt1, ArgInt2)); break;} 00344 case ebi_UniDevStep:{ 00345 int ArgInt1=int(ArgFlt1); if (ArgInt1<0){ArgInt1=0;} 00346 int ArgInt2=int(ArgFlt2); 00347 ExpVal=TExpVal::New(TRnd::GetUniDevStep(ArgInt1, ArgInt2)); break;} 00348 case ebi_NrmDevStep:{ 00349 int ArgInt1=int(ArgFlt1); if (ArgInt1<0){ArgInt1=0;} 00350 int ArgInt2=int(ArgFlt2); 00351 ExpVal=TExpVal::New(TRnd::GetNrmDevStep(ArgInt1, ArgInt2)); break;} 00352 case ebi_ExpDevStep:{ 00353 int ArgInt1=int(ArgFlt1); if (ArgInt1<0){ArgInt1=0;} 00354 int ArgInt2=int(ArgFlt2); 00355 ExpVal=TExpVal::New(TRnd::GetExpDevStep(ArgInt1, ArgInt2)); break;} 00356 00357 default: TExcept::Throw("Invalid function."); 00358 } 00359 return ExpVal; 00360 } 00361 00363 // Expression 00364 TExpBi TExp::ExpBi; 00365 00366 const TFSet TExp::MulOpSymSet(syAsterisk, sySlash, syPercent, syHash, syAmpersand); 00367 const TFSet TExp::UAddOpSymSet(syPlus, syMinus); 00368 const TFSet TExp::AddOpSymSet(syPlus, syMinus, syVBar); 00369 const TFSet TExp::RelOpSymSet(syEq, syNEq, syLss, syGtr, syLEq, syGEq); 00370 00371 const TFSet TExp::FactExpExpect(syFlt, syIdStr, syQStr, syLParen); 00372 const TFSet TExp::MulExpExpect(FactExpExpect); 00373 const TFSet TExp::AddExpExpect(MulExpExpect, UAddOpSymSet); 00374 const TFSet TExp::RelExpExpect(AddExpExpect); 00375 const TFSet TExp::ExpExpect(RelExpExpect); 00376 00377 PExpVal TExp::EvalExpOp( 00378 const PExpEnv& ExpEnv, const bool& DbgP, TChA& DbgChA){ 00379 PExpVal OutExpVal; 00380 TExpOp _ExpOp=TExpOp(int(ExpOp)); 00381 switch (_ExpOp){ 00382 case eoUPlus: 00383 case eoUMinus: 00384 case eoNot:{ 00385 PExpVal ExpVal=ArgExpV[0]->EvalExp(ExpEnv, DbgP, DbgChA); 00386 TExpValType ExpValType=ExpVal->GetValType(); 00387 if (ExpValType==evtFlt){ 00388 TFlt Flt; 00389 switch (_ExpOp){ 00390 case eoUPlus: Flt=ExpVal->GetFltVal(); break; 00391 case eoUMinus: Flt=-ExpVal->GetFltVal(); break; 00392 case eoNot: Flt=double(ExpVal->GetFltValAsInt()==0); 00393 default: Fail; Flt=0; 00394 } 00395 OutExpVal=TExpVal::New(Flt); 00396 } else { 00397 TExcept::Throw("Bad argument types."); 00398 } 00399 break;} 00400 case eoPlus: 00401 case eoMinus: 00402 case eoMul: 00403 case eoDiv: 00404 case eoIDiv: 00405 case eoMod: 00406 case eoAnd: 00407 case eoOr:{ 00408 PExpVal LExpVal=ArgExpV[0]->EvalExp(ExpEnv, DbgP, DbgChA); 00409 PExpVal RExpVal=ArgExpV[1]->EvalExp(ExpEnv, DbgP, DbgChA); 00410 TExpValType LExpValType=LExpVal->GetValType(); 00411 TExpValType RExpValType=RExpVal->GetValType(); 00412 if ((LExpValType==evtFlt)&&(RExpValType==evtFlt)){ 00413 // check left expression 00414 double LVal=LExpVal->GetFltVal(); 00415 int LValExpon; frexp(LVal, &LValExpon); 00416 if (LValExpon>150){LExpVal=TExpVal::GetZeroExpVal();} 00417 // check right expression 00418 double RVal=LExpVal->GetFltVal(); 00419 int RValExpon; frexp(RVal, &RValExpon); 00420 if (RValExpon>150){RExpVal=TExpVal::GetZeroExpVal();} 00421 // calculate 00422 TFlt Flt; 00423 switch (_ExpOp){ 00424 case eoPlus: Flt=LExpVal->GetFltVal()+RExpVal->GetFltVal(); break; 00425 case eoMinus: Flt=LExpVal->GetFltVal()-RExpVal->GetFltVal(); break; 00426 case eoMul: Flt=LExpVal->GetFltVal()*RExpVal->GetFltVal(); break; 00427 case eoDiv: 00428 if (RExpVal->GetFltVal()==0){TExcept::Throw("Division by zero.");} 00429 else {Flt=LExpVal->GetFltVal()/RExpVal->GetFltVal();} 00430 break; 00431 case eoIDiv: 00432 if (RExpVal->GetFltValAsInt()==0){TExcept::Throw("Division by zero.");} 00433 else {Flt=LExpVal->GetFltValAsInt()/RExpVal->GetFltValAsInt();} 00434 break; 00435 case eoMod: 00436 if (RExpVal->GetFltValAsInt()==0){TExcept::Throw("Division by zero.");} 00437 else {Flt=LExpVal->GetFltValAsInt()%RExpVal->GetFltValAsInt();} 00438 break; 00439 case eoAnd: 00440 Flt=(LExpVal->GetFltValAsInt()!=0)&&(RExpVal->GetFltValAsInt()!=0); break; 00441 case eoOr: 00442 Flt=(LExpVal->GetFltValAsInt()!=0)||(RExpVal->GetFltValAsInt()!=0); break; 00443 default: Fail; Flt=0; 00444 } 00445 OutExpVal=TExpVal::New(Flt); 00446 } else 00447 if ((_ExpOp==eoPlus)&&(LExpValType==evtStr)&&(RExpValType==evtStr)){ 00448 TStr Str=LExpVal->GetStrVal()+RExpVal->GetStrVal(); 00449 OutExpVal=TExpVal::New(Str); 00450 } else { 00451 TExcept::Throw("Bad argument types."); 00452 } 00453 break;} 00454 case eoEq: 00455 case eoNEq: 00456 case eoLss: 00457 case eoGtr: 00458 case eoLEq: 00459 case eoGEq:{ 00460 PExpVal LExpVal=ArgExpV[0]->EvalExp(ExpEnv, DbgP, DbgChA); 00461 PExpVal RExpVal=ArgExpV[1]->EvalExp(ExpEnv, DbgP, DbgChA); 00462 TExpValType LExpValType=LExpVal->GetValType(); 00463 TExpValType RExpValType=RExpVal->GetValType(); 00464 if ((LExpValType==evtFlt)&&(RExpValType==evtFlt)){ 00465 TFlt Flt; 00466 switch (_ExpOp){ 00467 case eoEq: Flt=double(LExpVal->GetFltVal()==RExpVal->GetFltVal()); break; 00468 case eoNEq: Flt=double(LExpVal->GetFltVal()!=RExpVal->GetFltVal()); break; 00469 case eoLss: Flt=double(LExpVal->GetFltVal()<RExpVal->GetFltVal()); break; 00470 case eoGtr: Flt=double(LExpVal->GetFltVal()>RExpVal->GetFltVal()); break; 00471 case eoLEq: Flt=double(LExpVal->GetFltVal()<=RExpVal->GetFltVal()); break; 00472 case eoGEq: Flt=double(LExpVal->GetFltVal()>=RExpVal->GetFltVal()); break; 00473 default: Fail; Flt=0; 00474 } 00475 OutExpVal=TExpVal::New(Flt); 00476 } else 00477 if ((LExpValType==evtStr)&&(RExpValType==evtStr)){ 00478 TFlt Flt; 00479 switch (_ExpOp){ 00480 case eoEq: Flt=double(LExpVal->GetStrVal()==RExpVal->GetStrVal()); break; 00481 case eoNEq: Flt=double(LExpVal->GetStrVal()!=RExpVal->GetStrVal()); break; 00482 case eoLss: Flt=double(LExpVal->GetStrVal()<RExpVal->GetStrVal()); break; 00483 case eoGtr: Flt=double(LExpVal->GetStrVal()>RExpVal->GetStrVal()); break; 00484 case eoLEq: Flt=double(LExpVal->GetStrVal()<=RExpVal->GetStrVal()); break; 00485 case eoGEq: Flt=double(LExpVal->GetStrVal()>=RExpVal->GetStrVal()); break; 00486 default: Fail; Flt=0; 00487 } 00488 OutExpVal=TExpVal::New(Flt); 00489 } else { 00490 TExcept::Throw("Bad argument types."); 00491 } 00492 break;} 00493 case eoIf:{ 00494 PExpVal CondExpVal=ArgExpV[0]->EvalExp(ExpEnv, DbgP, DbgChA); 00495 TExpValType CondExpValType=CondExpVal->GetValType(); 00496 if (CondExpValType==evtFlt){ 00497 PExpVal ExpVal; 00498 if (CondExpVal->GetFltVal()!=0){ 00499 ExpVal=ArgExpV[1]->EvalExp(ExpEnv, DbgP, DbgChA); 00500 } else { 00501 ExpVal=ArgExpV[2]->EvalExp(ExpEnv, DbgP, DbgChA); 00502 } 00503 OutExpVal=ExpVal; 00504 } else { 00505 TExcept::Throw("Bad argument types."); 00506 } 00507 break;} 00508 default: Fail; OutExpVal=NULL; 00509 } 00510 if (DbgP){ 00511 DbgChA+="['"; DbgChA+=TExp::GetExpOpStr(_ExpOp); 00512 DbgChA+="'='"; DbgChA+=OutExpVal->GetStr(); DbgChA+="'] "; 00513 } 00514 return OutExpVal; 00515 } 00516 00517 PExpVal TExp::EvalExp( 00518 const PExpEnv& ExpEnv, const bool& DbgP, TChA& DbgChA){ 00519 PExpVal OutExpVal; 00520 TExpType _ExpType=TExpType(int(ExpType)); 00521 switch (_ExpType){ 00522 case etUndef: 00523 OutExpVal=TExpVal::GetUndefExpVal(); 00524 break; 00525 case etVal: 00526 OutExpVal=ExpVal; 00527 break; 00528 case etVec:{ 00529 PExpVal ExpVal=TExpVal::New(evtVec); 00530 for (int ArgExpN=0; ArgExpN<ArgExpV.Len(); ArgExpN++){ 00531 PExpVal ArgExpVal= 00532 PExpVal(ArgExpV[ArgExpN]->EvalExp(ExpEnv, DbgP, DbgChA)); 00533 ExpVal->AddToVec(ArgExpVal); 00534 } 00535 OutExpVal=ExpVal; 00536 break;} 00537 case etLst:{ 00538 PExpVal ExpVal=TExpVal::New(evtLst); 00539 for (int ArgExpN=0; ArgExpN<ArgExpV.Len(); ArgExpN++){ 00540 PExpVal ArgExpVal= 00541 PExpVal(ArgExpV[ArgExpN]->EvalExp(ExpEnv, DbgP, DbgChA)); 00542 ExpVal->AddToLst(ArgExpVal); 00543 } 00544 OutExpVal=ExpVal; 00545 break;} 00546 case etOp: 00547 OutExpVal=EvalExpOp(ExpEnv, DbgP, DbgChA); break; 00548 case etVar:{ 00549 bool IsVar=false; 00550 PExpVal ExpVal=ExpEnv->GetVarVal(ExpNm.GetUc(), IsVar); 00551 if (!IsVar){TExcept::Throw(TStr("Variable not defined (")+ExpNm+").");} 00552 OutExpVal=ExpVal; 00553 break;} 00554 case etBiConst: 00555 OutExpVal=ExpBi.GetBiConstVal(TExpBiId(int(ExpBiId))); 00556 break; 00557 case etFunc: 00558 case etBiFunc:{ 00559 TExpValV ArgExpValV(ArgExpV.Len(), 0); 00560 for (int ArgExpN=0; ArgExpN<ArgExpV.Len(); ArgExpN++){ 00561 PExpVal ArgExpVal= 00562 PExpVal(ArgExpV[ArgExpN]->EvalExp(ExpEnv, DbgP, DbgChA)); 00563 ArgExpValV.Add(ArgExpVal); 00564 } 00565 switch (_ExpType){ 00566 case etFunc:{ 00567 bool IsFunc=false; 00568 PExpVal ExpVal=ExpEnv->GetFuncVal(ExpNm.GetUc(), ArgExpValV, IsFunc); 00569 if (!IsFunc){ 00570 TExcept::Throw(TStr("Function not defined (")+ExpNm+").");} 00571 OutExpVal=ExpVal; 00572 break;} 00573 case etBiFunc: 00574 OutExpVal=ExpBi.GetBiFuncVal(TExpBiId(int(ExpBiId)), ArgExpValV, ExpEnv); 00575 break; 00576 default: Fail; OutExpVal=NULL; 00577 } 00578 break;} 00579 default: Fail; OutExpVal=NULL; 00580 } 00581 if (DbgP){ 00582 switch (_ExpType){ 00583 case etVal: 00584 case etOp: 00585 break; 00586 case etUndef: 00587 case etVec: 00588 case etLst:{ 00589 TStr ExpTypeStr=TExp::GetExpTypeStr(_ExpType); 00590 DbgChA+='['; DbgChA+=ExpTypeStr; DbgChA+='='; 00591 DbgChA+=OutExpVal->GetStr(); DbgChA+="] "; 00592 break;} 00593 case etVar: 00594 case etBiConst: 00595 case etFunc: 00596 case etBiFunc: 00597 DbgChA+='['; DbgChA+=ExpNm; DbgChA+='='; 00598 DbgChA+=OutExpVal->GetStr(); DbgChA+="] "; 00599 break; 00600 default: Fail; 00601 } 00602 } 00603 return OutExpVal; 00604 } 00605 00606 TExpOp TExp::GetExpOpFromLxSym(const TLxSym& LxSym){ 00607 switch (LxSym){ 00608 case syPlus: return eoPlus; 00609 case syMinus: return eoMinus; 00610 case syAsterisk: return eoMul; 00611 case sySlash: return eoDiv; 00612 case syPercent: return eoMod; 00613 case syExclamation: return eoNot; 00614 case syVBar: return eoOr; 00615 case syAmpersand: return eoAnd; 00616 case syQuestion: return eoIf; 00617 case syHash: return eoIDiv; 00618 case syEq: return eoEq; 00619 case syNEq: return eoNEq; 00620 case syLss: return eoLss; 00621 case syGtr: return eoGtr; 00622 case syLEq: return eoLEq; 00623 case syGEq: return eoGEq; 00624 default: Fail; return eoUndef; 00625 } 00626 } 00627 00628 TLxSym TExp::GetLxSymFromExpOp(const TExpOp& ExpOp){ 00629 switch (ExpOp){ 00630 case eoUPlus: return syPlus; 00631 case eoUMinus: return syMinus; 00632 case eoNot: return syExclamation; 00633 case eoPlus: return syPlus; 00634 case eoMinus: return syMinus; 00635 case eoMul: return syAsterisk; 00636 case eoDiv: return sySlash; 00637 case eoIDiv: return syHash; 00638 case eoMod: return syPercent; 00639 case eoAnd: return syAmpersand; 00640 case eoOr: return syVBar; 00641 case eoEq: return syEq; 00642 case eoNEq: return syNEq; 00643 case eoLss: return syLss; 00644 case eoGtr: return syGtr; 00645 case eoLEq: return syLEq; 00646 case eoGEq: return syGEq; 00647 case eoIf: return syQuestion; 00648 default: Fail; return syUndef; 00649 } 00650 } 00651 00652 PExp TExp::LoadTxtFact(TILx& Lx, const TFSet& Expect){ 00653 PExp Exp; 00654 switch (Lx.Sym){ 00655 case syFlt:{ 00656 PExpVal ExpVal=TExpVal::New(Lx.Flt); 00657 Exp=PExp(new TExp(ExpVal)); 00658 Lx.GetSym(Expect); 00659 break;} 00660 case syIdStr:{ 00661 TStr ExpNm=Lx.Str; 00662 Lx.GetSym(TFSet(Expect)|syLParen); 00663 if (Lx.Sym==syLParen){ 00664 TExpV ArgExpV; 00665 Lx.GetSym(TFSet(ExpExpect)|syRParen); 00666 while (Lx.Sym!=syRParen){ 00667 if (Lx.Sym==syComma){Lx.GetSym(ExpExpect);} 00668 PExp ArgExp=LoadTxtExp(Lx, TFSet()|syComma|syRParen); 00669 ArgExpV.Add(ArgExp); 00670 } 00671 Lx.GetSym(Expect); 00672 Exp=PExp(new TExp(ExpNm, ArgExpV)); 00673 } else { 00674 Exp=PExp(new TExp(ExpNm)); 00675 } 00676 break;} 00677 case syQStr:{ 00678 PExpVal ExpVal=TExpVal::New(Lx.Str); 00679 Exp=PExp(new TExp(ExpVal)); 00680 Lx.GetSym(Expect); 00681 break;} 00682 case syLParen:{ 00683 Lx.GetSym(ExpExpect); 00684 Exp=LoadTxtExp(Lx, TFSet()|syRParen); 00685 Exp->IsParen=true; 00686 Lx.GetSym(Expect); 00687 break;} 00688 default: Fail; 00689 } 00690 return Exp; 00691 } 00692 00693 PExp TExp::LoadTxtMulExp(TILx& Lx, const TFSet& Expect){ 00694 PExp Exp=LoadTxtFact(Lx, TFSet(Expect)|MulOpSymSet); 00695 while (MulOpSymSet.In(Lx.Sym)){ 00696 TExpOp ExpOp=GetExpOpFromLxSym(Lx.Sym); 00697 Lx.GetSym(FactExpExpect); 00698 PExp RExp=LoadTxtFact(Lx, TFSet(Expect)|MulOpSymSet); 00699 Exp=PExp(new TExp(ExpOp, Exp, RExp)); 00700 } 00701 return Exp; 00702 } 00703 00704 PExp TExp::LoadTxtAddExp(TILx& Lx, const TFSet& Expect){ 00705 TExpOp PrefExpOp=eoUndef; 00706 if (Lx.Sym==syPlus){PrefExpOp=eoUPlus; Lx.GetSym(MulExpExpect);} 00707 else if (Lx.Sym==syMinus){PrefExpOp=eoUMinus; Lx.GetSym(MulExpExpect);} 00708 PExp Exp=LoadTxtMulExp(Lx, TFSet(Expect)|AddOpSymSet); 00709 if (PrefExpOp!=eoUndef){ 00710 Exp=PExp(new TExp(PrefExpOp, Exp));} 00711 while (AddOpSymSet.In(Lx.Sym)){ 00712 TExpOp ExpOp=GetExpOpFromLxSym(Lx.Sym); 00713 Lx.GetSym(MulExpExpect); 00714 PExp RExp=LoadTxtMulExp(Lx, TFSet(Expect)|AddOpSymSet); 00715 Exp=PExp(new TExp(ExpOp, Exp, RExp)); 00716 } 00717 return Exp; 00718 } 00719 00720 PExp TExp::LoadTxtRelExp(TILx& Lx, const TFSet& Expect){ 00721 PExp Exp=LoadTxtAddExp(Lx, TFSet(Expect)|RelOpSymSet); 00722 if (RelOpSymSet.In(Lx.Sym)){ 00723 TExpOp ExpOp=GetExpOpFromLxSym(Lx.Sym); 00724 Lx.GetSym(AddExpExpect); 00725 PExp RExp=LoadTxtAddExp(Lx, Expect); 00726 Exp=PExp(new TExp(ExpOp, Exp, RExp)); 00727 } 00728 return Exp; 00729 } 00730 00731 PExp TExp::LoadTxtExp(TILx& Lx, const TFSet& Expect){ 00732 PExp Exp=LoadTxtRelExp(Lx, TFSet(Expect)|syQuestion); 00733 if (Lx.Sym==syQuestion){ 00734 TExpOp ExpOp=GetExpOpFromLxSym(Lx.Sym); 00735 Lx.GetSym(ExpExpect); 00736 PExp ThenExp=LoadTxtExp(Lx, TFSet()|syColon); 00737 Lx.GetSym(ExpExpect); 00738 PExp ElseExp=LoadTxtExp(Lx, Expect); 00739 Exp=PExp(new TExp(ExpOp, Exp, ThenExp, ElseExp)); 00740 } 00741 return Exp; 00742 } 00743 00744 void TExp::SaveTxtOp(TOLx& Lx) const { 00745 IAssert(TExpType(static_cast<int>(ExpType))==etOp); 00746 TExpOp _ExpOp=TExpOp(int(ExpOp)); 00747 TLxSym OpSym=GetLxSymFromExpOp(_ExpOp); 00748 switch (_ExpOp){ 00749 case eoUPlus: 00750 case eoUMinus: 00751 case eoNot: 00752 Lx.PutSym(OpSym); ArgExpV[0]->SaveTxt(Lx); 00753 break; 00754 case eoPlus: case eoMinus: 00755 case eoMul: case eoDiv: 00756 case eoIDiv: case eoMod: 00757 case eoAnd: case eoOr: 00758 case eoEq: case eoNEq: 00759 case eoLss: case eoGtr: 00760 case eoLEq: case eoGEq: 00761 ArgExpV[0]->SaveTxt(Lx); Lx.PutSym(OpSym); ArgExpV[1]->SaveTxt(Lx); 00762 break; 00763 case eoIf: 00764 ArgExpV[0]->SaveTxt(Lx); Lx.PutSym(OpSym); 00765 ArgExpV[1]->SaveTxt(Lx); Lx.PutSym(syColon); ArgExpV[2]->SaveTxt(Lx); 00766 break; 00767 default: Fail; 00768 } 00769 } 00770 00771 TExp::TExp(const TExpOp& _ExpOp, 00772 const PExp& Exp1, const PExp& Exp2, const PExp& Exp3): 00773 ExpType(etOp), IsParen(false), 00774 ExpVal(), ExpNm(), ExpOp(_ExpOp), ExpBiId(), ArgExpV(){ 00775 ArgExpV.Add(Exp1); 00776 if (!Exp2.Empty()){ArgExpV.Add(Exp2);} 00777 if (!Exp3.Empty()){ArgExpV.Add(Exp3);} 00778 } 00779 00780 TExp::TExp(const PExpVal& _ExpVal): 00781 ExpType(etVal), IsParen(false), 00782 ExpVal(_ExpVal), ExpNm(), ExpOp(), ExpBiId(), ArgExpV(){} 00783 00784 TExp::TExp(const TStr& _VarNm): 00785 ExpType(), IsParen(false), 00786 ExpVal(), ExpNm(_VarNm), ExpOp(), ExpBiId(), ArgExpV(){ 00787 TExpBiId _ExpBiId; 00788 if (ExpBi.IsExpBiId(ExpNm, _ExpBiId)){ 00789 ExpType=etBiConst; 00790 ExpBiId=TInt(int(_ExpBiId)); 00791 } else { 00792 ExpType=etVar; 00793 } 00794 } 00795 00796 TExp::TExp(const TStr& _FuncNm, const TExpV& _ArgExpV): 00797 ExpType(), IsParen(false), 00798 ExpVal(), ExpNm(_FuncNm), ExpOp(), ExpBiId(), ArgExpV(_ArgExpV){ 00799 TExpBiId _ExpBiId; 00800 if (ExpBi.IsExpBiId(ExpNm, _ExpBiId)){ 00801 ExpType=etBiFunc; 00802 ExpBiId=TInt(int(_ExpBiId)); 00803 } else { 00804 ExpType=etFunc; 00805 } 00806 } 00807 00808 PExp TExp::LoadTxt( 00809 const PSIn& SIn, bool& Ok, TStr& MsgStr, const TFSet& Expect){ 00810 TILx Lx(SIn, TFSet()|iloCmtAlw|iloCsSens|iloExcept); 00811 PExp Exp; Ok=true; MsgStr="Ok"; 00812 try { 00813 Lx.GetSym(ExpExpect); 00814 Exp=LoadTxtExp(Lx, Expect); 00815 } 00816 catch (PExcept Except){ 00817 Ok=false; MsgStr=Except->GetMsgStr(); 00818 Exp=PExp(new TExp(etUndef)); 00819 } 00820 return Exp; 00821 } 00822 00823 void TExp::SaveTxt(TOLx& Lx) const { 00824 if (IsParen){Lx.PutSym(syLParen);} 00825 TExpType _ExpType=TExpType(int(ExpType)); 00826 switch (_ExpType){ 00827 case etVal: 00828 ExpVal->SaveTxt(Lx); break; 00829 case etVec:{ 00830 Lx.PutSym(syLBrace); 00831 for (int ArgExpN=0; ArgExpN<ArgExpV.Len(); ArgExpN++){ 00832 if (ArgExpN>0){Lx.PutSym(syComma);} 00833 ArgExpV[ArgExpN]->SaveTxt(Lx); 00834 } 00835 Lx.PutSym(syRBrace); 00836 break;} 00837 case etLst:{ 00838 Lx.PutSym(syLBracket); 00839 for (int ArgExpN=0; ArgExpN<ArgExpV.Len(); ArgExpN++){ 00840 if (ArgExpN>0){Lx.PutSym(syComma);} 00841 ArgExpV[ArgExpN]->SaveTxt(Lx); 00842 } 00843 Lx.PutSym(syRBracket); 00844 break;} 00845 case etOp: 00846 SaveTxtOp(Lx); break; 00847 case etVar: 00848 case etBiConst: 00849 Lx.PutIdStr(ExpNm); break; 00850 case etFunc: 00851 case etBiFunc:{ 00852 Lx.PutIdStr(ExpNm); 00853 Lx.PutSym(syLParen); 00854 for (int ArgExpN=0; ArgExpN<ArgExpV.Len(); ArgExpN++){ 00855 if (ArgExpN>0){Lx.PutSym(syComma);} 00856 ArgExpV[ArgExpN]->SaveTxt(Lx); 00857 } 00858 Lx.PutSym(syRParen); 00859 break;} 00860 default: Fail; 00861 } 00862 if (IsParen){Lx.PutSym(syRParen);} 00863 } 00864 00865 TStr TExp::GetStr() const { 00866 PSOut SOut=TMOut::New(); TMOut& MOut=*(TMOut*)SOut(); 00867 SaveTxt(SOut); 00868 TStr ExpStr=TStr::LoadTxt(MOut.GetSIn()); 00869 return ExpStr; 00870 } 00871 00872 TStr TExp::GetTopObjNm() const { 00873 TStr TopObjNm; 00874 TExpType _ExpType=TExpType(int(ExpType)); 00875 switch (_ExpType){ 00876 case etOp:{ 00877 TExpOp _ExpOp=TExpOp(int(ExpOp)); 00878 TopObjNm=GetExpOpStr(_ExpOp); 00879 break;} 00880 case etVar: 00881 case etBiConst: 00882 case etFunc: 00883 case etBiFunc:{ 00884 TopObjNm=ExpNm; break;} 00885 default: break; 00886 } 00887 return TopObjNm; 00888 } 00889 00890 int TExp::GetArgExps() const { 00891 return ArgExpV.Len(); 00892 } 00893 00894 TStr TExp::GetArgExpStr(const int& ArgExpN) const { 00895 return ArgExpV[ArgExpN]->GetStr(); 00896 } 00897 00898 PExpVal TExp::Eval( 00899 bool& Ok, TStr& MsgStr, const bool& DbgP, TStr& DbgStr, const PExpEnv& ExpEnv){ 00900 Ok=true; MsgStr="Ok"; 00901 PExpVal ExpVal; TChA DbgChA; 00902 if (DbgP){DbgChA+="Debug Expression: ";} 00903 try { 00904 ExpVal=EvalExp(ExpEnv, DbgP, DbgChA); 00905 } 00906 catch (PExcept E){ 00907 Ok=false; MsgStr=E->GetMsgStr(); 00908 } 00909 if (!Ok){return TExpVal::GetUndefExpVal();} 00910 if (DbgP){ 00911 DbgChA+='['; DbgChA+=GetStr(); DbgChA+=" -> "; 00912 DbgChA+=ExpVal->GetStr(); DbgChA+="] "; DbgChA+=MsgStr; 00913 DbgStr=DbgChA; 00914 } 00915 return ExpVal; 00916 } 00917 00918 PExpVal TExp::LoadAndEvalExpL( 00919 const TStr& ExpLStr, bool& Ok, TStr& MsgStr, const PExpEnv& ExpEnv){ 00920 // create final expression value 00921 PExpVal ExpVal; 00922 // transform exp. str. to input stream 00923 PSIn SIn=TStrIn::New(ExpLStr); 00924 // create lexical 00925 TILx Lx(SIn, TFSet()|iloCmtAlw|iloCsSens|iloExcept); 00926 TFSet Expect=TFSet()|sySemicolon|syEof; 00927 // load & evaluate expression separated by semicolon 00928 while (Lx.Sym!=syEof){ 00929 // create expression 00930 PExp Exp; Ok=true; MsgStr="Ok"; 00931 try { 00932 Lx.GetSym(ExpExpect); 00933 Exp=LoadTxtExp(Lx, Expect); 00934 } 00935 catch (PExcept Except){ 00936 Ok=false; MsgStr=Except->GetMsgStr(); 00937 Exp=PExp(new TExp(etUndef)); 00938 } 00939 // evaluate expression 00940 if (Ok){ 00941 ExpVal=Exp->Eval(Ok, MsgStr, ExpEnv); 00942 //printf("%s\n", ExpVal->GetStr().CStr()); 00943 if (!Ok){ 00944 return NULL;} 00945 } else { 00946 return NULL; 00947 } 00948 } 00949 return ExpVal; 00950 } 00951 00952 TStr TExp::GetExpTypeStr(const TExpType& ExpType){ 00953 switch (ExpType){ 00954 case etUndef: return "Undef"; 00955 case etVal: return "Val"; 00956 case etVec: return "Vec"; 00957 case etLst: return "Lst"; 00958 case etOp: return "Op"; 00959 case etVar: return "Var"; 00960 case etBiConst: return "BiConst"; 00961 case etFunc: return "Func"; 00962 case etBiFunc: return "BiFunc"; 00963 default: Fail; return ""; 00964 } 00965 } 00966 00967 void TExp::GetBiDescV(TStrPrV& BiDescV){ 00968 BiDescV.Clr(); 00969 // constants 00970 BiDescV.Add(TStrPr("True", "Logical 'True' == 1.")); 00971 BiDescV.Add(TStrPr("False", "Logical 'False' == 0.")); 00972 BiDescV.Add(TStrPr("E", "Nat. logarithm basis (2.7182...).")); 00973 BiDescV.Add(TStrPr("Pi", "Constant pi (3.1415...).")); 00974 00975 // trigonometric funcions 00976 BiDescV.Add(TStrPr("Sin(X)", "Sine of angle in radians.")); 00977 BiDescV.Add(TStrPr("Cos(X)", "Cosine of angle in radians.")); 00978 BiDescV.Add(TStrPr("Tan(X)", "Tangent of angle in radians.")); 00979 BiDescV.Add(TStrPr("ASin(X)", "Arc sine of (-1..+1).")); 00980 BiDescV.Add(TStrPr("ACos(X)", "Arc cosine of (-1..+1).")); 00981 BiDescV.Add(TStrPr("ATan(X)", "Arc tangent of (-inf..+inf).")); 00982 BiDescV.Add(TStrPr("SinH(X)", "Hyperbolic sine.")); 00983 BiDescV.Add(TStrPr("CosH(X)", "Hyperbolic cosine.")); 00984 BiDescV.Add(TStrPr("TanH(X)", "Hyperbolic tangent.")); 00985 00986 // exponential functions 00987 BiDescV.Add(TStrPr("Pow(X, Y)", "X to the power of Y.")); 00988 BiDescV.Add(TStrPr("Exp(X)", "Exponential E to the power of X.")); 00989 BiDescV.Add(TStrPr("Sqr(X)", "X squared.")); 00990 BiDescV.Add(TStrPr("Sqrt(X)", "Positive square root.")); 00991 BiDescV.Add(TStrPr("Log(X)", "Natural logarithm.")); 00992 BiDescV.Add(TStrPr("Log10(X)", "Base 10 logarithm.")); 00993 00994 // number manipulation functions 00995 BiDescV.Add(TStrPr("Ceil(X)", "The smallest integer not less than X.")); 00996 BiDescV.Add(TStrPr("Floor(X)", "The largest integer not greater than X.")); 00997 BiDescV.Add(TStrPr("Int(X)", "Integer part of X.")); 00998 BiDescV.Add(TStrPr("Frac(X)", "Fractional part of X.")); 00999 BiDescV.Add(TStrPr("Abs(X)", "Absolute value of X.")); 01000 01001 // random deviates 01002 BiDescV.Add(TStrPr("UniDev()", "Uniform deviate (0..1).")); 01003 BiDescV.Add(TStrPr("NrmDev()", "Normal deviate (0, 1).")); 01004 BiDescV.Add(TStrPr("ExpDev()", "Exponential deviate.")); 01005 BiDescV.Add(TStrPr("GamDev(Order)", "Gamma deviate of Order.")); 01006 BiDescV.Add(TStrPr("PoiDev(Mean)", "Poisson deviate.")); 01007 BiDescV.Add(TStrPr("BinDev(Prb, Trials)", "Binomial deviate.")); 01008 01009 // operators 01010 BiDescV.Add(TStrPr("+N", "Unary plus.")); 01011 BiDescV.Add(TStrPr("-N", "Unary minus.")); 01012 BiDescV.Add(TStrPr("!L", "Not.")); 01013 BiDescV.Add(TStrPr("N1+N2", "Plus.")); 01014 BiDescV.Add(TStrPr("N1-N2", "Minus.")); 01015 BiDescV.Add(TStrPr("N1*N2", "Multiply.")); 01016 BiDescV.Add(TStrPr("N1/N2", "Division.")); 01017 BiDescV.Add(TStrPr("N1#N2", "Integer division.")); 01018 BiDescV.Add(TStrPr("N1%N2", "Modulo.")); 01019 BiDescV.Add(TStrPr("L1&L2", "And.")); 01020 BiDescV.Add(TStrPr("L1|L2", "Or.")); 01021 BiDescV.Add(TStrPr("E1=E2", "Equal.")); 01022 BiDescV.Add(TStrPr("E1<>E2", "Not equal.")); 01023 BiDescV.Add(TStrPr("E1<E2", "Less.")); 01024 BiDescV.Add(TStrPr("E1>E2", "Greater.")); 01025 BiDescV.Add(TStrPr("E1<=E2", "Less or equal.")); 01026 BiDescV.Add(TStrPr("E1>=E2", "Greater or equal.")); 01027 BiDescV.Add(TStrPr("L?E1:E2", "If L then return E1 else return E2.")); 01028 } 01029 01031 // Expression-Help-Object 01032 TStr TExpHelpObj::GetHdArgNmStr() const { 01033 TChA ChA; 01034 switch (Type){ 01035 case ehotOp: {// operator 01036 TStr OpStr=HdItem->GetNm(); 01037 if (ArgItemV.Len()==1){ 01038 ChA+=OpStr; ChA+=" "; ChA+=ArgItemV[0]->GetNm(); 01039 } else 01040 if (ArgItemV.Len()==2){ 01041 ChA+=ArgItemV[0]->GetNm(); 01042 ChA+=" "; ChA+=OpStr; ChA+=" "; 01043 ChA+=ArgItemV[1]->GetNm(); 01044 } else 01045 if (ArgItemV.Len()==3){ 01046 ChA+=ArgItemV[0]->GetNm(); 01047 ChA+=" "; ChA+=OpStr; ChA+=" "; 01048 ChA+=ArgItemV[1]->GetNm(); 01049 ChA+=" "; ChA+=":"; ChA+=" "; 01050 ChA+=ArgItemV[2]->GetNm(); 01051 } else { 01052 Fail; 01053 } 01054 break;} 01055 case ehotVar: // variable 01056 ChA+=HdItem->GetNm(); break; 01057 case ehotFunc: // function 01058 ChA+=HdItem->GetTypeStr(); ChA+=" <- "; 01059 ChA+=HdItem->GetNm(); 01060 ChA+="("; 01061 {for (int ArgN=0; ArgN<ArgItemV.Len(); ArgN++){ 01062 if (ArgN>0){ChA+=", ";} 01063 ChA+=ArgItemV[ArgN]->GetNm(); 01064 }} 01065 ChA+=")"; 01066 break; 01067 case ehotTempl: // template 01068 ChA+=HdItem->GetTypeStr(); break; 01069 default: Fail; 01070 } 01071 return ChA; 01072 } 01073 01074 TExpHelpObjType TExpHelpObj::GetObjTypeFromStr(const TStr& TypeStr){ 01075 if (TypeStr=="Op"){return ehotOp;} 01076 else if (TypeStr=="Var"){return ehotVar;} 01077 else if (TypeStr=="Func"){return ehotFunc;} 01078 else if (TypeStr=="Templ"){return ehotTempl;} 01079 else {TExcept::Throw("Invalid object type.", TypeStr); return ehotUndef;} 01080 } 01081 01083 // Expression-Help 01084 PExpHelp TExpHelp::LoadXml(const PSIn& SIn){ 01085 // create expression help 01086 PExpHelp ExpHelp=TExpHelp::New(); 01087 // load xml with expression help 01088 PXmlDoc Doc=TXmlDoc::LoadTxt(SIn); 01089 // retrieve objects 01090 TXmlTokV ObjTokV; Doc->GetTagTokV("ExpHelp|Obj", ObjTokV); 01091 for (int ObjTokN=0; ObjTokN<ObjTokV.Len(); ObjTokN++){ 01092 PXmlTok ObjTok=ObjTokV[ObjTokN]; 01093 // type 01094 TStr TypeStr=ObjTok->GetTagTok("Type")->GetTokStr(false); 01095 // category 01096 TStr CatNm=ObjTok->GetTagTok("Cat")->GetTokStr(false); 01097 // header 01098 TStr HdNm=ObjTok->GetTagTok("Head|Name")->GetTokStr(false); 01099 TStr HdTypeStr=ObjTok->GetTagTok("Head|Type")->GetTokStr(false); 01100 TStr HdDescStr=ObjTok->GetTagTok("Head|Desc")->GetTokStr(false); 01101 PExpHelpItem HdItem= 01102 TExpHelpItem::New(HdNm, HdTypeStr, HdDescStr, ""); 01103 // arguments 01104 TXmlTokV ArgTokV; ObjTok->GetTagTokV("Args|Arg", ArgTokV); 01105 TExpHelpItemV ArgItemV; 01106 for (int ArgTokN=0; ArgTokN<ArgTokV.Len(); ArgTokN++){ 01107 PXmlTok ArgTok=ArgTokV[ArgTokN]; 01108 // argument 01109 TStr ArgNm=ArgTok->GetTagTok("Name")->GetTokStr(false); 01110 TStr ArgTypeStr=ArgTok->GetTagTok("Type")->GetTokStr(false); 01111 TStr ArgDescStr=ArgTok->GetTagTok("Desc")->GetTokStr(false); 01112 TStr ArgDfValStr=ArgTok->GetTagTok("Default")->GetTokStr(false); 01113 PExpHelpItem ArgItem= 01114 TExpHelpItem::New(ArgNm, ArgTypeStr, ArgDescStr, ArgDfValStr); 01115 ArgItemV.Add(ArgItem); 01116 } 01117 // create & add object 01118 TExpHelpObjType Type=TExpHelpObj::GetObjTypeFromStr(TypeStr); 01119 PExpHelpObj Obj=TExpHelpObj::New(Type, CatNm, HdItem, ArgItemV); 01120 ExpHelp->AddObj(Obj); 01121 } 01122 // return result 01123 return ExpHelp; 01124 } 01125 01126 void TExpHelp::GetCatNmV(TStrV& CatNmV) const { 01127 CatNmV.Clr(); 01128 for (int ObjN=0; ObjN<ObjV.Len(); ObjN++){ 01129 TStr CatNm=ObjV[ObjN]->GetCatNm(); 01130 CatNmV.AddUnique(CatNm); 01131 } 01132 CatNmV.Ins(0, "All"); 01133 } 01134 01135 void TExpHelp::GetObjHdNmV(const TStr& CatNm, TStrV& ObjHdNmV) const { 01136 ObjHdNmV.Clr(); 01137 for (int ObjN=0; ObjN<ObjV.Len(); ObjN++){ 01138 TStr ObjCatNm=ObjV[ObjN]->GetCatNm(); 01139 TStr ObjHdNm=ObjV[ObjN]->GetHdItem()->GetNm(); 01140 if ((CatNm.Empty())||(CatNm=="All")||(CatNm==ObjCatNm)){ 01141 ObjHdNmV.AddUnique(ObjHdNm);} 01142 } 01143 ObjHdNmV.Sort(); 01144 } 01145 01146 PExpHelpObj TExpHelp::GetObj(const TStr& ObjNm) const { 01147 PExpHelpObj Obj; 01148 for (int ObjN=0; ObjN<ObjV.Len(); ObjN++){ 01149 if (ObjV[ObjN]->GetHdItem()->GetNm().GetUc()==ObjNm.GetUc()){ 01150 return ObjV[ObjN];} 01151 } 01152 return NULL; 01153 } 01154