LCOV - code coverage report
Current view: top level - basic/source/comp - exprnode.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 152 265 57.4 %
Date: 2015-06-13 12:38:46 Functions: 17 21 81.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : 
      21             : #include <math.h>
      22             : 
      23             : #include <rtl/math.hxx>
      24             : #include "codegen.hxx"
      25             : #include "parser.hxx"
      26             : #include "expr.hxx"
      27             : 
      28             : 
      29           0 : SbiExprNode::SbiExprNode()
      30             : {
      31           0 :     pLeft = NULL;
      32           0 :     pRight = NULL;
      33           0 :     pWithParent = NULL;
      34           0 :     pGen = NULL;
      35           0 :     eNodeType = SbxDUMMY;
      36           0 :     eType = SbxVARIANT;
      37           0 :     eTok = NIL;
      38           0 :     bError = false;
      39           0 : }
      40             : 
      41        2951 : SbiExprNode::SbiExprNode( SbiParser* p, SbiExprNode* l, SbiToken t, SbiExprNode* r )
      42             : {
      43        2951 :     BaseInit( p );
      44             : 
      45        2951 :     pLeft     = l;
      46        2951 :     pRight    = r;
      47        2951 :     eTok      = t;
      48        2951 :     nVal      = 0;
      49        2951 :     eType     = SbxVARIANT;     // Nodes are always Variant
      50        2951 :     eNodeType = SbxNODE;
      51        2951 : }
      52             : 
      53        1938 : SbiExprNode::SbiExprNode( SbiParser* p, double n, SbxDataType t )
      54             : {
      55        1938 :     BaseInit( p );
      56             : 
      57        1938 :     eType     = t;
      58        1938 :     eNodeType = SbxNUMVAL;
      59        1938 :     nVal      = n;
      60        1938 : }
      61             : 
      62        3576 : SbiExprNode::SbiExprNode( SbiParser* p, const OUString& rVal )
      63             : {
      64        3576 :     BaseInit( p );
      65             : 
      66        3576 :     eType     = SbxSTRING;
      67        3576 :     eNodeType = SbxSTRVAL;
      68        3576 :     aStrVal   = rVal;
      69        3576 : }
      70             : 
      71       12754 : SbiExprNode::SbiExprNode( SbiParser* p, const SbiSymDef& r, SbxDataType t, SbiExprList* l )
      72             : {
      73       12754 :     BaseInit( p );
      74             : 
      75       12754 :     eType     = ( t == SbxVARIANT ) ? r.GetType() : t;
      76       12754 :     eNodeType = SbxVARVAL;
      77       12754 :     aVar.pDef = const_cast<SbiSymDef*>(&r);
      78       12754 :     aVar.pPar = l;
      79       12754 :     aVar.pvMorePar = NULL;
      80       12754 :     aVar.pNext= NULL;
      81       12754 : }
      82             : 
      83             : // #120061 TypeOf
      84           0 : SbiExprNode::SbiExprNode( SbiParser* p, SbiExprNode* l, sal_uInt16 nId )
      85             : {
      86           0 :     BaseInit( p );
      87             : 
      88           0 :     pLeft      = l;
      89           0 :     eType      = SbxBOOL;
      90           0 :     eNodeType  = SbxTYPEOF;
      91           0 :     nTypeStrId = nId;
      92           0 : }
      93             : 
      94             : // new <type>
      95           0 : SbiExprNode::SbiExprNode( SbiParser* p, sal_uInt16 nId )
      96             : {
      97           0 :     BaseInit( p );
      98             : 
      99           0 :     eType     = SbxOBJECT;
     100           0 :     eNodeType = SbxNEW;
     101           0 :     nTypeStrId = nId;
     102           0 : }
     103             : 
     104             : // From 1995-12-17, auxiliary function for Ctor for the uniform initialisation
     105       21219 : void SbiExprNode::BaseInit( SbiParser* p )
     106             : {
     107       21219 :     pGen = &p->aGen;
     108       21219 :     eTok = NIL;
     109       21219 :     pLeft       = NULL;
     110       21219 :     pRight      = NULL;
     111       21219 :     pWithParent = NULL;
     112       21219 :     bError      = false;
     113       21219 : }
     114             : 
     115       63657 : SbiExprNode::~SbiExprNode()
     116             : {
     117       21219 :     delete pLeft;
     118       21219 :     delete pRight;
     119       21219 :     if( IsVariable() )
     120             :     {
     121       12754 :         delete aVar.pPar;
     122       12754 :         delete aVar.pNext;
     123       12754 :         SbiExprListVector* pvMorePar = aVar.pvMorePar;
     124       12754 :         if( pvMorePar )
     125             :         {
     126           0 :             SbiExprListVector::iterator it;
     127           0 :             for( it = pvMorePar->begin() ; it != pvMorePar->end() ; ++it )
     128           0 :                 delete *it;
     129           0 :             delete pvMorePar;
     130             :         }
     131             :     }
     132       42438 : }
     133             : 
     134        3668 : SbiSymDef* SbiExprNode::GetVar()
     135             : {
     136        3668 :     if( eNodeType == SbxVARVAL )
     137        3668 :         return aVar.pDef;
     138             :     else
     139           0 :         return NULL;
     140             : }
     141             : 
     142        3652 : SbiSymDef* SbiExprNode::GetRealVar()
     143             : {
     144        3652 :     SbiExprNode* p = GetRealNode();
     145        3652 :     if( p )
     146        3652 :         return p->GetVar();
     147             :     else
     148           0 :         return NULL;
     149             : }
     150             : 
     151             : // From 1995-12-18
     152        3668 : SbiExprNode* SbiExprNode::GetRealNode()
     153             : {
     154        3668 :     if( eNodeType == SbxVARVAL )
     155             :     {
     156        3668 :         SbiExprNode* p = this;
     157        8503 :         while( p->aVar.pNext )
     158        1167 :             p = p->aVar.pNext;
     159        3668 :         return p;
     160             :     }
     161             :     else
     162           0 :         return NULL;
     163             : }
     164             : 
     165             : // This method transform the type, if it fits into the Integer range
     166             : 
     167          28 : bool SbiExprNode::IsIntConst()
     168             : {
     169          28 :     if( eNodeType == SbxNUMVAL )
     170             :     {
     171          27 :         if( eType >= SbxINTEGER && eType <= SbxDOUBLE )
     172             :         {
     173             :             double n;
     174          27 :             if( nVal >= SbxMININT && nVal <= SbxMAXINT && modf( nVal, &n ) == 0 )
     175             :             {
     176          27 :                 nVal = (double) (short) nVal;
     177          27 :                 eType = SbxINTEGER;
     178          27 :                 return true;
     179             :             }
     180             :         }
     181             :     }
     182           1 :     return false;
     183             : }
     184             : 
     185         322 : bool SbiExprNode::IsNumber()
     186             : {
     187         322 :     return eNodeType == SbxNUMVAL;
     188             : }
     189             : 
     190       23874 : bool SbiExprNode::IsVariable()
     191             : {
     192       23874 :     return eNodeType == SbxVARVAL;
     193             : }
     194             : 
     195        2559 : bool SbiExprNode::IsLvalue()
     196             : {
     197        2559 :     return IsVariable();
     198             : }
     199             : 
     200             : // Identify of the depth of a tree
     201             : 
     202           0 : short SbiExprNode::GetDepth()
     203             : {
     204           0 :     if( IsOperand() ) return 0;
     205             :     else
     206             :     {
     207           0 :         short d1 = pLeft->GetDepth();
     208           0 :         short d2 = pRight->GetDepth();
     209           0 :         return( (d1 < d2 ) ? d2 : d1 ) + 1;
     210             :     }
     211             : }
     212             : 
     213             : 
     214             : // Adjustment of a tree:
     215             : // 1. Constant Folding
     216             : // 2. Type-Adjustment
     217             : // 3. Conversion of the operans into Strings
     218             : // 4. Lifting of the composite- and error-bits
     219             : 
     220        8693 : void SbiExprNode::Optimize()
     221             : {
     222        8693 :     FoldConstants();
     223        8693 :     CollectBits();
     224        8693 : }
     225             : 
     226             : // Lifting of the error-bits
     227             : 
     228       14352 : void SbiExprNode::CollectBits()
     229             : {
     230       14352 :     if( pLeft )
     231             :     {
     232        2876 :         pLeft->CollectBits();
     233        2876 :         bError = bError || pLeft->bError;
     234             :     }
     235       14352 :     if( pRight )
     236             :     {
     237        2751 :         pRight->CollectBits();
     238        2751 :         bError = bError || pRight->bError;
     239             :     }
     240       14352 : }
     241             : 
     242             : // If a twig can be converted, True will be returned. In this case
     243             : // the result is in the left twig.
     244       14395 : void SbiExprNode::FoldConstants()
     245             : {
     246       28790 :     if( IsOperand() || eTok == LIKE ) return;
     247        2951 :     if( pLeft )
     248        2951 :         pLeft->FoldConstants();
     249        2951 :     if (pLeft && pRight)
     250             :     {
     251        2751 :         pRight->FoldConstants();
     252        5926 :         if( pLeft->IsConstant() && pRight->IsConstant()
     253        2783 :             && pLeft->eNodeType == pRight->eNodeType )
     254             :         {
     255          32 :             CollectBits();
     256          32 :             if( eTok == CAT )
     257             :                 // CAT affiliate also two numbers!
     258           0 :                 eType = SbxSTRING;
     259          32 :             if( pLeft->eType == SbxSTRING )
     260             :                 // No Type Mismatch!
     261          30 :                 eType = SbxSTRING;
     262          32 :             if( eType == SbxSTRING )
     263             :             {
     264          30 :                 OUString rl( pLeft->GetString() );
     265          60 :                 OUString rr( pRight->GetString() );
     266          30 :                 delete pLeft; pLeft = NULL;
     267          30 :                 delete pRight; pRight = NULL;
     268          30 :                 if( eTok == PLUS || eTok == CAT )
     269             :                 {
     270          30 :                     eTok = CAT;
     271             :                     // Linking:
     272          30 :                     aStrVal = rl;
     273          30 :                     aStrVal += rr;
     274          30 :                     eType = SbxSTRING;
     275          30 :                     eNodeType = SbxSTRVAL;
     276             :                 }
     277             :                 else
     278             :                 {
     279           0 :                     eType = SbxDOUBLE;
     280           0 :                     eNodeType = SbxNUMVAL;
     281           0 :                     int eRes = rr.compareTo( rl );
     282           0 :                     switch( eTok )
     283             :                     {
     284             :                     case EQ:
     285           0 :                         nVal = ( eRes == 0 ) ? SbxTRUE : SbxFALSE;
     286           0 :                         break;
     287             :                     case NE:
     288           0 :                         nVal = ( eRes != 0 ) ? SbxTRUE : SbxFALSE;
     289           0 :                         break;
     290             :                     case LT:
     291           0 :                         nVal = ( eRes < 0 ) ? SbxTRUE : SbxFALSE;
     292           0 :                         break;
     293             :                     case GT:
     294           0 :                         nVal = ( eRes > 0 ) ? SbxTRUE : SbxFALSE;
     295           0 :                         break;
     296             :                     case LE:
     297           0 :                         nVal = ( eRes <= 0 ) ? SbxTRUE : SbxFALSE;
     298           0 :                         break;
     299             :                     case GE:
     300           0 :                         nVal = ( eRes >= 0 ) ? SbxTRUE : SbxFALSE;
     301           0 :                         break;
     302             :                     default:
     303           0 :                         pGen->GetParser()->Error( SbERR_CONVERSION );
     304           0 :                         bError = true;
     305           0 :                         break;
     306             :                     }
     307          30 :                 }
     308             :             }
     309             :             else
     310             :             {
     311           2 :                 double nl = pLeft->nVal;
     312           2 :                 double nr = pRight->nVal;
     313           2 :                 long ll = 0, lr = 0;
     314           2 :                 long llMod = 0, lrMod = 0;
     315           2 :                 if( ( eTok >= AND && eTok <= IMP )
     316           2 :                    || eTok == IDIV || eTok == MOD )
     317             :                 {
     318             :                     // Integer operations
     319           0 :                     bool err = false;
     320           0 :                     if( nl > SbxMAXLNG ) err = true, nl = SbxMAXLNG;
     321           0 :                     else if( nl < SbxMINLNG ) err = true, nl = SbxMINLNG;
     322           0 :                     if( nr > SbxMAXLNG ) err = true, nr = SbxMAXLNG;
     323           0 :                     else if( nr < SbxMINLNG ) err = true, nr = SbxMINLNG;
     324           0 :                     ll = static_cast<long>(nl); lr = static_cast<long>(nr);
     325           0 :                     llMod = static_cast<long>(nl);
     326           0 :                     lrMod = static_cast<long>(nr);
     327           0 :                     if( err )
     328             :                     {
     329           0 :                         pGen->GetParser()->Error( SbERR_MATH_OVERFLOW );
     330           0 :                         bError = true;
     331             :                     }
     332             :                 }
     333           2 :                 bool bBothInt = ( pLeft->eType < SbxSINGLE
     334           2 :                                    && pRight->eType < SbxSINGLE );
     335           2 :                 delete pLeft; pLeft = NULL;
     336           2 :                 delete pRight; pRight = NULL;
     337           2 :                 nVal = 0;
     338           2 :                 eType = SbxDOUBLE;
     339           2 :                 eNodeType = SbxNUMVAL;
     340           2 :                 bool bCheckType = false;
     341           2 :                 switch( eTok )
     342             :                 {
     343             :                     case EXPON:
     344           0 :                         nVal = pow( nl, nr ); break;
     345             :                     case MUL:
     346           0 :                         bCheckType = true;
     347           0 :                         nVal = nl * nr; break;
     348             :                     case DIV:
     349           0 :                         if( !nr )
     350             :                         {
     351           0 :                             pGen->GetParser()->Error( SbERR_ZERODIV ); nVal = HUGE_VAL;
     352           0 :                             bError = true;
     353           0 :                         } else nVal = nl / nr;
     354           0 :                         break;
     355             :                     case PLUS:
     356           0 :                         bCheckType = true;
     357           0 :                         nVal = nl + nr; break;
     358             :                     case MINUS:
     359           1 :                         bCheckType = true;
     360           1 :                         nVal = nl - nr; break;
     361             :                     case EQ:
     362           1 :                         nVal = ( nl == nr ) ? SbxTRUE : SbxFALSE;
     363           1 :                         eType = SbxINTEGER; break;
     364             :                     case NE:
     365           0 :                         nVal = ( nl != nr ) ? SbxTRUE : SbxFALSE;
     366           0 :                         eType = SbxINTEGER; break;
     367             :                     case LT:
     368           0 :                         nVal = ( nl <  nr ) ? SbxTRUE : SbxFALSE;
     369           0 :                         eType = SbxINTEGER; break;
     370             :                     case GT:
     371           0 :                         nVal = ( nl >  nr ) ? SbxTRUE : SbxFALSE;
     372           0 :                         eType = SbxINTEGER; break;
     373             :                     case LE:
     374           0 :                         nVal = ( nl <= nr ) ? SbxTRUE : SbxFALSE;
     375           0 :                         eType = SbxINTEGER; break;
     376             :                     case GE:
     377           0 :                         nVal = ( nl >= nr ) ? SbxTRUE : SbxFALSE;
     378           0 :                         eType = SbxINTEGER; break;
     379             :                     case IDIV:
     380           0 :                         if( !lr )
     381             :                         {
     382           0 :                             pGen->GetParser()->Error( SbERR_ZERODIV ); nVal = HUGE_VAL;
     383           0 :                             bError = true;
     384           0 :                         } else nVal = ll / lr;
     385           0 :                         eType = SbxLONG; break;
     386             :                     case MOD:
     387           0 :                         if( !lr )
     388             :                         {
     389           0 :                             pGen->GetParser()->Error( SbERR_ZERODIV ); nVal = HUGE_VAL;
     390           0 :                             bError = true;
     391           0 :                         } else nVal = llMod - lrMod * (llMod/lrMod);
     392           0 :                         eType = SbxLONG; break;
     393             :                     case AND:
     394           0 :                         nVal = (double) ( ll & lr ); eType = SbxLONG; break;
     395             :                     case OR:
     396           0 :                         nVal = (double) ( ll | lr ); eType = SbxLONG; break;
     397             :                     case XOR:
     398           0 :                         nVal = (double) ( ll ^ lr ); eType = SbxLONG; break;
     399             :                     case EQV:
     400           0 :                         nVal = (double) ( ~ll ^ lr ); eType = SbxLONG; break;
     401             :                     case IMP:
     402           0 :                         nVal = (double) ( ~ll | lr ); eType = SbxLONG; break;
     403           0 :                     default: break;
     404             :                 }
     405             : 
     406           2 :                 if( !::rtl::math::isFinite( nVal ) )
     407           0 :                     pGen->GetParser()->Error( SbERR_MATH_OVERFLOW );
     408             : 
     409             :                 // Recover the data type to kill rounding error
     410           2 :                 if( bCheckType && bBothInt
     411           1 :                  && nVal >= SbxMINLNG && nVal <= SbxMAXLNG )
     412             :                 {
     413             :                     // Decimal place away
     414           1 :                     long n = (long) nVal;
     415           1 :                     nVal = n;
     416           1 :                     eType = ( n >= SbxMININT && n <= SbxMAXINT )
     417           2 :                           ? SbxINTEGER : SbxLONG;
     418             :                 }
     419             :             }
     420        2751 :         }
     421             :     }
     422         200 :     else if (pLeft && pLeft->IsNumber())
     423             :     {
     424          75 :         nVal = pLeft->nVal;
     425          75 :         delete pLeft;
     426          75 :         pLeft = NULL;
     427          75 :         eType = SbxDOUBLE;
     428          75 :         eNodeType = SbxNUMVAL;
     429          75 :         switch( eTok )
     430             :         {
     431             :             case NEG:
     432          75 :                 nVal = -nVal; break;
     433             :             case NOT: {
     434             :                 // Integer operation!
     435           0 :                 bool err = false;
     436           0 :                 if( nVal > SbxMAXLNG ) err = true, nVal = SbxMAXLNG;
     437           0 :                 else if( nVal < SbxMINLNG ) err = true, nVal = SbxMINLNG;
     438           0 :                 if( err )
     439             :                 {
     440           0 :                     pGen->GetParser()->Error( SbERR_MATH_OVERFLOW );
     441           0 :                     bError = true;
     442             :                 }
     443           0 :                 nVal = (double) ~((long) nVal);
     444           0 :                 eType = SbxLONG;
     445           0 :                 } break;
     446           0 :             default: break;
     447             :         }
     448             :     }
     449        2951 :     if( eNodeType == SbxNUMVAL )
     450             :     {
     451             :         // Potentially convolve in INTEGER (because of better opcode)?
     452          77 :         if( eType == SbxSINGLE || eType == SbxDOUBLE )
     453             :         {
     454             :             double x;
     455         225 :             if( nVal >= SbxMINLNG && nVal <= SbxMAXLNG
     456         150 :             && !modf( nVal, &x ) )
     457          69 :                 eType = SbxLONG;
     458             :         }
     459          77 :         if( eType == SbxLONG && nVal >= SbxMININT && nVal <= SbxMAXINT )
     460          68 :             eType = SbxINTEGER;
     461             :     }
     462             : }
     463             : 
     464             : 
     465             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11