src/corelib/expr.cpp

Go to the documentation of this file.
00001 /*  $Id: expr.cpp 146530 2008-11-26 17:24:27Z ssikorsk $
00002  * ===========================================================================
00003  *
00004  *                            PUBLIC DOMAIN NOTICE
00005  *               National Center for Biotechnology Information
00006  *
00007  *  This software/database is a "United States Government Work" under the
00008  *  terms of the United States Copyright Act.  It was written as part of
00009  *  the author's official duties as a United States Government employee and
00010  *  thus cannot be copyrighted.  This software/database is freely available
00011  *  to the public for use. The National Library of Medicine and the U.S.
00012  *  Government have not placed any restriction on its use or reproduction.
00013  *
00014  *  Although all reasonable efforts have been taken to ensure the accuracy
00015  *  and reliability of the software and data, the NLM and the U.S.
00016  *  Government do not and cannot warrant the performance or results that
00017  *  may be obtained by using this software or data. The NLM and the U.S.
00018  *  Government disclaim all warranties, express or implied, including
00019  *  warranties of performance, merchantability or fitness for any particular
00020  *  purpose.
00021  *
00022  *  Please cite the author in any work or product based on this material.
00023  *
00024  * ===========================================================================
00025  *
00026  * Author: Sergey Sikorskiy
00027  *
00028  * File Description: 
00029  *      Expression parsing and evaluation.
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 static
00311 char* 
00312 to_bin(int nval, char* pbuf, int nbufsize)
00313 {
00314     int ncnt;
00315     int bcnt;
00316     int nlen = sizeof(int) * 8 + sizeof(int);
00317 
00318     if (pbuf != NULL && nbufsize > nlen)
00319     {
00320         pbuf[nlen] = '\0';
00321         pbuf[nlen - 1] = 'b';
00322         for(ncnt = 0, bcnt = nlen - 2; ncnt < nlen; ncnt ++, bcnt --)
00323         {
00324             if (ncnt > 0 && (ncnt % 8) == 0)
00325             {
00326                 pbuf[bcnt] = '.';
00327                 bcnt --;
00328             }
00329             pbuf[bcnt] = (nval & (1 << ncnt))? '1' : '0';
00330         }
00331     }
00332 
00333     return pbuf;
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,       // eBEGIN, eOPERAND, eERROR, eEND, 
00422     4, 4,             // eLPAR, eRPAR 
00423     5, 98, 98,        // eFUNC, ePOSTINC, ePOSTDEC,
00424     98, 98, 98, 98, 98, 98, // ePREINC, ePREDEC, ePLUS, eMINUS, eNOT, eCOM,
00425     90,               // ePOW,
00426     80, 80, 80,       // eMUL, eDIV, eMOD,
00427     70, 70,           // eADD, eSUB, 
00428     60, 60, 60,       // eASL, eASR, eLSR, 
00429     50, 50, 50, 50,   // eGT, eGE, eLT, eLE,     
00430     40, 40,           // eEQ, eNE, 
00431     38,               // eAND,
00432     36,               // eXOR,
00433     34,               // eOR,
00434     20, 20, 20, 20, 20, 20, 20, //eSET, eSETADD, eSETSUB, eSETMUL, eSETDIV, eSETMOD, 
00435     20, 20, 20, 20, 20, 20, // eSETASL, eSETASR, eSETLSR, eSETAND, eSETXOR, eSETOR,
00436     10               // eCOMMA
00437 };
00438 
00439 int CExprParser::sm_rpr[eTERMINALS] = {
00440     0, 0, 0, 1,       // eBEGIN, eOPERAND, eERROR, eEND, 
00441     110, 3,           // eLPAR, eRPAR 
00442     120, 99, 99,      // eFUNC, ePOSTINC, ePOSTDEC
00443     99, 99, 99, 99, 99, 99, // ePREINC, ePREDEC, ePLUS, eMINUS, eNOT, eCOM,
00444     95,               // ePOW,
00445     80, 80, 80,       // eMUL, eDIV, eMOD,
00446     70, 70,           // eADD, eSUB, 
00447     60, 60, 60,       // eASL, eASR, eLSR, 
00448     50, 50, 50, 50,   // eGT, eGE, eLT, eLE,     
00449     40, 40,           // eEQ, eNE, 
00450     38,               // eAND,
00451     36,               // eXOR,
00452     34,               // eOR,
00453     25, 25, 25, 25, 25, 25, 25, //eSET, eSETADD, eSETSUB, eSETMUL, eSETDIV, eSETMOD, 
00454     25, 25, 25, 25, 25, 25, // eSETASL, eSETASR, eSETLSR, eSETAND, eSETXOR, eSETOR,
00455     15               // eCOMMA
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         // Check for true/false ...
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     // char var_name[16];
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                     sprintf(var_name, "$%d", ++m_TmpVarCount);
00738                     printf("%s = ", var_name);
00739                     CExprSymbol::add(CExprSymbol::eVARIABLE, var_name)->m_Val = m_VStack[0];
00740                     if (m_VStack[0].GetType() == CExprValue::eINT) { 
00741                         printf("%" INT_FORMAT "d [%#" INT_FORMAT "x %#" INT_FORMAT "o]\n", 
00742                                m_VStack[0].ival,  m_VStack[0].ival, m_VStack[0].ival);
00743                     } else { 
00744                         printf("%.10g\n", m_VStack[0].fval);
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                 // no break
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 

Generated on Wed Dec 9 04:14:17 2009 for NCBI C++ ToolKit by  doxygen 1.4.6
Modified on Wed Dec 09 08:17:56 2009 by modify_doxy.py rev. 173732