1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_basic.hxx" 26 27 #include <math.h> 28 29 #include <rtl/math.hxx> 30 #include "sbcomp.hxx" 31 #include "expr.hxx" 32 33 ////////////////////////////////////////////////////////////////////////// 34 35 SbiExprNode::SbiExprNode( void ) 36 { 37 pLeft = NULL; 38 pRight = NULL; 39 eNodeType = SbxDUMMY; 40 } 41 42 SbiExprNode::SbiExprNode( SbiParser* p, SbiExprNode* l, SbiToken t, SbiExprNode* r ) 43 { 44 BaseInit( p ); 45 46 pLeft = l; 47 pRight = r; 48 eTok = t; 49 nVal = 0; 50 eType = SbxVARIANT; // Nodes sind immer Variant 51 eNodeType = SbxNODE; 52 bComposite= sal_True; 53 } 54 55 SbiExprNode::SbiExprNode( SbiParser* p, double n, SbxDataType t ) 56 { 57 BaseInit( p ); 58 59 eType = t; 60 eNodeType = SbxNUMVAL; 61 nVal = n; 62 } 63 64 SbiExprNode::SbiExprNode( SbiParser* p, const String& rVal ) 65 { 66 BaseInit( p ); 67 68 eType = SbxSTRING; 69 eNodeType = SbxSTRVAL; 70 aStrVal = rVal; 71 } 72 73 SbiExprNode::SbiExprNode( SbiParser* p, const SbiSymDef& r, SbxDataType t, SbiExprList* l ) 74 { 75 BaseInit( p ); 76 77 eType = ( t == SbxVARIANT ) ? r.GetType() : t; 78 eNodeType = SbxVARVAL; 79 aVar.pDef = (SbiSymDef*) &r; 80 aVar.pPar = l; 81 aVar.pvMorePar = NULL; 82 aVar.pNext= NULL; 83 84 // Funktionsergebnisse sind nie starr 85 bComposite= sal_Bool( aVar.pDef->GetProcDef() != NULL ); 86 } 87 88 // #120061 TypeOf 89 SbiExprNode::SbiExprNode( SbiParser* p, SbiExprNode* l, sal_uInt16 nId ) 90 { 91 BaseInit( p ); 92 93 pLeft = l; 94 eType = SbxBOOL; 95 eNodeType = SbxTYPEOF; 96 nTypeStrId = nId; 97 } 98 99 // new <type> 100 SbiExprNode::SbiExprNode( SbiParser* p, sal_uInt16 nId ) 101 { 102 BaseInit( p ); 103 104 eType = SbxOBJECT; 105 eNodeType = SbxNEW; 106 nTypeStrId = nId; 107 } 108 109 // AB: 17.12.95, Hilfsfunktion fuer Ctor fuer einheitliche Initialisierung 110 void SbiExprNode::BaseInit( SbiParser* p ) 111 { 112 pGen = &p->aGen; 113 eTok = NIL; 114 pLeft = NULL; 115 pRight = NULL; 116 pWithParent = NULL; 117 bComposite = sal_False; 118 bError = sal_False; 119 } 120 121 SbiExprNode::~SbiExprNode() 122 { 123 delete pLeft; 124 delete pRight; 125 if( IsVariable() ) 126 { 127 delete aVar.pPar; 128 delete aVar.pNext; 129 SbiExprListVector* pvMorePar = aVar.pvMorePar; 130 if( pvMorePar ) 131 { 132 SbiExprListVector::iterator it; 133 for( it = pvMorePar->begin() ; it != pvMorePar->end() ; ++it ) 134 delete *it; 135 delete pvMorePar; 136 } 137 } 138 } 139 140 SbiSymDef* SbiExprNode::GetVar() 141 { 142 if( eNodeType == SbxVARVAL ) 143 return aVar.pDef; 144 else 145 return NULL; 146 } 147 148 SbiSymDef* SbiExprNode::GetRealVar() 149 { 150 SbiExprNode* p = GetRealNode(); 151 if( p ) 152 return p->GetVar(); 153 else 154 return NULL; 155 } 156 157 // AB: 18.12.95 158 SbiExprNode* SbiExprNode::GetRealNode() 159 { 160 if( eNodeType == SbxVARVAL ) 161 { 162 SbiExprNode* p = this; 163 while( p->aVar.pNext ) 164 p = p->aVar.pNext; 165 return p; 166 } 167 else 168 return NULL; 169 } 170 171 // Diese Methode setzt den Typ um, falls er in den Integer-Bereich hineinpasst 172 173 sal_Bool SbiExprNode::IsIntConst() 174 { 175 if( eNodeType == SbxNUMVAL ) 176 { 177 if( eType >= SbxINTEGER && eType <= SbxDOUBLE ) 178 { 179 double n; 180 if( nVal >= SbxMININT && nVal <= SbxMAXINT && modf( nVal, &n ) == 0 ) 181 { 182 nVal = (double) (short) nVal; 183 eType = SbxINTEGER; 184 return sal_True; 185 } 186 } 187 } 188 return sal_False; 189 } 190 191 sal_Bool SbiExprNode::IsNumber() 192 { 193 return sal_Bool( eNodeType == SbxNUMVAL ); 194 } 195 196 sal_Bool SbiExprNode::IsString() 197 { 198 return sal_Bool( eNodeType == SbxSTRVAL ); 199 } 200 201 sal_Bool SbiExprNode::IsVariable() 202 { 203 return sal_Bool( eNodeType == SbxVARVAL ); 204 } 205 206 sal_Bool SbiExprNode::IsLvalue() 207 { 208 return IsVariable(); 209 } 210 211 // Ermitteln der Tiefe eines Baumes 212 213 short SbiExprNode::GetDepth() 214 { 215 if( IsOperand() ) return 0; 216 else 217 { 218 short d1 = pLeft->GetDepth(); 219 short d2 = pRight->GetDepth(); 220 return( (d1 < d2 ) ? d2 : d1 ) + 1; 221 } 222 } 223 224 225 // Abgleich eines Baumes: 226 // 1. Constant Folding 227 // 2. Typabgleich 228 // 3. Umwandlung der Operanden in Strings 229 // 4. Hochziehen der Composite- und Error-Bits 230 231 void SbiExprNode::Optimize() 232 { 233 FoldConstants(); 234 CollectBits(); 235 } 236 237 // Hochziehen der Composite- und Fehlerbits 238 239 void SbiExprNode::CollectBits() 240 { 241 if( pLeft ) 242 { 243 pLeft->CollectBits(); 244 bError |= pLeft->bError; 245 bComposite |= pLeft->bComposite; 246 } 247 if( pRight ) 248 { 249 pRight->CollectBits(); 250 bError |= pRight->bError; 251 bComposite |= pRight->bComposite; 252 } 253 } 254 255 // Kann ein Zweig umgeformt werden, wird sal_True zurueckgeliefert. In diesem 256 // Fall ist das Ergebnis im linken Zweig. 257 258 void SbiExprNode::FoldConstants() 259 { 260 if( IsOperand() || eTok == LIKE ) return; 261 if( pLeft ) 262 pLeft->FoldConstants(); 263 if( pRight ) 264 { 265 pRight->FoldConstants(); 266 if( pLeft->IsConstant() && pRight->IsConstant() 267 && pLeft->eNodeType == pRight->eNodeType ) 268 { 269 CollectBits(); 270 if( eTok == CAT ) 271 // CAT verbindet auch zwei Zahlen miteinander! 272 eType = SbxSTRING; 273 if( pLeft->eType == SbxSTRING ) 274 // Kein Type Mismatch! 275 eType = SbxSTRING; 276 if( eType == SbxSTRING ) 277 { 278 String rl( pLeft->GetString() ); 279 String rr( pRight->GetString() ); 280 delete pLeft; pLeft = NULL; 281 delete pRight; pRight = NULL; 282 bComposite = sal_False; 283 if( eTok == PLUS || eTok == CAT ) 284 { 285 eTok = CAT; 286 // Verkettung: 287 aStrVal = rl; 288 aStrVal += rr; 289 eType = SbxSTRING; 290 eNodeType = SbxSTRVAL; 291 } 292 else 293 { 294 eType = SbxDOUBLE; 295 eNodeType = SbxNUMVAL; 296 StringCompare eRes = rr.CompareTo( rl ); 297 switch( eTok ) 298 { 299 case EQ: 300 nVal = ( eRes == COMPARE_EQUAL ) ? SbxTRUE : SbxFALSE; 301 break; 302 case NE: 303 nVal = ( eRes != COMPARE_EQUAL ) ? SbxTRUE : SbxFALSE; 304 break; 305 case LT: 306 nVal = ( eRes == COMPARE_LESS ) ? SbxTRUE : SbxFALSE; 307 break; 308 case GT: 309 nVal = ( eRes == COMPARE_GREATER ) ? SbxTRUE : SbxFALSE; 310 break; 311 case LE: 312 nVal = ( eRes != COMPARE_GREATER ) ? SbxTRUE : SbxFALSE; 313 break; 314 case GE: 315 nVal = ( eRes != COMPARE_LESS ) ? SbxTRUE : SbxFALSE; 316 break; 317 default: 318 pGen->GetParser()->Error( SbERR_CONVERSION ); 319 bError = sal_True; 320 } 321 } 322 } 323 else 324 { 325 double nl = pLeft->nVal; 326 double nr = pRight->nVal; 327 long ll = 0, lr = 0; 328 long llMod = 0, lrMod = 0; 329 if( ( eTok >= AND && eTok <= IMP ) 330 || eTok == IDIV || eTok == MOD ) 331 { 332 // Integer-Operationen 333 sal_Bool err = sal_False; 334 if( nl > SbxMAXLNG ) err = sal_True, nl = SbxMAXLNG; 335 else 336 if( nl < SbxMINLNG ) err = sal_True, nl = SbxMINLNG; 337 if( nr > SbxMAXLNG ) err = sal_True, nr = SbxMAXLNG; 338 else 339 if( nr < SbxMINLNG ) err = sal_True, nr = SbxMINLNG; 340 ll = (long) nl; lr = (long) nr; 341 llMod = (long) (nl < 0 ? nl - 0.5 : nl + 0.5); 342 lrMod = (long) (nr < 0 ? nr - 0.5 : nr + 0.5); 343 if( err ) 344 { 345 pGen->GetParser()->Error( SbERR_MATH_OVERFLOW ); 346 bError = sal_True; 347 } 348 } 349 sal_Bool bBothInt = sal_Bool( pLeft->eType < SbxSINGLE 350 && pRight->eType < SbxSINGLE ); 351 delete pLeft; pLeft = NULL; 352 delete pRight; pRight = NULL; 353 nVal = 0; 354 eType = SbxDOUBLE; 355 eNodeType = SbxNUMVAL; 356 bComposite = sal_False; 357 sal_Bool bCheckType = sal_False; 358 switch( eTok ) 359 { 360 case EXPON: 361 nVal = pow( nl, nr ); break; 362 case MUL: 363 bCheckType = sal_True; 364 nVal = nl * nr; break; 365 case DIV: 366 if( !nr ) 367 { 368 pGen->GetParser()->Error( SbERR_ZERODIV ); nVal = HUGE_VAL; 369 bError = sal_True; 370 } else nVal = nl / nr; 371 break; 372 case PLUS: 373 bCheckType = sal_True; 374 nVal = nl + nr; break; 375 case MINUS: 376 bCheckType = sal_True; 377 nVal = nl - nr; break; 378 case EQ: 379 nVal = ( nl == nr ) ? SbxTRUE : SbxFALSE; 380 eType = SbxINTEGER; break; 381 case NE: 382 nVal = ( nl != nr ) ? SbxTRUE : SbxFALSE; 383 eType = SbxINTEGER; break; 384 case LT: 385 nVal = ( nl < nr ) ? SbxTRUE : SbxFALSE; 386 eType = SbxINTEGER; break; 387 case GT: 388 nVal = ( nl > nr ) ? SbxTRUE : SbxFALSE; 389 eType = SbxINTEGER; break; 390 case LE: 391 nVal = ( nl <= nr ) ? SbxTRUE : SbxFALSE; 392 eType = SbxINTEGER; break; 393 case GE: 394 nVal = ( nl >= nr ) ? SbxTRUE : SbxFALSE; 395 eType = SbxINTEGER; break; 396 case IDIV: 397 if( !lr ) 398 { 399 pGen->GetParser()->Error( SbERR_ZERODIV ); nVal = HUGE_VAL; 400 bError = sal_True; 401 } else nVal = ll / lr; 402 eType = SbxLONG; break; 403 case MOD: 404 if( !lr ) 405 { 406 pGen->GetParser()->Error( SbERR_ZERODIV ); nVal = HUGE_VAL; 407 bError = sal_True; 408 } else nVal = llMod % lrMod; 409 eType = SbxLONG; break; 410 case AND: 411 nVal = (double) ( ll & lr ); eType = SbxLONG; break; 412 case OR: 413 nVal = (double) ( ll | lr ); eType = SbxLONG; break; 414 case XOR: 415 nVal = (double) ( ll ^ lr ); eType = SbxLONG; break; 416 case EQV: 417 nVal = (double) ( ~ll ^ lr ); eType = SbxLONG; break; 418 case IMP: 419 nVal = (double) ( ~ll | lr ); eType = SbxLONG; break; 420 default: break; 421 } 422 423 if( !::rtl::math::isFinite( nVal ) ) 424 pGen->GetParser()->Error( SbERR_MATH_OVERFLOW ); 425 426 // Den Datentyp wiederherstellen, um Rundungsfehler 427 // zu killen 428 if( bCheckType && bBothInt 429 && nVal >= SbxMINLNG && nVal <= SbxMAXLNG ) 430 { 431 // NK-Stellen weg 432 long n = (long) nVal; 433 nVal = n; 434 eType = ( n >= SbxMININT && n <= SbxMAXINT ) 435 ? SbxINTEGER : SbxLONG; 436 } 437 } 438 } 439 } 440 else if( pLeft && pLeft->IsNumber() ) 441 { 442 nVal = pLeft->nVal; 443 delete pLeft; 444 pLeft = NULL; 445 eType = SbxDOUBLE; 446 eNodeType = SbxNUMVAL; 447 bComposite = sal_False; 448 switch( eTok ) 449 { 450 case NEG: 451 nVal = -nVal; break; 452 case NOT: { 453 // Integer-Operation! 454 sal_Bool err = sal_False; 455 if( nVal > SbxMAXLNG ) err = sal_True, nVal = SbxMAXLNG; 456 else 457 if( nVal < SbxMINLNG ) err = sal_True, nVal = SbxMINLNG; 458 if( err ) 459 { 460 pGen->GetParser()->Error( SbERR_MATH_OVERFLOW ); 461 bError = sal_True; 462 } 463 nVal = (double) ~((long) nVal); 464 eType = SbxLONG; 465 } break; 466 default: break; 467 } 468 } 469 if( eNodeType == SbxNUMVAL ) 470 { 471 // Evtl auf INTEGER falten (wg. besserem Opcode)? 472 if( eType == SbxSINGLE || eType == SbxDOUBLE ) 473 { 474 double x; 475 if( nVal >= SbxMINLNG && nVal <= SbxMAXLNG 476 && !modf( nVal, &x ) ) 477 eType = SbxLONG; 478 } 479 if( eType == SbxLONG && nVal >= SbxMININT && nVal <= SbxMAXINT ) 480 eType = SbxINTEGER; 481 } 482 } 483 484 485