[Libreoffice-commits] core.git: basic/source

Arnaud Versini arnaud.versini at gmail.com
Tue Dec 22 03:13:40 PST 2015


 basic/source/comp/exprnode.cxx |  342 +++++++++++++++++++++--------------------
 basic/source/inc/expr.hxx      |    6 
 2 files changed, 189 insertions(+), 159 deletions(-)

New commits:
commit 4251e676bb818cde1989b9077b1497f1d9b0cbdc
Author: Arnaud Versini <arnaud.versini at gmail.com>
Date:   Sun Jul 12 13:52:53 2015 +0200

    BASIC : Refactor FoldConstants for extracting it from SwExprNode.
    
    Change-Id: Ia47597b26d63db216dd3ab71acbb18449ece7b1a
    Reviewed-on: https://gerrit.libreoffice.org/16963
    Reviewed-by: Arnaud Versini <arnaud.versini at libreoffice.org>
    Tested-by: Arnaud Versini <arnaud.versini at libreoffice.org>

diff --git a/basic/source/comp/exprnode.cxx b/basic/source/comp/exprnode.cxx
index 52c2211..9d77f6d 100644
--- a/basic/source/comp/exprnode.cxx
+++ b/basic/source/comp/exprnode.cxx
@@ -231,182 +231,206 @@ void SbiExprNode::CollectBits()
 void SbiExprNode::FoldConstants(SbiParser* pParser)
 {
     if( IsOperand() || eTok == LIKE ) return;
-    if( pLeft )
-        pLeft->FoldConstants(pParser);
-    if (pLeft && pRight)
+
+    if (IsUnary())
+        FoldConstantsUnaryNode(pParser);
+    else if (IsBinary())
+        FoldConstantsBinaryNode(pParser);
+
+    if( eNodeType == SbxNUMVAL )
     {
-        pRight->FoldConstants(pParser);
-        if( pLeft->IsConstant() && pRight->IsConstant()
-            && pLeft->eNodeType == pRight->eNodeType )
+        // Potentially convolve in INTEGER (because of better opcode)?
+        if( eType == SbxSINGLE || eType == SbxDOUBLE )
         {
-            CollectBits();
-            if( eTok == CAT )
-                // CAT affiliate also two numbers!
-                eType = SbxSTRING;
-            if( pLeft->eType == SbxSTRING )
-                // No Type Mismatch!
+            double x;
+            if( nVal >= SbxMINLNG && nVal <= SbxMAXLNG
+            && !modf( nVal, &x ) )
+                eType = SbxLONG;
+        }
+        if( eType == SbxLONG && nVal >= SbxMININT && nVal <= SbxMAXINT )
+            eType = SbxINTEGER;
+    }
+}
+
+void SbiExprNode::FoldConstantsBinaryNode(SbiParser* pParser)
+{
+    pLeft->FoldConstants(pParser);
+    pRight->FoldConstants(pParser);
+    if( pLeft->IsConstant() && pRight->IsConstant()
+        && pLeft->eNodeType == pRight->eNodeType )
+    {
+        CollectBits();
+        if( eTok == CAT )
+            // CAT affiliate also two numbers!
+            eType = SbxSTRING;
+        if( pLeft->eType == SbxSTRING )
+            // No Type Mismatch!
+            eType = SbxSTRING;
+        if( eType == SbxSTRING )
+        {
+            OUString rl( pLeft->GetString() );
+            OUString rr( pRight->GetString() );
+            pLeft.reset();
+            pRight.reset();
+            if( eTok == PLUS || eTok == CAT )
+            {
+                eTok = CAT;
+                // Linking:
+                aStrVal = rl;
+                aStrVal += rr;
                 eType = SbxSTRING;
-            if( eType == SbxSTRING )
+                eNodeType = SbxSTRVAL;
+            }
+            else
             {
-                OUString rl( pLeft->GetString() );
-                OUString rr( pRight->GetString() );
-                pLeft.reset();
-                pRight.reset();
-                if( eTok == PLUS || eTok == CAT )
+                eType = SbxDOUBLE;
+                eNodeType = SbxNUMVAL;
+                int eRes = rr.compareTo( rl );
+                switch( eTok )
                 {
-                    eTok = CAT;
-                    // Linking:
-                    aStrVal = rl;
-                    aStrVal += rr;
-                    eType = SbxSTRING;
-                    eNodeType = SbxSTRVAL;
+                case EQ:
+                    nVal = ( eRes == 0 ) ? SbxTRUE : SbxFALSE;
+                    break;
+                case NE:
+                    nVal = ( eRes != 0 ) ? SbxTRUE : SbxFALSE;
+                    break;
+                case LT:
+                    nVal = ( eRes < 0 ) ? SbxTRUE : SbxFALSE;
+                    break;
+                case GT:
+                    nVal = ( eRes > 0 ) ? SbxTRUE : SbxFALSE;
+                    break;
+                case LE:
+                    nVal = ( eRes <= 0 ) ? SbxTRUE : SbxFALSE;
+                    break;
+                case GE:
+                    nVal = ( eRes >= 0 ) ? SbxTRUE : SbxFALSE;
+                    break;
+                default:
+                    pParser->Error( ERRCODE_BASIC_CONVERSION );
+                    bError = true;
+                    break;
                 }
-                else
+            }
+        }
+        else
+        {
+            double nl = pLeft->nVal;
+            double nr = pRight->nVal;
+            long ll = 0, lr = 0;
+            long llMod = 0, lrMod = 0;
+            if( ( eTok >= AND && eTok <= IMP )
+               || eTok == IDIV || eTok == MOD )
+            {
+                // Integer operations
+                bool bErr = false;
+                if( nl > SbxMAXLNG ) bErr = true, nl = SbxMAXLNG;
+                else if( nl < SbxMINLNG ) bErr = true, nl = SbxMINLNG;
+                if( nr > SbxMAXLNG ) bErr = true, nr = SbxMAXLNG;
+                else if( nr < SbxMINLNG ) bErr = true, nr = SbxMINLNG;
+                ll = static_cast<long>(nl); lr = static_cast<long>(nr);
+                llMod = static_cast<long>(nl);
+                lrMod = static_cast<long>(nr);
+                if( bErr )
                 {
-                    eType = SbxDOUBLE;
-                    eNodeType = SbxNUMVAL;
-                    int eRes = rr.compareTo( rl );
-                    switch( eTok )
-                    {
-                    case EQ:
-                        nVal = ( eRes == 0 ) ? SbxTRUE : SbxFALSE;
-                        break;
-                    case NE:
-                        nVal = ( eRes != 0 ) ? SbxTRUE : SbxFALSE;
-                        break;
-                    case LT:
-                        nVal = ( eRes < 0 ) ? SbxTRUE : SbxFALSE;
-                        break;
-                    case GT:
-                        nVal = ( eRes > 0 ) ? SbxTRUE : SbxFALSE;
-                        break;
-                    case LE:
-                        nVal = ( eRes <= 0 ) ? SbxTRUE : SbxFALSE;
-                        break;
-                    case GE:
-                        nVal = ( eRes >= 0 ) ? SbxTRUE : SbxFALSE;
-                        break;
-                    default:
-                        pParser->Error( ERRCODE_BASIC_CONVERSION );
-                        bError = true;
-                        break;
-                    }
+                    pParser->Error( ERRCODE_BASIC_MATH_OVERFLOW );
+                    bError = true;
                 }
             }
-            else
+            bool bBothInt = ( pLeft->eType < SbxSINGLE
+                               && pRight->eType < SbxSINGLE );
+            pLeft.reset();
+            pRight.reset();
+            nVal = 0;
+            eType = SbxDOUBLE;
+            eNodeType = SbxNUMVAL;
+            bool bCheckType = false;
+            switch( eTok )
             {
-                double nl = pLeft->nVal;
-                double nr = pRight->nVal;
-                long ll = 0, lr = 0;
-                long llMod = 0, lrMod = 0;
-                if( ( eTok >= AND && eTok <= IMP )
-                   || eTok == IDIV || eTok == MOD )
-                {
-                    // Integer operations
-                    bool bErr = false;
-                    if( nl > SbxMAXLNG ) bErr = true, nl = SbxMAXLNG;
-                    else if( nl < SbxMINLNG ) bErr = true, nl = SbxMINLNG;
-                    if( nr > SbxMAXLNG ) bErr = true, nr = SbxMAXLNG;
-                    else if( nr < SbxMINLNG ) bErr = true, nr = SbxMINLNG;
-                    ll = static_cast<long>(nl); lr = static_cast<long>(nr);
-                    llMod = static_cast<long>(nl);
-                    lrMod = static_cast<long>(nr);
-                    if( bErr )
+                case EXPON:
+                    nVal = pow( nl, nr ); break;
+                case MUL:
+                    bCheckType = true;
+                    nVal = nl * nr; break;
+                case DIV:
+                    if( !nr )
                     {
-                        pParser->Error( ERRCODE_BASIC_MATH_OVERFLOW );
+                        pParser->Error( ERRCODE_BASIC_ZERODIV ); nVal = HUGE_VAL;
                         bError = true;
-                    }
-                }
-                bool bBothInt = ( pLeft->eType < SbxSINGLE
-                                   && pRight->eType < SbxSINGLE );
-                pLeft.reset();
-                pRight.reset();
-                nVal = 0;
-                eType = SbxDOUBLE;
-                eNodeType = SbxNUMVAL;
-                bool bCheckType = false;
-                switch( eTok )
-                {
-                    case EXPON:
-                        nVal = pow( nl, nr ); break;
-                    case MUL:
-                        bCheckType = true;
-                        nVal = nl * nr; break;
-                    case DIV:
-                        if( !nr )
-                        {
-                            pParser->Error( ERRCODE_BASIC_ZERODIV ); nVal = HUGE_VAL;
-                            bError = true;
-                        } else nVal = nl / nr;
-                        break;
-                    case PLUS:
-                        bCheckType = true;
-                        nVal = nl + nr; break;
-                    case MINUS:
-                        bCheckType = true;
-                        nVal = nl - nr; break;
-                    case EQ:
-                        nVal = ( nl == nr ) ? SbxTRUE : SbxFALSE;
-                        eType = SbxINTEGER; break;
-                    case NE:
-                        nVal = ( nl != nr ) ? SbxTRUE : SbxFALSE;
-                        eType = SbxINTEGER; break;
-                    case LT:
-                        nVal = ( nl <  nr ) ? SbxTRUE : SbxFALSE;
-                        eType = SbxINTEGER; break;
-                    case GT:
-                        nVal = ( nl >  nr ) ? SbxTRUE : SbxFALSE;
-                        eType = SbxINTEGER; break;
-                    case LE:
-                        nVal = ( nl <= nr ) ? SbxTRUE : SbxFALSE;
-                        eType = SbxINTEGER; break;
-                    case GE:
-                        nVal = ( nl >= nr ) ? SbxTRUE : SbxFALSE;
-                        eType = SbxINTEGER; break;
-                    case IDIV:
-                        if( !lr )
-                        {
-                            pParser->Error( ERRCODE_BASIC_ZERODIV ); nVal = HUGE_VAL;
-                            bError = true;
-                        } else nVal = ll / lr;
-                        eType = SbxLONG; break;
-                    case MOD:
-                        if( !lr )
-                        {
-                            pParser->Error( ERRCODE_BASIC_ZERODIV ); nVal = HUGE_VAL;
-                            bError = true;
-                        } else nVal = llMod - lrMod * (llMod/lrMod);
-                        eType = SbxLONG; break;
-                    case AND:
-                        nVal = (double) ( ll & lr ); eType = SbxLONG; break;
-                    case OR:
-                        nVal = (double) ( ll | lr ); eType = SbxLONG; break;
-                    case XOR:
-                        nVal = (double) ( ll ^ lr ); eType = SbxLONG; break;
-                    case EQV:
-                        nVal = (double) ( ~ll ^ lr ); eType = SbxLONG; break;
-                    case IMP:
-                        nVal = (double) ( ~ll | lr ); eType = SbxLONG; break;
-                    default: break;
-                }
+                    } else nVal = nl / nr;
+                    break;
+                case PLUS:
+                    bCheckType = true;
+                    nVal = nl + nr; break;
+                case MINUS:
+                    bCheckType = true;
+                    nVal = nl - nr; break;
+                case EQ:
+                    nVal = ( nl == nr ) ? SbxTRUE : SbxFALSE;
+                    eType = SbxINTEGER; break;
+                case NE:
+                    nVal = ( nl != nr ) ? SbxTRUE : SbxFALSE;
+                    eType = SbxINTEGER; break;
+                case LT:
+                    nVal = ( nl <  nr ) ? SbxTRUE : SbxFALSE;
+                    eType = SbxINTEGER; break;
+                case GT:
+                    nVal = ( nl >  nr ) ? SbxTRUE : SbxFALSE;
+                    eType = SbxINTEGER; break;
+                case LE:
+                    nVal = ( nl <= nr ) ? SbxTRUE : SbxFALSE;
+                    eType = SbxINTEGER; break;
+                case GE:
+                    nVal = ( nl >= nr ) ? SbxTRUE : SbxFALSE;
+                    eType = SbxINTEGER; break;
+                case IDIV:
+                    if( !lr )
+                    {
+                        pParser->Error( ERRCODE_BASIC_ZERODIV ); nVal = HUGE_VAL;
+                        bError = true;
+                    } else nVal = ll / lr;
+                    eType = SbxLONG; break;
+                case MOD:
+                    if( !lr )
+                    {
+                        pParser->Error( ERRCODE_BASIC_ZERODIV ); nVal = HUGE_VAL;
+                        bError = true;
+                    } else nVal = llMod - lrMod * (llMod/lrMod);
+                    eType = SbxLONG; break;
+                case AND:
+                    nVal = (double) ( ll & lr ); eType = SbxLONG; break;
+                case OR:
+                    nVal = (double) ( ll | lr ); eType = SbxLONG; break;
+                case XOR:
+                    nVal = (double) ( ll ^ lr ); eType = SbxLONG; break;
+                case EQV:
+                    nVal = (double) ( ~ll ^ lr ); eType = SbxLONG; break;
+                case IMP:
+                    nVal = (double) ( ~ll | lr ); eType = SbxLONG; break;
+                default: break;
+            }
 
-                if( !::rtl::math::isFinite( nVal ) )
-                    pParser->Error( ERRCODE_BASIC_MATH_OVERFLOW );
+            if( !::rtl::math::isFinite( nVal ) )
+                pParser->Error( ERRCODE_BASIC_MATH_OVERFLOW );
 
-                // Recover the data type to kill rounding error
-                if( bCheckType && bBothInt
-                 && nVal >= SbxMINLNG && nVal <= SbxMAXLNG )
-                {
-                    // Decimal place away
-                    long n = (long) nVal;
-                    nVal = n;
-                    eType = ( n >= SbxMININT && n <= SbxMAXINT )
-                          ? SbxINTEGER : SbxLONG;
-                }
+            // Recover the data type to kill rounding error
+            if( bCheckType && bBothInt
+             && nVal >= SbxMINLNG && nVal <= SbxMAXLNG )
+            {
+                // Decimal place away
+                long n = (long) nVal;
+                nVal = n;
+                eType = ( n >= SbxMININT && n <= SbxMAXINT )
+                      ? SbxINTEGER : SbxLONG;
             }
         }
     }
