summaryrefslogtreecommitdiff
path: root/basic/source/comp
diff options
context:
space:
mode:
authorArnaud Versini <arnaud.versini@gmail.com>2015-07-12 13:52:53 +0200
committerArnaud Versini <arnaud.versini@libreoffice.org>2015-12-22 11:13:03 +0000
commit4251e676bb818cde1989b9077b1497f1d9b0cbdc (patch)
treee2165ce1a736fb99cb40dd29f6ea45022e23e08c /basic/source/comp
parenta9db17aabc3ac970e6e4754e28310d20138144d9 (diff)
BASIC : Refactor FoldConstants for extracting it from SwExprNode.
Change-Id: Ia47597b26d63db216dd3ab71acbb18449ece7b1a Reviewed-on: https://gerrit.libreoffice.org/16963 Reviewed-by: Arnaud Versini <arnaud.versini@libreoffice.org> Tested-by: Arnaud Versini <arnaud.versini@libreoffice.org>
Diffstat (limited to 'basic/source/comp')
-rw-r--r--basic/source/comp/exprnode.cxx342
1 files changed, 183 insertions, 159 deletions
diff --git a/basic/source/comp/exprnode.cxx b/basic/source/comp/exprnode.cxx
index 52c2211fcfa3..9d77f6dba071 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();