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