-    else if (pLeft && pLeft->IsNumber())
+
+}
+void SbiExprNode::FoldConstantsUnaryNode(SbiParser* pParser)
+{
+    pLeft->FoldConstants(pParser);
+    if (pLeft->IsNumber())
     {
         nVal = pLeft->nVal;
         pLeft.reset();
diff --git a/basic/source/inc/expr.hxx b/basic/source/inc/expr.hxx
index ac2cce8..6efa150 100644
--- a/basic/source/inc/expr.hxx
+++ b/basic/source/inc/expr.hxx
@@ -105,6 +105,8 @@ class SbiExprNode {                  // operators (and operands)
     SbiToken     eTok;
     bool  bError;                   // true: error
     void  FoldConstants(SbiParser*);
+    void  FoldConstantsBinaryNode(SbiParser*);
+    void  FoldConstantsUnaryNode(SbiParser*);
     void  CollectBits();            // converting numbers to strings
     bool  IsOperand()
         { return eNodeType != SbxNODE && eNodeType != SbxTYPEOF && eNodeType != SbxNEW; }
@@ -131,6 +133,10 @@ public:
         { return eNodeType == SbxSTRVAL || eNodeType == SbxNUMVAL; }
     bool IsIntConst();
     bool IsVariable();
+    bool  IsUnary()
+        { return pLeft && !pRight; }
+    bool  IsBinary()
+        { return pLeft && pRight; }
 
     SbiExprNode* GetWithParent()            { return pWithParent; }
     void SetWithParent( SbiExprNode* p )    { pWithParent = p; }


More information about the Libreoffice-commits mailing list