diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 9dd208958b..8689d65152 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -8,6 +8,18 @@ 2008-12-31 13:59 UTC+0100 Foo Bar */ +2008-06-02 13:32 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/include/hbexprop.h + * harbour/include/hbexprb.c + * harbour/source/common/expropt2.c + + added hb_compExprReducePower() and compile time optimization for: + ^ + + added compile time optimization for: + % + when or is not integer value + NOTE: both optimizations are not Clipper compatible and disabled + when -kc compiler switch is used + 2008-06-02 12:42 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) * harbour/contrib/hbsqlit3/tests/blob.prg * harbour/contrib/hbsqlit3/tests/sqlite3_test.prg diff --git a/harbour/include/hbexprb.c b/harbour/include/hbexprb.c index 7602aa7498..b1dc6d8c88 100644 --- a/harbour/include/hbexprb.c +++ b/harbour/include/hbexprb.c @@ -3751,7 +3751,13 @@ static HB_EXPR_FUNC( hb_compExprUsePower ) { switch( iMessage ) { - case HB_EA_REDUCE: /* Clipper doesn't optimize it */ + case HB_EA_REDUCE: + if( HB_SUPPORT_HARBOUR ) /* Clipper doesn't optimize it */ + { + pSelf->value.asOperator.pLeft = hb_compExprListStrip( HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_REDUCE ), HB_COMP_PARAM ); + pSelf->value.asOperator.pRight = hb_compExprListStrip( HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_REDUCE ), HB_COMP_PARAM ); + pSelf =hb_compExprReducePower( pSelf, HB_COMP_PARAM ); + } break; case HB_EA_ARRAY_AT: diff --git a/harbour/include/hbexprop.h b/harbour/include/hbexprop.h index 381587e59c..0265e4eb47 100644 --- a/harbour/include/hbexprop.h +++ b/harbour/include/hbexprop.h @@ -174,6 +174,7 @@ extern HB_EXPR_PTR hb_compExprSetGetBlock( HB_EXPR_PTR pExpr, HB_COMP_DECL ); extern void hb_compExprDelOperator( HB_EXPR_PTR, HB_COMP_DECL ); +extern HB_EXPR_PTR hb_compExprReducePower( HB_EXPR_PTR pSelf, HB_COMP_DECL ); extern HB_EXPR_PTR hb_compExprReduceMod( HB_EXPR_PTR pSelf, HB_COMP_DECL ); extern HB_EXPR_PTR hb_compExprReduceDiv( HB_EXPR_PTR pSelf, HB_COMP_DECL ); extern HB_EXPR_PTR hb_compExprReduceMult( HB_EXPR_PTR pSelf, HB_COMP_DECL ); diff --git a/harbour/source/common/expropt2.c b/harbour/source/common/expropt2.c index 12ceafc931..ecc961c4fb 100644 --- a/harbour/source/common/expropt2.c +++ b/harbour/source/common/expropt2.c @@ -128,20 +128,44 @@ HB_EXPR_PTR hb_compExprReduceMod( HB_EXPR_PTR pSelf, HB_COMP_DECL ) if( pLeft->ExprType == HB_ET_NUMERIC && pRight->ExprType == HB_ET_NUMERIC ) { - if( pLeft->value.asNum.NumType == HB_ET_LONG && pRight->value.asNum.NumType == HB_ET_LONG ) + switch( pLeft->value.asNum.NumType & pRight->value.asNum.NumType ) { - if( pRight->value.asNum.val.l ) - { - HB_LONG lVal = pLeft->value.asNum.val.l % pRight->value.asNum.val.l; + case HB_ET_LONG: + if( pRight->value.asNum.val.l ) + { + pSelf->value.asNum.val.l = pLeft->value.asNum.val.l % pRight->value.asNum.val.l; + pSelf->value.asNum.bDec = 0; + pSelf->value.asNum.NumType = HB_ET_LONG; + pSelf->ExprType = HB_ET_NUMERIC; + pSelf->ValType = HB_EV_NUMERIC; + HB_COMP_EXPR_FREE( pLeft ); + HB_COMP_EXPR_FREE( pRight ); + } + break; - pSelf->value.asNum.val.l = lVal; - pSelf->value.asNum.bDec = 0; - pSelf->value.asNum.NumType = HB_ET_LONG; - pSelf->ExprType = HB_ET_NUMERIC; - pSelf->ValType = HB_EV_NUMERIC; - HB_COMP_EXPR_FREE( pLeft ); - HB_COMP_EXPR_FREE( pRight ); - } + default: + if( HB_SUPPORT_HARBOUR ) + { + double dValue, dDivisor; + + dDivisor = pRight->value.asNum.NumType == HB_ET_LONG ? + pRight->value.asNum.val.l : + pRight->value.asNum.val.d; + if( dDivisor ) + { + dValue = pLeft->value.asNum.NumType == HB_ET_LONG ? + pLeft->value.asNum.val.l : + pLeft->value.asNum.val.d; + pSelf->value.asNum.val.d = fmod( dValue, dDivisor ); + pSelf->value.asNum.bWidth = HB_DEFAULT_WIDTH; + pSelf->value.asNum.bDec = HB_DEFAULT_DECIMALS; + pSelf->value.asNum.NumType = HB_ET_DOUBLE; + pSelf->ExprType = HB_ET_NUMERIC; + pSelf->ValType = HB_EV_NUMERIC; + HB_COMP_EXPR_FREE( pLeft ); + HB_COMP_EXPR_FREE( pRight ); + } + } } } else @@ -316,6 +340,56 @@ HB_EXPR_PTR hb_compExprReduceMult( HB_EXPR_PTR pSelf, HB_COMP_DECL ) return pSelf; } +HB_EXPR_PTR hb_compExprReducePower( HB_EXPR_PTR pSelf, HB_COMP_DECL ) +{ + HB_EXPR_PTR pLeft, pRight; + + pLeft = pSelf->value.asOperator.pLeft; + pRight = pSelf->value.asOperator.pRight; + + if( pLeft->ExprType == HB_ET_NUMERIC && pRight->ExprType == HB_ET_NUMERIC ) + { + BYTE bType = ( pLeft->value.asNum.NumType & pRight->value.asNum.NumType ); + + switch( bType ) + { + case HB_ET_LONG: + pSelf->value.asNum.val.d = pow( ( double ) pLeft->value.asNum.val.l, + ( double ) pRight->value.asNum.val.l ); + break; + + case HB_ET_DOUBLE: + pSelf->value.asNum.val.d = pow( pLeft->value.asNum.val.d, + pRight->value.asNum.val.d ); + break; + + default: + pSelf->value.asNum.val.d = pow( pLeft->value.asNum.val.d, + pRight->value.asNum.val.d ); + if( pLeft->value.asNum.NumType == HB_ET_DOUBLE ) + pSelf->value.asNum.val.d = pow( pLeft->value.asNum.val.d, + ( double ) pRight->value.asNum.val.l ); + else + pSelf->value.asNum.val.d = pow( ( double ) pLeft->value.asNum.val.l, + pRight->value.asNum.val.d ); + break; + } + pSelf->value.asNum.bWidth = HB_DEFAULT_WIDTH; + pSelf->value.asNum.bDec = HB_DEFAULT_DECIMALS; + pSelf->value.asNum.NumType = HB_ET_DOUBLE; + pSelf->ExprType = HB_ET_NUMERIC; + pSelf->ValType = HB_EV_NUMERIC; + HB_COMP_EXPR_FREE( pLeft ); + HB_COMP_EXPR_FREE( pRight ); + } + else + { + /* TODO: Check for incompatible types e.g. 3 * "txt" + */ + } + return pSelf; +} + HB_EXPR_PTR hb_compExprReduceMinus( HB_EXPR_PTR pSelf, HB_COMP_DECL ) { HB_EXPR_PTR pLeft, pRight;