00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <ncbi_pch.hpp>
00035
00036 #include <corelib/expr.hpp>
00037
00038 #include <math.h>
00039 #include <limits>
00040
00041
00042 BEGIN_NCBI_SCOPE
00043
00044
00045 CExprValue::CExprValue(void)
00046 : ival(0)
00047 , m_Var(NULL)
00048 , m_Pos(0)
00049 , m_Tag()
00050 {
00051 }
00052
00053 CExprValue::CExprValue(const CExprValue& value)
00054 : ival(value.ival)
00055 , m_Var(value.m_Var)
00056 , m_Pos(value.m_Pos)
00057 , m_Tag(value.m_Tag)
00058 {
00059 }
00060
00061 CExprValue::CExprValue(Uint4 value)
00062 : ival(value)
00063 , m_Var(NULL)
00064 , m_Pos(0)
00065 , m_Tag(eINT)
00066 {
00067 }
00068
00069 CExprValue::CExprValue(Int4 value)
00070 : ival(value)
00071 , m_Var(NULL)
00072 , m_Pos(0)
00073 , m_Tag(eINT)
00074 {
00075 }
00076
00077 CExprValue::CExprValue(Uint8 value)
00078 : ival(0)
00079 , m_Var(NULL)
00080 , m_Pos(0)
00081 , m_Tag(eINT)
00082 {
00083 if (static_cast<Uint8>(numeric_limits<Int8>::max()) < value) {
00084 NCBI_THROW2(CExprParserException,
00085 eTypeConversionError,
00086 "Value too big to fit in the 8-byte signed integer type",
00087 m_Pos);
00088 }
00089
00090 ival = static_cast<Int8>(value);
00091 }
00092
00093
00094 CExprValue::CExprValue(Int8 value)
00095 : ival(value)
00096 , m_Var(NULL)
00097 , m_Pos(0)
00098 , m_Tag(eINT)
00099 {
00100 }
00101
00102 CExprValue::CExprValue(double value)
00103 : fval(value)
00104 , m_Var(NULL)
00105 , m_Pos(0)
00106 , m_Tag(eFLOAT)
00107 {
00108 }
00109
00110 CExprValue::CExprValue(bool value)
00111 : bval(value)
00112 , m_Var(NULL)
00113 , m_Pos(0)
00114 , m_Tag(eBOOL)
00115 {
00116 }
00117
00118
00119 CExprSymbol::CExprSymbol(void)
00120 : m_Tag()
00121 , m_IntFunc1(NULL)
00122 , m_Val()
00123 , m_Next(NULL)
00124 {
00125 }
00126
00127 CExprSymbol::~CExprSymbol(void)
00128 {
00129 delete m_Next;
00130 }
00131
00132 CExprSymbol::CExprSymbol(const char* name, Uint4 value)
00133 : m_Tag(eVARIABLE)
00134 , m_IntFunc1(NULL)
00135 , m_Val(value)
00136 , m_Name(name)
00137 , m_Next(NULL)
00138 {
00139 }
00140
00141 CExprSymbol::CExprSymbol(const char* name, Int4 value)
00142 : m_Tag(eVARIABLE)
00143 , m_IntFunc1(NULL)
00144 , m_Val(value)
00145 , m_Name(name)
00146 , m_Next(NULL)
00147 {
00148 }
00149
00150 CExprSymbol::CExprSymbol(const char* name, Uint8 value)
00151 : m_Tag(eVARIABLE)
00152 , m_IntFunc1(NULL)
00153 , m_Val(value)
00154 , m_Name(name)
00155 , m_Next(NULL)
00156 {
00157 }
00158
00159 CExprSymbol::CExprSymbol(const char* name, Int8 value)
00160 : m_Tag(eVARIABLE)
00161 , m_IntFunc1(NULL)
00162 , m_Val(value)
00163 , m_Name(name)
00164 , m_Next(NULL)
00165 {
00166 }
00167
00168 CExprSymbol::CExprSymbol(const char* name, bool value)
00169 : m_Tag(eVARIABLE)
00170 , m_IntFunc1(NULL)
00171 , m_Val(value)
00172 , m_Name(name)
00173 , m_Next(NULL)
00174 {
00175 }
00176
00177 CExprSymbol::CExprSymbol(const char* name, double value)
00178 : m_Tag(eVARIABLE)
00179 , m_IntFunc1(NULL)
00180 , m_Val(value)
00181 , m_Name(name)
00182 , m_Next(NULL)
00183 {
00184 }
00185
00186 CExprSymbol::CExprSymbol(const char* name, FIntFunc1 value)
00187 : m_Tag(eIFUNC1)
00188 , m_IntFunc1(value)
00189 , m_Val((Int8)0)
00190 , m_Name(name)
00191 , m_Next(NULL)
00192 {
00193 }
00194
00195 CExprSymbol::CExprSymbol(const char* name, FIntFunc2 value)
00196 : m_Tag(eIFUNC2)
00197 , m_IntFunc2(value)
00198 , m_Val((Int8)0)
00199 , m_Name(name)
00200 , m_Next(NULL)
00201 {
00202 }
00203
00204 CExprSymbol::CExprSymbol(const char* name, FFloatFunc1 value)
00205 : m_Tag(eFFUNC1)
00206 , m_FloatFunc1(value)
00207 , m_Val((Int8)0)
00208 , m_Name(name)
00209 , m_Next(NULL)
00210 {
00211 }
00212
00213 CExprSymbol::CExprSymbol(const char* name, FFloatFunc2 value)
00214 : m_Tag(eFFUNC2)
00215 , m_FloatFunc2(value)
00216 , m_Val((Int8)0)
00217 , m_Name(name)
00218 , m_Next(NULL)
00219 {
00220 }
00221
00222 CExprSymbol::CExprSymbol(const char* name, FBoolFunc1 value)
00223 : m_Tag(eBFUNC1)
00224 , m_BoolFunc1(value)
00225 , m_Val((Int8)0)
00226 , m_Name(name)
00227 , m_Next(NULL)
00228 {
00229 }
00230
00231 CExprSymbol::CExprSymbol(const char* name, FBoolFunc2 value)
00232 : m_Tag(eBFUNC2)
00233 , m_BoolFunc2(value)
00234 , m_Val((Int8)0)
00235 , m_Name(name)
00236 , m_Next(NULL)
00237 {
00238 }
00239
00240
00241 static
00242 Int8 to_int(Int8 m_Val)
00243 {
00244 return m_Val;
00245 }
00246
00247 static
00248 double to_float(double m_Val)
00249 {
00250 return m_Val;
00251 }
00252
00253 static
00254 Int8 gcd(Int8 x, Int8 y)
00255 {
00256 while (x) {
00257 Int8 r = y%x;
00258 y=x;
00259 x=r;
00260 }
00261
00262 return y;
00263 }
00264
00265 static
00266 Int8 invmod(Int8 x, Int8 y)
00267 {
00268 Int8 m = y;
00269 Int8 u = 1, v = 0;
00270 Int8 s = 0, t = 1;
00271
00272 while (x) {
00273 Int8 q = y/x;
00274 Int8 r = y%x;
00275 Int8 a = s - q*u;
00276 Int8 b = t - q*v;
00277 y=x; s=u; t=v;
00278 x=r; u=a; v=b;
00279 }
00280
00281 if (y!=1) return 0;
00282
00283 while (s<0) s+=m;
00284
00285 return s;
00286 }
00287
00288 static
00289 Int8 prime(Int8 n)
00290 {
00291 if (n <= 3) {
00292 return n;
00293 }
00294 n |= 1;
00295 while (true) {
00296 Int8 m = (Int8)sqrt((double)n) + 1;
00297 Int8 k = 3;
00298 while (true) {
00299 if (k > m) {
00300 return n;
00301 }
00302 if (n % k == 0) break;
00303 k += 2;
00304 }
00305 n += 2;
00306 }
00307 }
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337 unsigned string_hash_function(const char* p)
00338 {
00339 unsigned h = 0, g;
00340 while(*p) {
00341 h = (h << 4) + *p++;
00342 if ((g = h & 0xF0000000) != 0) {
00343 h ^= g >> 24;
00344 }
00345 h &= ~g;
00346 }
00347 return h;
00348 }
00349
00350
00351 const char* CExprParserException::GetErrCodeString(void) const
00352 {
00353 switch (GetErrCode()) {
00354 case eParseError: return "eParseError";
00355 case eTypeConversionError: return "eTypeConversionError";
00356 default:
00357 break;
00358 }
00359
00360 return CException::GetErrCodeString();
00361 }
00362
00363 void CExprParserException::ReportExtra(ostream& out) const
00364 {
00365 out << "pos: " << m_Pos;
00366 }
00367
00368 void CExprParserException::x_Assign(const CException& src)
00369 {
00370 CException::x_Assign(src);
00371
00372 const CExprParserException& other = dynamic_cast<const CExprParserException&>(src);
00373 m_Pos = other.m_Pos;
00374 }
00375
00376
00377 CExprParser::CExprParser(CExprParser::EAutoVar auto_var)
00378 : m_Buf(NULL)
00379 , m_Pos(0)
00380 , m_TmpVarCount(0)
00381 , m_AutoCreateVariable(auto_var)
00382 {
00383 memset(hash_table, 0, sizeof(hash_table));
00384
00385 AddSymbol("abs", (CExprSymbol::FFloatFunc1)fabs);
00386 AddSymbol("acos", (CExprSymbol::FFloatFunc1)acos);
00387 AddSymbol("asin", (CExprSymbol::FFloatFunc1)asin);
00388 AddSymbol("atan", (CExprSymbol::FFloatFunc1)atan);
00389 AddSymbol("atan2", (CExprSymbol::FFloatFunc2)atan2);
00390 AddSymbol("cos", (CExprSymbol::FFloatFunc1)cos);
00391 AddSymbol("cosh", (CExprSymbol::FFloatFunc1)cosh);
00392 AddSymbol("exp", (CExprSymbol::FFloatFunc1)exp);
00393 AddSymbol("log", (CExprSymbol::FFloatFunc1)log);
00394 AddSymbol("log10", (CExprSymbol::FFloatFunc1)log10);
00395 AddSymbol("sin", (CExprSymbol::FFloatFunc1)sin);
00396 AddSymbol("sinh", (CExprSymbol::FFloatFunc1)sinh);
00397 AddSymbol("tan", (CExprSymbol::FFloatFunc1)tan);
00398 AddSymbol("tanh", (CExprSymbol::FFloatFunc1)tanh);
00399 AddSymbol("sqrt", (CExprSymbol::FFloatFunc1)sqrt);
00400
00401 AddSymbol("float", to_float);
00402 AddSymbol("int", to_int);
00403
00404 AddSymbol("gcd", gcd);
00405 AddSymbol("invmod", invmod);
00406
00407 AddSymbol("prime", prime);
00408
00409 AddSymbol("pi", 3.1415926535897932385E0);
00410 AddSymbol("e", 2.7182818284590452354E0);
00411 }
00412
00413 CExprParser::~CExprParser(void)
00414 {
00415 for (int i = 0; i < hash_table_size; ++i) {
00416 delete hash_table[i];
00417 }
00418 }
00419
00420 int CExprParser::sm_lpr[eTERMINALS] = {
00421 2, 0, 0, 0,
00422 4, 4,
00423 5, 98, 98,
00424 98, 98, 98, 98, 98, 98,
00425 90,
00426 80, 80, 80,
00427 70, 70,
00428 60, 60, 60,
00429 50, 50, 50, 50,
00430 40, 40,
00431 38,
00432 36,
00433 34,
00434 20, 20, 20, 20, 20, 20, 20,
00435 20, 20, 20, 20, 20, 20,
00436 10
00437 };
00438
00439 int CExprParser::sm_rpr[eTERMINALS] = {
00440 0, 0, 0, 1,
00441 110, 3,
00442 120, 99, 99,
00443 99, 99, 99, 99, 99, 99,
00444 95,
00445 80, 80, 80,
00446 70, 70,
00447 60, 60, 60,
00448 50, 50, 50, 50,
00449 40, 40,
00450 38,
00451 36,
00452 34,
00453 25, 25, 25, 25, 25, 25, 25,
00454 25, 25, 25, 25, 25, 25,
00455 15
00456 };
00457
00458 CExprSymbol* CExprParser::GetSymbol(const char* name) const
00459 {
00460 unsigned h = string_hash_function(name) % hash_table_size;
00461 CExprSymbol* sp = NULL;
00462
00463 for (sp = hash_table[h]; sp != NULL; sp = sp->m_Next) {
00464 if (sp->m_Name.compare(name) == 0) {
00465 return sp;
00466 }
00467 }
00468
00469 return sp;
00470 }
00471
00472 CExprParser::EOperator
00473 CExprParser::Scan(bool operand)
00474 {
00475 char sym_name[max_expression_length], *np;
00476
00477 while (isspace(m_Buf[m_Pos])) m_Pos += 1;
00478
00479 switch (m_Buf[m_Pos++]) {
00480 case '\0':
00481 return eEND;
00482 case '(':
00483 return eLPAR;
00484 case ')':
00485 return eRPAR;
00486 case '+':
00487 if (m_Buf[m_Pos] == '+') {
00488 m_Pos += 1;
00489 return operand ? ePREINC : ePOSTINC;
00490 } else if (m_Buf[m_Pos] == '=') {
00491 m_Pos += 1;
00492 return eSETADD;
00493 }
00494 return operand ? ePLUS : eADD;
00495 case '-':
00496 if (m_Buf[m_Pos] == '-') {
00497 m_Pos += 1;
00498 return operand ? ePREDEC : ePOSTDEC;
00499 } else if (m_Buf[m_Pos] == '=') {
00500 m_Pos += 1;
00501 return eSETSUB;
00502 }
00503 return operand ? eMINUS : eSUB;
00504 case '!':
00505 return IfChar('=', eNE, eNOT);
00506 case '~':
00507 return eCOM;
00508 case '*':
00509 return IfLongest2ElseChar('*', '=', eSETPOW, ePOW, eSETMUL, eMUL);
00510 case '/':
00511 return IfChar('=', eSETDIV, eDIV);
00512 case '%':
00513 return IfChar('=', eSETMOD, eMOD);
00514 case '<':
00515 return IfLongest2ElseChar('<', '=', eSETASL, eASL, eLE, eLT);
00516 case '>':
00517 if (m_Buf[m_Pos] == '>') {
00518 if (m_Buf[m_Pos+1] == '>') {
00519 if (m_Buf[m_Pos+2] == '=') {
00520 m_Pos += 3;
00521 return eSETLSR;
00522 }
00523 m_Pos += 2;
00524 return eLSR;
00525 } else if (m_Buf[m_Pos+1] == '=') {
00526 m_Pos += 2;
00527 return eSETASR;
00528 } else {
00529 m_Pos += 1;
00530 return eASR;
00531 }
00532 } else if (m_Buf[m_Pos] == '=') {
00533 m_Pos += 1;
00534 return eGE;
00535 }
00536 return eGT;
00537 case '=':
00538 return IfChar('=', eEQ, eSET);
00539 case '&':
00540 return IfElseChar(
00541 '&', eAND,
00542 '=', eSETAND,
00543 eAND);
00544 case '|':
00545 return IfElseChar(
00546 '|', eOR,
00547 '=', eSETOR,
00548 eOR);
00549 case '^':
00550 return IfChar('=', eSETXOR, eXOR);
00551 case ',':
00552 return eCOMMA;
00553 case '0': case '1': case '2': case '3': case '4':
00554 case '5': case '6': case '7': case '8': case '9':
00555 {
00556 Int8 ival;
00557 double fval;
00558 int ierr, ferr;
00559 char *ipos;
00560 char *fpos;
00561
00562 #ifdef NCBI_OS_MSWIN
00563 int n = 0;
00564 ierr = sscanf(m_Buf+m_Pos-1, "%" INT_FORMAT "i%n", &ival, &n) != 1;
00565 ipos = const_cast<char*>(m_Buf+m_Pos-1+n);
00566 #else
00567 errno = 0;
00568 #if SIZEOF_LONG == 8
00569 ival = strtoul(m_Buf+m_Pos-1, &ipos, 0);
00570 #else
00571 ival = strtoull(m_Buf+m_Pos-1, &ipos, 0);
00572 #endif
00573 ierr = errno;
00574 #endif
00575 errno = 0;
00576 fval = strtod(m_Buf+m_Pos-1, &fpos);
00577 ferr = errno;
00578
00579 if (ierr && ferr) {
00580 ReportError("bad numeric constant");
00581 return eERROR;
00582 }
00583
00584 if (m_v_sp == max_stack_size) {
00585 ReportError("stack overflow");
00586 return eERROR;
00587 }
00588
00589 if (!ierr && ipos >= fpos) {
00590 m_VStack[m_v_sp].SetType(CExprValue::eINT);
00591 m_VStack[m_v_sp].ival = ival;
00592 m_Pos = ipos - m_Buf;
00593 } else {
00594 m_VStack[m_v_sp].SetType(CExprValue::eFLOAT);
00595 m_VStack[m_v_sp].fval = fval;
00596 m_Pos = fpos - m_Buf;
00597 }
00598
00599 m_VStack[m_v_sp].m_Pos = m_Pos;
00600 m_VStack[m_v_sp++].m_Var = NULL;
00601
00602 return eOPERAND;
00603 }
00604
00605 default:
00606 m_Pos -= 1;
00607 np = sym_name;
00608
00609 while (isalnum(m_Buf[m_Pos]) || m_Buf[m_Pos] == '$' || m_Buf[m_Pos] == '_') {
00610 *np++ = m_Buf[m_Pos++];
00611 }
00612
00613 if (np == m_Buf) {
00614 ReportError("Bad character");
00615 return eERROR;
00616 }
00617
00618 *np = '\0';
00619
00620
00621 if (strcmp(sym_name, "true") == 0) {
00622 m_VStack[m_v_sp].SetType(CExprValue::eBOOL);
00623 m_VStack[m_v_sp].bval = true;
00624
00625 m_VStack[m_v_sp].m_Pos = m_Pos;
00626 m_VStack[m_v_sp++].m_Var = NULL;
00627
00628 return eOPERAND;
00629 } else if (strcmp(sym_name, "false") == 0) {
00630 m_VStack[m_v_sp].SetType(CExprValue::eBOOL);
00631 m_VStack[m_v_sp].bval = false;
00632
00633 m_VStack[m_v_sp].m_Pos = m_Pos;
00634 m_VStack[m_v_sp++].m_Var = NULL;
00635
00636 return eOPERAND;
00637 }
00638
00639 CExprSymbol* sym = NULL;
00640
00641 if (AutoCreateVariable() == eAllowAutoVar) {
00642 sym = AddSymbol(sym_name, Int8(0));
00643 } else {
00644 sym = GetSymbol(sym_name);
00645 if (!sym) {
00646 ReportError(string("Invalid symbol name: ") + sym_name);
00647 return eERROR;
00648 }
00649 }
00650
00651 if (m_v_sp == max_stack_size) {
00652 ReportError("stack overflow");
00653 return eERROR;
00654 }
00655
00656 m_VStack[m_v_sp] = sym->m_Val;
00657 m_VStack[m_v_sp].m_Pos = m_Pos;
00658 m_VStack[m_v_sp++].m_Var = sym;
00659
00660 return (sym->m_Tag == CExprSymbol::eVARIABLE) ? eOPERAND : eFUNC;
00661 }
00662 }
00663
00664 bool CExprParser::Assign(void)
00665 {
00666 CExprValue& v = m_VStack[m_v_sp-1];
00667 if (v.m_Var == NULL) {
00668 ReportError(v.m_Pos, "variable expected");
00669 return false;
00670 } else {
00671 v.m_Var->m_Val = v;
00672 return true;
00673 }
00674 }
00675
00676 void CExprParser::Parse(const char* str)
00677 {
00678
00679 m_Buf = str;
00680 m_v_sp = 0;
00681 m_o_sp = 0;
00682 m_Pos = 0;
00683 m_OStack[m_o_sp++] = eBEGIN;
00684 bool operand = true;
00685 int n_args = 0;
00686
00687 while (true) {
00688 next_token:
00689 int op_pos = m_Pos;
00690
00691 EOperator oper = Scan(operand);
00692
00693 if (oper == eERROR) {
00694 return;
00695 }
00696
00697 if (!operand) {
00698 if (!BINARY(oper) && oper != eEND && oper != ePOSTINC
00699 && oper != ePOSTDEC && oper != eRPAR)
00700 {
00701 ReportError(op_pos, "operator expected");
00702 return;
00703 }
00704 if (oper != ePOSTINC && oper != ePOSTDEC && oper != eRPAR) {
00705 operand = true;
00706 }
00707 } else {
00708 if (oper == eOPERAND) {
00709 operand = false;
00710 n_args += 1;
00711 continue;
00712 }
00713 if (BINARY(oper) || oper == eRPAR) {
00714 ReportError(op_pos, "operand expected");
00715 return;
00716 }
00717 }
00718
00719 int n_args = 1;
00720
00721 while (sm_lpr[m_OStack[m_o_sp-1]] >= sm_rpr[oper]) {
00722 int cop = m_OStack[--m_o_sp];
00723
00724 switch (cop) {
00725 case eBEGIN:
00726 if (oper == eRPAR) {
00727 ReportError("Unmatched ')'");
00728 return;
00729 }
00730
00731 if (oper != eEND) {
00732 ReportError("Unexpected end of input");
00733 }
00734
00735 if (m_v_sp == 1) {
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747 return;
00748 } else if (m_v_sp != 0) {
00749 ReportError("Unexpected end of expression");
00750 }
00751
00752 return;
00753 case eCOMMA:
00754 n_args += 1;
00755 continue;
00756 case eADD:
00757 case eSETADD:
00758 if (m_VStack[m_v_sp-1].GetType() == CExprValue::eINT && m_VStack[m_v_sp-2].GetType() == CExprValue::eINT) {
00759 m_VStack[m_v_sp-2].ival += m_VStack[m_v_sp-1].ival;
00760 } else {
00761 m_VStack[m_v_sp-2].fval =
00762 m_VStack[m_v_sp-2].GetDouble() + m_VStack[m_v_sp-1].GetDouble();
00763 m_VStack[m_v_sp-2].SetType(CExprValue::eFLOAT);
00764 }
00765
00766 m_v_sp -= 1;
00767
00768 if (cop == eSETADD) {
00769 if (!Assign()) return;
00770 }
00771
00772 m_VStack[m_v_sp-1].m_Var = NULL;
00773 break;
00774 case eSUB:
00775 case eSETSUB:
00776 if (m_VStack[m_v_sp-1].GetType() == CExprValue::eINT && m_VStack[m_v_sp-2].GetType() == CExprValue::eINT) {
00777 m_VStack[m_v_sp-2].ival -= m_VStack[m_v_sp-1].ival;
00778 } else {
00779 m_VStack[m_v_sp-2].fval =
00780 m_VStack[m_v_sp-2].GetDouble() - m_VStack[m_v_sp-1].GetDouble();
00781 m_VStack[m_v_sp-2].SetType(CExprValue::eFLOAT);
00782 }
00783
00784 m_v_sp -= 1;
00785
00786 if (cop == eSETSUB) {
00787 if (!Assign()) return;
00788 }
00789
00790 m_VStack[m_v_sp-1].m_Var = NULL;
00791
00792 break;
00793 case eMUL:
00794 case eSETMUL:
00795 if (m_VStack[m_v_sp-1].GetType() == CExprValue::eINT && m_VStack[m_v_sp-2].GetType() == CExprValue::eINT) {
00796 m_VStack[m_v_sp-2].ival *= m_VStack[m_v_sp-1].ival;
00797 } else {
00798 m_VStack[m_v_sp-2].fval =
00799 m_VStack[m_v_sp-2].GetDouble() * m_VStack[m_v_sp-1].GetDouble();
00800 m_VStack[m_v_sp-2].SetType(CExprValue::eFLOAT);
00801 }
00802
00803 m_v_sp -= 1;
00804
00805 if (cop == eSETMUL) {
00806 if (!Assign()) return;
00807 }
00808 m_VStack[m_v_sp-1].m_Var = NULL;
00809
00810 break;
00811 case eDIV:
00812 case eSETDIV:
00813 if (m_VStack[m_v_sp-1].GetDouble() == 0.0) {
00814 ReportError(m_VStack[m_v_sp-2].m_Pos, "Division by zero");
00815 return;
00816 }
00817 if (m_VStack[m_v_sp-1].GetType() == CExprValue::eINT && m_VStack[m_v_sp-2].GetType() == CExprValue::eINT) {
00818 m_VStack[m_v_sp-2].ival /= m_VStack[m_v_sp-1].ival;
00819 } else {
00820 m_VStack[m_v_sp-2].fval =
00821 m_VStack[m_v_sp-2].GetDouble() / m_VStack[m_v_sp-1].GetDouble();
00822 m_VStack[m_v_sp-2].SetType(CExprValue::eFLOAT);
00823 }
00824 m_v_sp -= 1;
00825 if (cop == eSETDIV) {
00826 if (!Assign()) return;
00827 }
00828 m_VStack[m_v_sp-1].m_Var = NULL;
00829 break;
00830 case eMOD:
00831 case eSETMOD:
00832 if (m_VStack[m_v_sp-1].GetDouble() == 0.0) {
00833 ReportError(m_VStack[m_v_sp-2].m_Pos, "Division by zero");
00834 return;
00835 }
00836 if (m_VStack[m_v_sp-1].GetType() == CExprValue::eINT && m_VStack[m_v_sp-2].GetType() == CExprValue::eINT) {
00837 m_VStack[m_v_sp-2].ival %= m_VStack[m_v_sp-1].ival;
00838 } else {
00839 m_VStack[m_v_sp-2].fval =
00840 fmod(m_VStack[m_v_sp-2].GetDouble(), m_VStack[m_v_sp-1].GetDouble());
00841 m_VStack[m_v_sp-2].SetType(CExprValue::eFLOAT);
00842 }
00843 m_v_sp -= 1;
00844 if (cop == eSETMOD) {
00845 if (!Assign()) return;
00846 }
00847 m_VStack[m_v_sp-1].m_Var = NULL;
00848 break;
00849 case ePOW:
00850 case eSETPOW:
00851 if (m_VStack[m_v_sp-1].GetType() == CExprValue::eINT && m_VStack[m_v_sp-2].GetType() == CExprValue::eINT) {
00852 m_VStack[m_v_sp-2].ival =
00853 (Int8)pow((double)m_VStack[m_v_sp-2].ival,
00854 (double)m_VStack[m_v_sp-1].ival);
00855 } else {
00856 m_VStack[m_v_sp-2].fval =
00857 pow(m_VStack[m_v_sp-2].GetDouble(), m_VStack[m_v_sp-1].GetDouble());
00858 m_VStack[m_v_sp-2].SetType(CExprValue::eFLOAT);
00859 }
00860 m_v_sp -= 1;
00861 if (cop == eSETPOW) {
00862 if (!Assign()) return;
00863 }
00864 m_VStack[m_v_sp-1].m_Var = NULL;
00865 break;
00866 case eAND:
00867 case eSETAND:
00868 if (m_VStack[m_v_sp-1].GetType() == CExprValue::eINT && m_VStack[m_v_sp-2].GetType() == CExprValue::eINT) {
00869 m_VStack[m_v_sp-2].ival &= m_VStack[m_v_sp-1].ival;
00870 } else if (m_VStack[m_v_sp-2].GetType() == CExprValue::eBOOL) {
00871 m_VStack[m_v_sp-2].bval =
00872 m_VStack[m_v_sp-2].bval && m_VStack[m_v_sp-1].GetBool();
00873 } else {
00874 m_VStack[m_v_sp-2].ival =
00875 m_VStack[m_v_sp-2].GetInt() & m_VStack[m_v_sp-1].GetInt();
00876 m_VStack[m_v_sp-2].SetType(CExprValue::eINT);
00877 }
00878 m_v_sp -= 1;
00879 if (cop == eSETAND) {
00880 if (!Assign()) return;
00881 }
00882 m_VStack[m_v_sp-1].m_Var = NULL;
00883 break;
00884 case eOR:
00885 case eSETOR:
00886 if (m_VStack[m_v_sp-1].GetType() == CExprValue::eINT && m_VStack[m_v_sp-2].GetType() == CExprValue::eINT) {
00887 m_VStack[m_v_sp-2].ival |= m_VStack[m_v_sp-1].ival;
00888 } else if (m_VStack[m_v_sp-2].GetType() == CExprValue::eBOOL) {
00889 m_VStack[m_v_sp-2].bval =
00890 m_VStack[m_v_sp-2].bval || m_VStack[m_v_sp-1].GetBool();
00891 } else {
00892 m_VStack[m_v_sp-2].ival =
00893 m_VStack[m_v_sp-2].GetInt() | m_VStack[m_v_sp-1].GetInt();
00894 m_VStack[m_v_sp-2].SetType(CExprValue::eINT);
00895 }
00896 m_v_sp -= 1;
00897 if (cop == eSETOR) {
00898 if (!Assign()) return;
00899 }
00900 m_VStack[m_v_sp-1].m_Var = NULL;
00901 break;
00902 case eXOR:
00903 case eSETXOR:
00904 if (m_VStack[m_v_sp-1].GetType() == CExprValue::eINT && m_VStack[m_v_sp-2].GetType() == CExprValue::eINT) {
00905 m_VStack[m_v_sp-2].ival ^= m_VStack[m_v_sp-1].ival;
00906 } else if (m_VStack[m_v_sp-2].GetType() == CExprValue::eBOOL) {
00907 m_VStack[m_v_sp-2].bval =
00908 m_VStack[m_v_sp-2].bval != m_VStack[m_v_sp-1].GetBool();
00909 } else {
00910 m_VStack[m_v_sp-2].ival =
00911 m_VStack[m_v_sp-2].GetInt() ^ m_VStack[m_v_sp-1].GetInt();
00912 m_VStack[m_v_sp-2].SetType(CExprValue::eINT);
00913 }
00914 m_v_sp -= 1;
00915 if (cop == eSETXOR) {
00916 if (!Assign()) return;
00917 }
00918 m_VStack[m_v_sp-1].m_Var = NULL;
00919 break;
00920 case eASL:
00921 case eSETASL:
00922 if (m_VStack[m_v_sp-1].GetType() == CExprValue::eINT && m_VStack[m_v_sp-2].GetType() == CExprValue::eINT) {
00923 m_VStack[m_v_sp-2].ival <<= m_VStack[m_v_sp-1].ival;
00924 } else {
00925 m_VStack[m_v_sp-2].ival =
00926 m_VStack[m_v_sp-2].GetInt() << m_VStack[m_v_sp-1].GetInt();
00927 m_VStack[m_v_sp-2].SetType(CExprValue::eINT);
00928 }
00929 m_v_sp -= 1;
00930 if (cop == eSETASL) {
00931 if (!Assign()) return;
00932 }
00933 m_VStack[m_v_sp-1].m_Var = NULL;
00934 break;
00935 case eASR:
00936 case eSETASR:
00937 if (m_VStack[m_v_sp-1].GetType() == CExprValue::eINT && m_VStack[m_v_sp-2].GetType() == CExprValue::eINT) {
00938 m_VStack[m_v_sp-2].ival >>= m_VStack[m_v_sp-1].ival;
00939 } else {
00940 m_VStack[m_v_sp-2].ival =
00941 m_VStack[m_v_sp-2].GetInt() >> m_VStack[m_v_sp-1].GetInt();
00942 m_VStack[m_v_sp-2].SetType(CExprValue::eINT);
00943 }
00944 m_v_sp -= 1;
00945 if (cop == eSETASR) {
00946 if (!Assign()) return;
00947 }
00948 m_VStack[m_v_sp-1].m_Var = NULL;
00949 break;
00950 case eLSR:
00951 case eSETLSR:
00952 if (m_VStack[m_v_sp-1].GetType() == CExprValue::eINT && m_VStack[m_v_sp-2].GetType() == CExprValue::eINT) {
00953 m_VStack[m_v_sp-2].ival =
00954 (Uint8)m_VStack[m_v_sp-2].ival >> m_VStack[m_v_sp-1].ival;
00955 } else {
00956 m_VStack[m_v_sp-2].ival = (Uint8)m_VStack[m_v_sp-2].GetInt()
00957 >> m_VStack[m_v_sp-1].GetInt();
00958 m_VStack[m_v_sp-2].SetType(CExprValue::eINT);
00959 }
00960 m_v_sp -= 1;
00961 if (cop == eSETLSR) {
00962 if (!Assign()) return;
00963 }
00964 m_VStack[m_v_sp-1].m_Var = NULL;
00965 break;
00966 case eEQ:
00967 if (m_VStack[m_v_sp-1].GetType() == CExprValue::eINT && m_VStack[m_v_sp-2].GetType() == CExprValue::eINT) {
00968 m_VStack[m_v_sp-2].bval =
00969 m_VStack[m_v_sp-2].ival == m_VStack[m_v_sp-1].ival;
00970 m_VStack[m_v_sp-2].SetType(CExprValue::eBOOL);
00971 } else if (m_VStack[m_v_sp-2].GetType() == CExprValue::eBOOL) {
00972 m_VStack[m_v_sp-2].bval =
00973 m_VStack[m_v_sp-2].bval == m_VStack[m_v_sp-1].GetBool();
00974 } else {
00975 m_VStack[m_v_sp-2].bval =
00976 m_VStack[m_v_sp-2].GetDouble() == m_VStack[m_v_sp-1].GetDouble();
00977 m_VStack[m_v_sp-2].SetType(CExprValue::eBOOL);
00978 }
00979 m_v_sp -= 1;
00980 m_VStack[m_v_sp-1].m_Var = NULL;
00981 break;
00982 case eNE:
00983 if (m_VStack[m_v_sp-1].GetType() == CExprValue::eINT && m_VStack[m_v_sp-2].GetType() == CExprValue::eINT) {
00984 m_VStack[m_v_sp-2].bval =
00985 m_VStack[m_v_sp-2].ival != m_VStack[m_v_sp-1].ival;
00986 m_VStack[m_v_sp-2].SetType(CExprValue::eBOOL);
00987 } else if (m_VStack[m_v_sp-2].GetType() == CExprValue::eBOOL) {
00988 m_VStack[m_v_sp-2].bval =
00989 m_VStack[m_v_sp-2].bval != m_VStack[m_v_sp-1].GetBool();
00990 } else {
00991 m_VStack[m_v_sp-2].bval =
00992 m_VStack[m_v_sp-2].GetDouble() != m_VStack[m_v_sp-1].GetDouble();
00993 m_VStack[m_v_sp-2].SetType(CExprValue::eBOOL);
00994 }
00995 m_v_sp -= 1;
00996 m_VStack[m_v_sp-1].m_Var = NULL;
00997 break;
00998 case eGT:
00999 if (m_VStack[m_v_sp-1].GetType() == CExprValue::eINT && m_VStack[m_v_sp-2].GetType() == CExprValue::eINT) {
01000 m_VStack[m_v_sp-2].bval =
01001 m_VStack[m_v_sp-2].ival > m_VStack[m_v_sp-1].ival;
01002 m_VStack[m_v_sp-2].SetType(CExprValue::eBOOL);
01003 } else if (m_VStack[m_v_sp-2].GetType() == CExprValue::eBOOL) {
01004 m_VStack[m_v_sp-2].bval =
01005 m_VStack[m_v_sp-2].bval > m_VStack[m_v_sp-1].GetBool();
01006 } else {
01007 m_VStack[m_v_sp-2].bval =
01008 m_VStack[m_v_sp-2].GetDouble() > m_VStack[m_v_sp-1].GetDouble();
01009 m_VStack[m_v_sp-2].SetType(CExprValue::eBOOL);
01010 }
01011 m_v_sp -= 1;
01012 m_VStack[m_v_sp-1].m_Var = NULL;
01013 break;
01014 case eGE:
01015 if (m_VStack[m_v_sp-1].GetType() == CExprValue::eINT && m_VStack[m_v_sp-2].GetType() == CExprValue::eINT) {
01016 m_VStack[m_v_sp-2].bval =
01017 m_VStack[m_v_sp-2].ival >= m_VStack[m_v_sp-1].ival;
01018 m_VStack[m_v_sp-2].SetType(CExprValue::eBOOL);
01019 } else if (m_VStack[m_v_sp-2].GetType() == CExprValue::eBOOL) {
01020 m_VStack[m_v_sp-2].bval =
01021 m_VStack[m_v_sp-2].bval >= m_VStack[m_v_sp-1].GetBool();
01022 } else {
01023 m_VStack[m_v_sp-2].bval =
01024 m_VStack[m_v_sp-2].GetDouble() >= m_VStack[m_v_sp-1].GetDouble();
01025 m_VStack[m_v_sp-2].SetType(CExprValue::eBOOL);
01026 }
01027 m_v_sp -= 1;
01028 m_VStack[m_v_sp-1].m_Var = NULL;
01029 break;
01030 case eLT:
01031 if (m_VStack[m_v_sp-1].GetType() == CExprValue::eINT && m_VStack[m_v_sp-2].GetType() == CExprValue::eINT) {
01032 m_VStack[m_v_sp-2].bval =
01033 m_VStack[m_v_sp-2].ival < m_VStack[m_v_sp-1].ival;
01034 m_VStack[m_v_sp-2].SetType(CExprValue::eBOOL);
01035 } else if (m_VStack[m_v_sp-2].GetType() == CExprValue::eBOOL) {
01036 m_VStack[m_v_sp-2].bval =
01037 m_VStack[m_v_sp-2].bval < m_VStack[m_v_sp-1].GetBool();
01038 } else {
01039 m_VStack[m_v_sp-2].bval =
01040 m_VStack[m_v_sp-2].GetDouble() < m_VStack[m_v_sp-1].GetDouble();
01041 m_VStack[m_v_sp-2].SetType(CExprValue::eBOOL);
01042 }
01043 m_v_sp -= 1;
01044 m_VStack[m_v_sp-1].m_Var = NULL;
01045 break;
01046 case eLE:
01047 if (m_VStack[m_v_sp-1].GetType() == CExprValue::eINT && m_VStack[m_v_sp-2].GetType() == CExprValue::eINT) {
01048 m_VStack[m_v_sp-2].bval =
01049 m_VStack[m_v_sp-2].ival <= m_VStack[m_v_sp-1].ival;
01050 m_VStack[m_v_sp-2].SetType(CExprValue::eBOOL);
01051 } else if (m_VStack[m_v_sp-2].GetType() == CExprValue::eBOOL) {
01052 m_VStack[m_v_sp-2].bval =
01053 m_VStack[m_v_sp-2].bval <= m_VStack[m_v_sp-1].GetBool();
01054 } else {
01055 m_VStack[m_v_sp-2].bval =
01056 m_VStack[m_v_sp-2].GetDouble() <= m_VStack[m_v_sp-1].GetDouble();
01057 m_VStack[m_v_sp-2].SetType(CExprValue::eBOOL);
01058 }
01059 m_v_sp -= 1;
01060 m_VStack[m_v_sp-1].m_Var = NULL;
01061 break;
01062 case ePREINC:
01063 if (m_VStack[m_v_sp-1].GetType() == CExprValue::eINT) {
01064 m_VStack[m_v_sp-1].ival += 1;
01065 } else {
01066 m_VStack[m_v_sp-1].fval += 1;
01067 }
01068 if (!Assign()) return;
01069 m_VStack[m_v_sp-1].m_Var = NULL;
01070 break;
01071 case ePREDEC:
01072 if (m_VStack[m_v_sp-1].GetType() == CExprValue::eINT) {
01073 m_VStack[m_v_sp-1].ival -= 1;
01074 } else {
01075 m_VStack[m_v_sp-1].fval -= 1;
01076 }
01077 if (!Assign()) return;
01078 m_VStack[m_v_sp-1].m_Var = NULL;
01079 break;
01080 case ePOSTINC:
01081 if (m_VStack[m_v_sp-1].m_Var == NULL) {
01082 ReportError(m_VStack[m_v_sp-1].m_Pos, "Varaibale expected");
01083 return;
01084 }
01085 if (m_VStack[m_v_sp-1].m_Var->m_Val.GetType() == CExprValue::eINT) {
01086 m_VStack[m_v_sp-1].m_Var->m_Val.ival += 1;
01087 } else {
01088 m_VStack[m_v_sp-1].m_Var->m_Val.fval += 1;
01089 }
01090 m_VStack[m_v_sp-1].m_Var = NULL;
01091 break;
01092 case ePOSTDEC:
01093 if (m_VStack[m_v_sp-1].m_Var == NULL) {
01094 ReportError(m_VStack[m_v_sp-1].m_Pos, "Varaibale expected");
01095 return;
01096 }
01097 if (m_VStack[m_v_sp-1].m_Var->m_Val.GetType() == CExprValue::eINT) {
01098 m_VStack[m_v_sp-1].m_Var->m_Val.ival -= 1;
01099 } else {
01100 m_VStack[m_v_sp-1].m_Var->m_Val.fval -= 1;
01101 }
01102 m_VStack[m_v_sp-1].m_Var = NULL;
01103 break;
01104 case eSET:
01105 if (m_VStack[m_v_sp-2].m_Var == NULL) {
01106 ReportError(m_VStack[m_v_sp-2].m_Pos, "Variabale expected");
01107 return;
01108 } else {
01109 m_VStack[m_v_sp-2]=m_VStack[m_v_sp-2].m_Var->m_Val=m_VStack[m_v_sp-1];
01110 }
01111 m_v_sp -= 1;
01112 m_VStack[m_v_sp-1].m_Var = NULL;
01113 break;
01114 case eNOT:
01115 if (m_VStack[m_v_sp-1].GetType() == CExprValue::eINT) {
01116 m_VStack[m_v_sp-1].ival = !m_VStack[m_v_sp-1].ival;
01117 } else if (m_VStack[m_v_sp-1].GetType() == CExprValue::eBOOL) {
01118 m_VStack[m_v_sp-1].bval = !m_VStack[m_v_sp-1].bval;
01119 } else {
01120 m_VStack[m_v_sp-1].ival = !m_VStack[m_v_sp-1].fval;
01121 m_VStack[m_v_sp-1].SetType(CExprValue::eINT);
01122 }
01123 m_VStack[m_v_sp-1].m_Var = NULL;
01124 break;
01125 case eMINUS:
01126 if (m_VStack[m_v_sp-1].GetType() == CExprValue::eINT) {
01127 m_VStack[m_v_sp-1].ival = -m_VStack[m_v_sp-1].ival;
01128 } else {
01129 m_VStack[m_v_sp-1].fval = -m_VStack[m_v_sp-1].fval;
01130 }
01131
01132 case ePLUS:
01133 m_VStack[m_v_sp-1].m_Var = NULL;
01134 break;
01135 case eCOM:
01136 if (m_VStack[m_v_sp-1].GetType() == CExprValue::eINT) {
01137 m_VStack[m_v_sp-1].ival = ~m_VStack[m_v_sp-1].ival;
01138 } else {
01139 m_VStack[m_v_sp-1].ival = ~(int)m_VStack[m_v_sp-1].fval;
01140 m_VStack[m_v_sp-1].SetType(CExprValue::eINT);
01141 }
01142 m_VStack[m_v_sp-1].m_Var = NULL;
01143 break;
01144 case eRPAR:
01145 ReportError("mismatched ')'");
01146 return;
01147 case eFUNC:
01148 ReportError("'(' expected");
01149 return;
01150 case eLPAR:
01151 if (oper != eRPAR) {
01152 ReportError("')' expected");
01153 return;
01154 }
01155 if (m_OStack[m_o_sp-1] == eFUNC) {
01156 CExprSymbol* sym = m_VStack[m_v_sp-n_args-1].m_Var;
01157
01158 switch(sym->m_Tag) {
01159 case CExprSymbol::eIFUNC1:
01160 if (n_args != 1) {
01161 ReportError(m_VStack[m_v_sp-n_args-1].m_Pos,
01162 "Function should take one argument");
01163 return;
01164 }
01165 m_VStack[m_v_sp-2].ival =
01166 (*sym->m_IntFunc1)(m_VStack[m_v_sp-1].GetInt());
01167 m_VStack[m_v_sp-2].SetType(CExprValue::eINT);
01168 m_v_sp -= 1;
01169 break;
01170 case CExprSymbol::eIFUNC2:
01171 if (n_args != 2) {
01172 ReportError(m_VStack[m_v_sp-n_args-1].m_Pos,
01173 "Function should take two arguments");
01174 return;
01175 }
01176 m_VStack[m_v_sp-3].ival =
01177 (*sym->m_IntFunc2)
01178 (m_VStack[m_v_sp-2].GetInt(), m_VStack[m_v_sp-1].GetInt());
01179 m_VStack[m_v_sp-3].SetType(CExprValue::eINT);
01180 m_v_sp -= 2;
01181 break;
01182 case CExprSymbol::eFFUNC1:
01183 if (n_args != 1) {
01184 ReportError(m_VStack[m_v_sp-n_args-1].m_Pos,
01185 "Function should take one argument");
01186 return;
01187 }
01188 m_VStack[m_v_sp-2].fval =
01189 (*sym->m_FloatFunc1)(m_VStack[m_v_sp-1].GetDouble());
01190 m_VStack[m_v_sp-2].SetType(CExprValue::eFLOAT);
01191 m_v_sp -= 1;
01192 break;
01193 case CExprSymbol::eFFUNC2:
01194 if (n_args != 2) {
01195 ReportError(m_VStack[m_v_sp-n_args-1].m_Pos,
01196 "Function should take two arguments");
01197 return;
01198 }
01199 m_VStack[m_v_sp-3].fval =
01200 (*sym->m_FloatFunc2)
01201 (m_VStack[m_v_sp-2].GetDouble(), m_VStack[m_v_sp-1].GetDouble());
01202 m_VStack[m_v_sp-3].SetType(CExprValue::eFLOAT);
01203 m_v_sp -= 2;
01204 break;
01205 case CExprSymbol::eBFUNC1:
01206 if (n_args != 1) {
01207 ReportError(m_VStack[m_v_sp-n_args-1].m_Pos,
01208 "Function should take one argument");
01209 return;
01210 }
01211 m_VStack[m_v_sp-2].bval =
01212 (*sym->m_BoolFunc1)(m_VStack[m_v_sp-1].GetBool());
01213 m_VStack[m_v_sp-2].SetType(CExprValue::eBOOL);
01214 m_v_sp -= 1;
01215 break;
01216 case CExprSymbol::eBFUNC2:
01217 if (n_args != 2) {
01218 ReportError(m_VStack[m_v_sp-n_args-1].m_Pos,
01219 "Function should take two arguments");
01220 return;
01221 }
01222 m_VStack[m_v_sp-3].bval =
01223 (*sym->m_BoolFunc2)
01224 (m_VStack[m_v_sp-2].GetBool(), m_VStack[m_v_sp-1].GetBool());
01225 m_VStack[m_v_sp-3].SetType(CExprValue::eBOOL);
01226 m_v_sp -= 2;
01227 break;
01228 default:
01229 ReportError("Invalid expression");
01230 }
01231
01232 m_VStack[m_v_sp-1].m_Var = NULL;
01233 m_o_sp -= 1;
01234 n_args = 1;
01235 } else if (n_args != 1) {
01236 ReportError("Function call expected");
01237 return;
01238 }
01239
01240 goto next_token;
01241
01242 default:
01243 ReportError("synctax ReportError");
01244 }
01245 }
01246
01247 if (m_o_sp == max_stack_size) {
01248 ReportError("operator stack overflow");
01249 return;
01250 }
01251
01252 m_OStack[m_o_sp++] = oper;
01253 }
01254 }
01255
01256
01257 END_NCBI_SCOPE
01258
01259