2007-01-05 08:00 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
* harbour/include/hbcompdf.h
+ added comment
* harbour/include/hbexpra.c
* change expression type for <exp> = <exp> from HB_EO_EQUAL
to HB_EO_ASSIGN in hb_compExprGenStatement() function so
later we can safely make all optimization in hb_compExprUseEqual()
during reduce process - optimization only when PCODE is generated
is too late and causes that expressions like:
iif( 1 = 1, <exp>, <exp> )
are not reduces (Clipper reduce them)
* do not execute hb_compFunCallCheck() in hb_compExprNewFunCall()
to avoid repeating the same error message in hb_compExprUseFunCall()
* harbour/include/hbexprb.c
* enabled reduction for hb_compExprUseEqual() and generate errors
when it's used as statement
* harbour/source/common/expropt2.c
* added some missing reductions for expressions like: NIL == NIL
* harbour/source/common/reserved.c
% very basic optimization: use binary search instead of linear
scanning for reserved words and shortcuts - it gives noticeable
speed improvement in macro compiler
* harbour/source/compiler/complex.c
* changed the order of special keywords to keep alphabetic sorting
* harbour/source/compiler/harbour.c
% some minor optimizations in aliased expressions
! added protection in hb_compIsJump() to avoid possible problems
when this function is executed after replacing some code with
jumps by series of NOOPs in optimizations process
* harbour/source/compiler/hbfix.c
* better optimization of PCODE generated for logical expressions
* harbour/source/compiler/hbfunchk.c
% use binary search instead of linear scan
* harbour/source/rtl/minmax.c
! fixed GPF when MIN() or MAX() function is called with less then
two parameters
* harbour/source/vm/itemapi.c
* minor optimization and formatting
This commit is contained in:
@@ -8,6 +8,55 @@
|
||||
2002-12-01 13:30 UTC+0100 Foo Bar <foo.bar@foobar.org>
|
||||
*/
|
||||
|
||||
2007-01-05 08:00 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
|
||||
* harbour/include/hbcompdf.h
|
||||
+ added comment
|
||||
|
||||
* harbour/include/hbexpra.c
|
||||
* change expression type for <exp> = <exp> from HB_EO_EQUAL
|
||||
to HB_EO_ASSIGN in hb_compExprGenStatement() function so
|
||||
later we can safely make all optimization in hb_compExprUseEqual()
|
||||
during reduce process - optimization only when PCODE is generated
|
||||
is too late and causes that expressions like:
|
||||
iif( 1 = 1, <exp>, <exp> )
|
||||
are not reduces (Clipper reduce them)
|
||||
* do not execute hb_compFunCallCheck() in hb_compExprNewFunCall()
|
||||
to avoid repeating the same error message in hb_compExprUseFunCall()
|
||||
|
||||
* harbour/include/hbexprb.c
|
||||
* enabled reduction for hb_compExprUseEqual() and generate errors
|
||||
when it's used as statement
|
||||
|
||||
* harbour/source/common/expropt2.c
|
||||
* added some missing reductions for expressions like: NIL == NIL
|
||||
|
||||
* harbour/source/common/reserved.c
|
||||
% very basic optimization: use binary search instead of linear
|
||||
scanning for reserved words and shortcuts - it gives noticeable
|
||||
speed improvement in macro compiler
|
||||
|
||||
* harbour/source/compiler/complex.c
|
||||
* changed the order of special keywords to keep alphabetic sorting
|
||||
|
||||
* harbour/source/compiler/harbour.c
|
||||
% some minor optimizations in aliased expressions
|
||||
! added protection in hb_compIsJump() to avoid possible problems
|
||||
when this function is executed after replacing some code with
|
||||
jumps by series of NOOPs in optimizations process
|
||||
|
||||
* harbour/source/compiler/hbfix.c
|
||||
* better optimization of PCODE generated for logical expressions
|
||||
|
||||
* harbour/source/compiler/hbfunchk.c
|
||||
% use binary search instead of linear scan
|
||||
|
||||
* harbour/source/rtl/minmax.c
|
||||
! fixed GPF when MIN() or MAX() function is called with less then
|
||||
two parameters
|
||||
|
||||
* harbour/source/vm/itemapi.c
|
||||
* minor optimization and formatting
|
||||
|
||||
2006-12-30 22:45 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
|
||||
* harbour/include/hbcomp.h
|
||||
* harbour/include/hbcompdf.h
|
||||
|
||||
@@ -481,7 +481,7 @@ HB_COMMON, * HB_COMMON_PTR;
|
||||
#define HB_COMP_PARAM pMacro
|
||||
#define HB_COMP_DECL HB_MACRO_PTR HB_COMP_PARAM
|
||||
|
||||
typedef struct HB_PCODE_INFO_ /* compiled pcode container */
|
||||
typedef struct HB_PCODE_INFO_ /* compiled pcode container for macro compiler */
|
||||
{
|
||||
BYTE * pCode; /* pointer to a memory block where pcode is stored */
|
||||
ULONG lPCodeSize; /* total memory size for pcode */
|
||||
|
||||
@@ -393,17 +393,7 @@ HB_EXPR_PTR hb_compExprNewFunCall( HB_EXPR_PTR pName, HB_EXPR_PTR pParms, HB_COM
|
||||
|
||||
iCount = ( int ) hb_compExprParamListLen( pParms );
|
||||
|
||||
#ifndef HB_MACRO_SUPPORT
|
||||
if( ! hb_compFunCallCheck( HB_COMP_PARAM, pName->value.asSymbol, iCount ) )
|
||||
{
|
||||
/* skip any farther modifications which can depend on valid number
|
||||
of parameters */
|
||||
;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
/* TODO: EMPTY() (not done by Clipper) */
|
||||
|
||||
if( iCount && strcmp( "EVAL", pName->value.asSymbol ) == 0 )
|
||||
{
|
||||
HB_EXPR_PTR pEval;
|
||||
@@ -935,6 +925,12 @@ HB_EXPR_PTR hb_compExprGenStatement( HB_EXPR_PTR pExpr, HB_COMP_DECL )
|
||||
HB_TRACE(HB_TR_DEBUG, ("hb_compExprGenStatement(%p)", pExpr));
|
||||
if( pExpr )
|
||||
{
|
||||
if( pExpr->ExprType == HB_EO_EQUAL )
|
||||
{
|
||||
/* NOTE: direct type change */
|
||||
pExpr->ExprType = HB_EO_ASSIGN;
|
||||
}
|
||||
|
||||
pExpr = HB_EXPR_USE( pExpr, HB_EA_REDUCE );
|
||||
HB_EXPR_USE( pExpr, HB_EA_STATEMENT );
|
||||
}
|
||||
|
||||
@@ -2709,13 +2709,15 @@ static HB_EXPR_FUNC( hb_compExprUseEqual )
|
||||
switch( iMessage )
|
||||
{
|
||||
case HB_EA_REDUCE:
|
||||
{
|
||||
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->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_compExprReduceEQ( pSelf, HB_COMP_PARAM );
|
||||
break;
|
||||
|
||||
case HB_EA_ARRAY_AT:
|
||||
hb_compErrorType( HB_COMP_PARAM, pSelf );
|
||||
break;
|
||||
|
||||
case HB_EA_ARRAY_INDEX:
|
||||
break;
|
||||
|
||||
@@ -2723,81 +2725,9 @@ static HB_EXPR_FUNC( hb_compExprUseEqual )
|
||||
hb_compErrorLValue( HB_COMP_PARAM, pSelf );
|
||||
break;
|
||||
case HB_EA_PUSH_PCODE:
|
||||
{
|
||||
/* '=' used in an expression - compare values
|
||||
*/
|
||||
/* Try to optimize expression - we cannot optimize in HB_EA_REDUCE
|
||||
* because it is not decided yet if it is assigment or comparision
|
||||
*/
|
||||
HB_EXPR_PTR pLeft, pRight;
|
||||
|
||||
pLeft = pSelf->value.asOperator.pLeft;
|
||||
pRight = pSelf->value.asOperator.pRight;
|
||||
|
||||
if( pLeft->ExprType == pRight->ExprType )
|
||||
switch( pLeft->ExprType )
|
||||
{
|
||||
case HB_ET_LOGICAL:
|
||||
HB_EXPR_PCODE1( hb_compGenPushLogical, (pLeft->value.asLogical == pRight->value.asLogical) );
|
||||
break;
|
||||
|
||||
case HB_ET_STRING:
|
||||
/* NOTE: the result depends on SET EXACT setting then it
|
||||
* cannot be optimized except the case when NULL string are
|
||||
* compared - the result is always TRUE regardless of EXACT
|
||||
* setting
|
||||
*/
|
||||
if( (pLeft->ulLength | pRight->ulLength) == 0 )
|
||||
HB_EXPR_PCODE1( hb_compGenPushLogical, TRUE ); /* NOTE: COMPATIBILITY: Clipper doesn't optimize this */
|
||||
else
|
||||
{
|
||||
HB_EXPR_USE( pLeft, HB_EA_PUSH_PCODE );
|
||||
HB_EXPR_USE( pRight, HB_EA_PUSH_PCODE );
|
||||
HB_EXPR_PCODE1( hb_compGenPCode1, HB_P_EQUAL );
|
||||
}
|
||||
break;
|
||||
|
||||
case HB_ET_NIL:
|
||||
/* NOTE: COMPATIBILITY: Clipper doesn't optimize this */
|
||||
HB_EXPR_PCODE1( hb_compGenPushLogical, TRUE ); /* NIL = NIL is always TRUE */
|
||||
break;
|
||||
|
||||
case HB_ET_NUMERIC:
|
||||
switch( pLeft->value.asNum.NumType & pRight->value.asNum.NumType )
|
||||
{
|
||||
case HB_ET_LONG:
|
||||
HB_EXPR_PCODE1( hb_compGenPushLogical, (pLeft->value.asNum.val.l == pRight->value.asNum.val.l) );
|
||||
break;
|
||||
case HB_ET_DOUBLE:
|
||||
HB_EXPR_PCODE1( hb_compGenPushLogical, (pLeft->value.asNum.val.d == pRight->value.asNum.val.d) );
|
||||
break;
|
||||
default:
|
||||
{
|
||||
if( pLeft->value.asNum.NumType == HB_ET_LONG )
|
||||
HB_EXPR_PCODE1( hb_compGenPushLogical, (pLeft->value.asNum.val.l == pRight->value.asNum.val.d) );
|
||||
else
|
||||
HB_EXPR_PCODE1( hb_compGenPushLogical, (pLeft->value.asNum.val.d == pRight->value.asNum.val.l) );
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
HB_EXPR_USE( pLeft, HB_EA_PUSH_PCODE );
|
||||
HB_EXPR_USE( pRight, HB_EA_PUSH_PCODE );
|
||||
HB_EXPR_PCODE1( hb_compGenPCode1, HB_P_EQUAL );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* TODO: check for incompatible types
|
||||
*/
|
||||
HB_EXPR_USE( pLeft, HB_EA_PUSH_PCODE );
|
||||
HB_EXPR_USE( pRight, HB_EA_PUSH_PCODE );
|
||||
HB_EXPR_PCODE1( hb_compGenPCode1, HB_P_EQUAL );
|
||||
}
|
||||
}
|
||||
HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE );
|
||||
HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE );
|
||||
HB_EXPR_PCODE1( hb_compGenPCode1, HB_P_EQUAL );
|
||||
break;
|
||||
|
||||
case HB_EA_POP_PCODE:
|
||||
@@ -2820,25 +2750,7 @@ static HB_EXPR_FUNC( hb_compExprUseEqual )
|
||||
break;
|
||||
|
||||
case HB_EA_STATEMENT:
|
||||
/* '=' used standalone in a statement - assign a value
|
||||
* it assigns a value and removes it from the stack
|
||||
* */
|
||||
if( pSelf->value.asOperator.pLeft->ExprType == HB_ET_SEND )
|
||||
{
|
||||
/* Send messages are implemented as function calls
|
||||
*/
|
||||
HB_EXPR_PTR pObj = pSelf->value.asOperator.pLeft;
|
||||
pObj->value.asMessage.pParms = pSelf->value.asOperator.pRight;
|
||||
HB_EXPR_USE( pObj, HB_EA_POP_PCODE );
|
||||
pObj->value.asMessage.pParms = NULL; /* to suppress duplicated releasing */
|
||||
/* Remove the return value */
|
||||
HB_EXPR_PCODE1( hb_compGenPCode1, HB_P_POP );
|
||||
}
|
||||
else
|
||||
{
|
||||
HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE );
|
||||
HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_POP_PCODE );
|
||||
}
|
||||
hb_compErrorSyntax( HB_COMP_PARAM, pSelf );
|
||||
break;
|
||||
|
||||
case HB_EA_DELETE:
|
||||
|
||||
@@ -571,6 +571,7 @@ HB_EXPR_PTR hb_compExprReduceNE( HB_EXPR_PTR pSelf, HB_COMP_DECL )
|
||||
pRight = pSelf->value.asOperator.pRight;
|
||||
|
||||
if( pLeft->ExprType == pRight->ExprType )
|
||||
{
|
||||
switch( pLeft->ExprType )
|
||||
{
|
||||
case HB_ET_LOGICAL:
|
||||
@@ -581,8 +582,8 @@ HB_EXPR_PTR hb_compExprReduceNE( HB_EXPR_PTR pSelf, HB_COMP_DECL )
|
||||
* .T. != .F. = .T.
|
||||
*/
|
||||
BOOL bResult = ( pLeft->value.asLogical != pRight->value.asLogical );
|
||||
hb_compExprFree( pSelf->value.asOperator.pLeft, HB_COMP_PARAM );
|
||||
hb_compExprFree( pSelf->value.asOperator.pRight, HB_COMP_PARAM );
|
||||
hb_compExprFree( pLeft, HB_COMP_PARAM );
|
||||
hb_compExprFree( pRight, HB_COMP_PARAM );
|
||||
pSelf->ExprType = HB_ET_LOGICAL;
|
||||
pSelf->ValType = HB_EV_LOGICAL;
|
||||
pSelf->value.asLogical = bResult;
|
||||
@@ -595,10 +596,10 @@ HB_EXPR_PTR hb_compExprReduceNE( HB_EXPR_PTR pSelf, HB_COMP_DECL )
|
||||
* compared - "" != "" is always FALSE regardless of EXACT
|
||||
* setting
|
||||
*/
|
||||
if( (pLeft->ulLength | pRight->ulLength) == 0 )
|
||||
if( ( pLeft->ulLength | pRight->ulLength ) == 0 )
|
||||
{
|
||||
hb_compExprFree( pSelf->value.asOperator.pLeft, HB_COMP_PARAM );
|
||||
hb_compExprFree( pSelf->value.asOperator.pRight, HB_COMP_PARAM );
|
||||
hb_compExprFree( pLeft, HB_COMP_PARAM );
|
||||
hb_compExprFree( pRight, HB_COMP_PARAM );
|
||||
pSelf->ExprType = HB_ET_LOGICAL;
|
||||
pSelf->ValType = HB_EV_LOGICAL;
|
||||
pSelf->value.asLogical = FALSE;
|
||||
@@ -628,15 +629,23 @@ HB_EXPR_PTR hb_compExprReduceNE( HB_EXPR_PTR pSelf, HB_COMP_DECL )
|
||||
}
|
||||
break;
|
||||
}
|
||||
hb_compExprFree( pSelf->value.asOperator.pLeft, HB_COMP_PARAM );
|
||||
hb_compExprFree( pSelf->value.asOperator.pRight, HB_COMP_PARAM );
|
||||
hb_compExprFree( pLeft, HB_COMP_PARAM );
|
||||
hb_compExprFree( pRight, HB_COMP_PARAM );
|
||||
pSelf->ExprType = HB_ET_LOGICAL;
|
||||
pSelf->ValType = HB_EV_LOGICAL;
|
||||
pSelf->value.asLogical = bResult;
|
||||
}
|
||||
break;
|
||||
|
||||
case HB_ET_NIL:
|
||||
hb_compExprFree( pLeft, HB_COMP_PARAM );
|
||||
hb_compExprFree( pRight, HB_COMP_PARAM );
|
||||
pSelf->ExprType = HB_ET_LOGICAL;
|
||||
pSelf->ValType = HB_EV_LOGICAL;
|
||||
pSelf->value.asLogical = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* TODO: add checking of incompatible types
|
||||
else
|
||||
{
|
||||
@@ -663,8 +672,8 @@ HB_EXPR_PTR hb_compExprReduceGE( HB_EXPR_PTR pSelf, HB_COMP_DECL )
|
||||
* .F. >= .T. = .f.
|
||||
*/
|
||||
BOOL bResult = ! ( ! pLeft->value.asLogical && pRight->value.asLogical );
|
||||
hb_compExprFree( pSelf->value.asOperator.pLeft, HB_COMP_PARAM );
|
||||
hb_compExprFree( pSelf->value.asOperator.pRight, HB_COMP_PARAM );
|
||||
hb_compExprFree( pLeft, HB_COMP_PARAM );
|
||||
hb_compExprFree( pRight, HB_COMP_PARAM );
|
||||
pSelf->ExprType = HB_ET_LOGICAL;
|
||||
pSelf->ValType = HB_EV_LOGICAL;
|
||||
pSelf->value.asLogical = bResult;
|
||||
@@ -692,8 +701,8 @@ HB_EXPR_PTR hb_compExprReduceGE( HB_EXPR_PTR pSelf, HB_COMP_DECL )
|
||||
}
|
||||
break;
|
||||
}
|
||||
hb_compExprFree( pSelf->value.asOperator.pLeft, HB_COMP_PARAM );
|
||||
hb_compExprFree( pSelf->value.asOperator.pRight, HB_COMP_PARAM );
|
||||
hb_compExprFree( pLeft, HB_COMP_PARAM );
|
||||
hb_compExprFree( pRight, HB_COMP_PARAM );
|
||||
pSelf->ExprType = HB_ET_LOGICAL;
|
||||
pSelf->ValType = HB_EV_LOGICAL;
|
||||
pSelf->value.asLogical = bResult;
|
||||
@@ -727,8 +736,8 @@ HB_EXPR_PTR hb_compExprReduceLE( HB_EXPR_PTR pSelf, HB_COMP_DECL )
|
||||
* .F. <= .T. = .T.
|
||||
*/
|
||||
BOOL bResult = ! ( pLeft->value.asLogical && ! pRight->value.asLogical );
|
||||
hb_compExprFree( pSelf->value.asOperator.pLeft, HB_COMP_PARAM );
|
||||
hb_compExprFree( pSelf->value.asOperator.pRight, HB_COMP_PARAM );
|
||||
hb_compExprFree( pLeft, HB_COMP_PARAM );
|
||||
hb_compExprFree( pRight, HB_COMP_PARAM );
|
||||
pSelf->ExprType = HB_ET_LOGICAL;
|
||||
pSelf->ValType = HB_EV_LOGICAL;
|
||||
pSelf->value.asLogical = bResult;
|
||||
@@ -756,8 +765,8 @@ HB_EXPR_PTR hb_compExprReduceLE( HB_EXPR_PTR pSelf, HB_COMP_DECL )
|
||||
}
|
||||
break;
|
||||
}
|
||||
hb_compExprFree( pSelf->value.asOperator.pLeft, HB_COMP_PARAM );
|
||||
hb_compExprFree( pSelf->value.asOperator.pRight, HB_COMP_PARAM );
|
||||
hb_compExprFree( pLeft, HB_COMP_PARAM );
|
||||
hb_compExprFree( pRight, HB_COMP_PARAM );
|
||||
pSelf->ExprType = HB_ET_LOGICAL;
|
||||
pSelf->ValType = HB_EV_LOGICAL;
|
||||
pSelf->value.asLogical = bResult;
|
||||
@@ -791,8 +800,8 @@ HB_EXPR_PTR hb_compExprReduceGT( HB_EXPR_PTR pSelf, HB_COMP_DECL )
|
||||
* .F. > .T. = .F.
|
||||
*/
|
||||
BOOL bResult = ( pLeft->value.asLogical && ! pRight->value.asLogical );
|
||||
hb_compExprFree( pSelf->value.asOperator.pLeft, HB_COMP_PARAM );
|
||||
hb_compExprFree( pSelf->value.asOperator.pRight, HB_COMP_PARAM );
|
||||
hb_compExprFree( pLeft, HB_COMP_PARAM );
|
||||
hb_compExprFree( pRight, HB_COMP_PARAM );
|
||||
pSelf->ExprType = HB_ET_LOGICAL;
|
||||
pSelf->ValType = HB_EV_LOGICAL;
|
||||
pSelf->value.asLogical = bResult;
|
||||
@@ -820,8 +829,8 @@ HB_EXPR_PTR hb_compExprReduceGT( HB_EXPR_PTR pSelf, HB_COMP_DECL )
|
||||
}
|
||||
break;
|
||||
}
|
||||
hb_compExprFree( pSelf->value.asOperator.pLeft, HB_COMP_PARAM );
|
||||
hb_compExprFree( pSelf->value.asOperator.pRight, HB_COMP_PARAM );
|
||||
hb_compExprFree( pLeft, HB_COMP_PARAM );
|
||||
hb_compExprFree( pRight, HB_COMP_PARAM );
|
||||
pSelf->ExprType = HB_ET_LOGICAL;
|
||||
pSelf->ValType = HB_EV_LOGICAL;
|
||||
pSelf->value.asLogical = bResult;
|
||||
@@ -855,8 +864,8 @@ HB_EXPR_PTR hb_compExprReduceLT( HB_EXPR_PTR pSelf, HB_COMP_DECL )
|
||||
* .T. < .F. = .F.
|
||||
*/
|
||||
BOOL bResult = ( ! pLeft->value.asLogical && pRight->value.asLogical );
|
||||
hb_compExprFree( pSelf->value.asOperator.pLeft, HB_COMP_PARAM );
|
||||
hb_compExprFree( pSelf->value.asOperator.pRight, HB_COMP_PARAM );
|
||||
hb_compExprFree( pLeft, HB_COMP_PARAM );
|
||||
hb_compExprFree( pRight, HB_COMP_PARAM );
|
||||
pSelf->ExprType = HB_ET_LOGICAL;
|
||||
pSelf->ValType = HB_EV_LOGICAL;
|
||||
pSelf->value.asLogical = bResult;
|
||||
@@ -884,8 +893,8 @@ HB_EXPR_PTR hb_compExprReduceLT( HB_EXPR_PTR pSelf, HB_COMP_DECL )
|
||||
}
|
||||
break;
|
||||
}
|
||||
hb_compExprFree( pSelf->value.asOperator.pLeft, HB_COMP_PARAM );
|
||||
hb_compExprFree( pSelf->value.asOperator.pRight, HB_COMP_PARAM );
|
||||
hb_compExprFree( pLeft, HB_COMP_PARAM );
|
||||
hb_compExprFree( pRight, HB_COMP_PARAM );
|
||||
pSelf->ExprType = HB_ET_LOGICAL;
|
||||
pSelf->ValType = HB_EV_LOGICAL;
|
||||
pSelf->value.asLogical = bResult;
|
||||
@@ -917,8 +926,8 @@ HB_EXPR_PTR hb_compExprReduceEQ( HB_EXPR_PTR pSelf, HB_COMP_DECL )
|
||||
case HB_ET_LOGICAL:
|
||||
{
|
||||
BOOL bResult = ( pLeft->value.asLogical == pRight->value.asLogical );
|
||||
hb_compExprFree( pSelf->value.asOperator.pLeft, HB_COMP_PARAM );
|
||||
hb_compExprFree( pSelf->value.asOperator.pRight, HB_COMP_PARAM );
|
||||
hb_compExprFree( pLeft, HB_COMP_PARAM );
|
||||
hb_compExprFree( pRight, HB_COMP_PARAM );
|
||||
pSelf->ExprType = HB_ET_LOGICAL;
|
||||
pSelf->ValType = HB_EV_LOGICAL;
|
||||
pSelf->value.asLogical = bResult;
|
||||
@@ -926,13 +935,21 @@ HB_EXPR_PTR hb_compExprReduceEQ( HB_EXPR_PTR pSelf, HB_COMP_DECL )
|
||||
break;
|
||||
|
||||
case HB_ET_STRING:
|
||||
/* NOTE: when not exact comparison (==) is used
|
||||
* the result depends on SET EXACT setting then it
|
||||
* cannot be optimized except the case when NULL string are
|
||||
* compared - "" = "" is always FALSE regardless of EXACT
|
||||
* setting
|
||||
*/
|
||||
if( pSelf->ExprType == HB_EO_EQ ||
|
||||
( pLeft->ulLength | pRight->ulLength ) == 0 )
|
||||
{
|
||||
BOOL bResult = FALSE;
|
||||
|
||||
if( pLeft->ulLength == pRight->ulLength )
|
||||
bResult = ( strcmp( pLeft->value.asString.string, pRight->value.asString.string ) == 0 );
|
||||
hb_compExprFree( pSelf->value.asOperator.pLeft, HB_COMP_PARAM );
|
||||
hb_compExprFree( pSelf->value.asOperator.pRight, HB_COMP_PARAM );
|
||||
BOOL bResult = pLeft->ulLength == pRight->ulLength &&
|
||||
memcmp( pLeft->value.asString.string,
|
||||
pRight->value.asString.string,
|
||||
pLeft->ulLength ) == 0;
|
||||
hb_compExprFree( pLeft, HB_COMP_PARAM );
|
||||
hb_compExprFree( pRight, HB_COMP_PARAM );
|
||||
pSelf->ExprType = HB_ET_LOGICAL;
|
||||
pSelf->ValType = HB_EV_LOGICAL;
|
||||
pSelf->value.asLogical = bResult;
|
||||
@@ -952,21 +969,27 @@ HB_EXPR_PTR hb_compExprReduceEQ( HB_EXPR_PTR pSelf, HB_COMP_DECL )
|
||||
bResult = ( pLeft->value.asNum.val.d == pRight->value.asNum.val.d );
|
||||
break;
|
||||
default:
|
||||
{
|
||||
if( pLeft->value.asNum.NumType == HB_ET_LONG )
|
||||
bResult = ( pLeft->value.asNum.val.l == pRight->value.asNum.val.d );
|
||||
else
|
||||
bResult = ( pLeft->value.asNum.val.d == pRight->value.asNum.val.l );
|
||||
}
|
||||
if( pLeft->value.asNum.NumType == HB_ET_LONG )
|
||||
bResult = ( pLeft->value.asNum.val.l == pRight->value.asNum.val.d );
|
||||
else
|
||||
bResult = ( pLeft->value.asNum.val.d == pRight->value.asNum.val.l );
|
||||
break;
|
||||
}
|
||||
hb_compExprFree( pSelf->value.asOperator.pLeft, HB_COMP_PARAM );
|
||||
hb_compExprFree( pSelf->value.asOperator.pRight, HB_COMP_PARAM );
|
||||
hb_compExprFree( pLeft, HB_COMP_PARAM );
|
||||
hb_compExprFree( pRight, HB_COMP_PARAM );
|
||||
pSelf->ExprType = HB_ET_LOGICAL;
|
||||
pSelf->ValType = HB_EV_LOGICAL;
|
||||
pSelf->value.asLogical = bResult;
|
||||
}
|
||||
break;
|
||||
|
||||
case HB_ET_NIL:
|
||||
hb_compExprFree( pLeft, HB_COMP_PARAM );
|
||||
hb_compExprFree( pRight, HB_COMP_PARAM );
|
||||
pSelf->ExprType = HB_ET_LOGICAL;
|
||||
pSelf->ValType = HB_EV_LOGICAL;
|
||||
pSelf->value.asLogical = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* TODO: add checking of incompatible types
|
||||
|
||||
@@ -54,8 +54,8 @@
|
||||
|
||||
/* Table with reserved functions names
|
||||
* NOTE: THIS TABLE MUST BE SORTED ALPHABETICALLY
|
||||
*/
|
||||
#if(!defined( HB_RESERVED_OFF ))
|
||||
*/
|
||||
#if !defined( HB_RESERVED_OFF )
|
||||
static const char * s_szReservedFun[] = {
|
||||
"AADD" ,
|
||||
"ABS" ,
|
||||
@@ -128,26 +128,34 @@ static const char * s_szReservedFun[] = {
|
||||
|
||||
char * hb_compReservedName( char * szName )
|
||||
{
|
||||
#if(!defined( HB_RESERVED_OFF ))
|
||||
unsigned int wNum = 0;
|
||||
int iFound = 1;
|
||||
#if !defined( HB_RESERVED_OFF )
|
||||
unsigned int uiFirst = 0, uiLast = RESERVED_FUNCTIONS - 1, uiMiddle;
|
||||
int iLen = ( int ) strlen( szName ), iCmp;
|
||||
|
||||
while( wNum < RESERVED_FUNCTIONS && iFound )
|
||||
/* Respect 4 or more letters shortcuts
|
||||
* SECO() is not allowed because of Clipper function SECONDS()
|
||||
* however SECO32() is a valid name.
|
||||
*/
|
||||
if( iLen < 4 )
|
||||
iLen = 4;
|
||||
do
|
||||
{
|
||||
/* Compare first 4 characters
|
||||
* If they are the same then compare the whole name
|
||||
* SECO() is not allowed because of Clipper function SECONDS()
|
||||
* however SECO32() is a valid name.
|
||||
*/
|
||||
iFound = strncmp( szName, s_szReservedFun[ wNum ], 4 );
|
||||
if( iFound == 0 )
|
||||
iFound = strncmp( szName, s_szReservedFun[ wNum ], strlen( szName ) );
|
||||
++wNum;
|
||||
uiMiddle = ( uiFirst + uiLast ) >> 1;
|
||||
iCmp = strncmp( szName, s_szReservedFun[ uiMiddle ], iLen );
|
||||
if( iCmp <= 0 )
|
||||
uiLast = uiMiddle;
|
||||
else
|
||||
uiFirst = uiMiddle + 1;
|
||||
}
|
||||
while( uiFirst < uiLast );
|
||||
|
||||
return iFound == 0 ? ( char * ) s_szReservedFun[ wNum - 1 ] : NULL;
|
||||
#else
|
||||
return NULL;
|
||||
if( uiFirst != uiMiddle )
|
||||
iCmp = strncmp( szName, s_szReservedFun[ uiFirst ], iLen );
|
||||
|
||||
if( iCmp == 0 )
|
||||
return ( char * ) s_szReservedFun[ uiFirst ];
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -108,27 +108,26 @@ HB_LEX_KEY, * PHB_LEX_KEY;
|
||||
static const HB_LEX_KEY s_keytable[] =
|
||||
{
|
||||
{ "ANNOUNCE", 4, 8, ANNOUNCE },
|
||||
{ "AS", 2, 2, AS_TYPE },
|
||||
{ "BEGIN", 4, 5, BEGINSEQ },
|
||||
{ "BREAK", 4, 5, BREAK },
|
||||
{ "CASE", 4, 4, CASE },
|
||||
{ "DECLARE", 4, 7, DECLARE },
|
||||
{ "OPTIONAL", 4, 8, OPTIONAL },
|
||||
{ "DO", 2, 2, DO },
|
||||
{ "DESCEND", 7, 7, DESCEND },
|
||||
{ "DO", 2, 2, DO },
|
||||
{ "ELSE", 4, 4, ELSE },
|
||||
{ "ELSEIF", 5, 6, ELSEIF },
|
||||
{ "END", 3, 3, END },
|
||||
{ "ENDIF", 4, 5, ENDIF },
|
||||
{ "ENDCASE", 4, 7, ENDCASE },
|
||||
{ "ENDDO", 4, 5, ENDDO },
|
||||
{ "ENDIF", 4, 5, ENDIF },
|
||||
{ "EXIT", 4, 4, EXIT },
|
||||
{ "EXTERNAL", 4, 8, EXTERN },
|
||||
{ "_FIELD", 4, 6, FIELD },
|
||||
{ "FIELD", 4, 5, FIELD },
|
||||
{ "FOR", 3, 3, FOR },
|
||||
{ "FUNCTION", 4, 8, FUNCTION },
|
||||
{ "IIF", 3, 3, IIF },
|
||||
{ "IF", 2, 2, IF },
|
||||
{ "IIF", 3, 3, IIF },
|
||||
{ "IN", 2, 2, IN },
|
||||
{ "INIT", 4, 4, INIT },
|
||||
{ "LOCAL", 4, 5, LOCAL },
|
||||
@@ -136,6 +135,7 @@ static const HB_LEX_KEY s_keytable[] =
|
||||
{ "MEMVAR", 4, 6, MEMVAR },
|
||||
{ "NEXT", 4, 4, NEXT },
|
||||
{ "NIL", 3, 3, NIL },
|
||||
{ "OPTIONAL", 4, 8, OPTIONAL },
|
||||
{ "OTHERWISE", 4, 9, OTHERWISE },
|
||||
{ "PARAMETERS", 4, 10, PARAMETERS },
|
||||
{ "PRIVATE", 4, 7, PRIVATE },
|
||||
@@ -150,10 +150,10 @@ static const HB_LEX_KEY s_keytable[] =
|
||||
{ "TO", 2, 2, TO },
|
||||
{ "WHILE", 4, 5, WHILE },
|
||||
{ "WITH", 4, 4, WITH },
|
||||
{ "_PROCREQ_", 9, 9, PROCREQ },
|
||||
{ "AS", 2, 2, AS_TYPE },
|
||||
{ "_FIELD", 4, 6, FIELD },
|
||||
{ "_HB_CLASS", 9, 9, DECLARE_CLASS },
|
||||
{ "_HB_MEMBER", 10, 10, DECLARE_MEMBER }
|
||||
{ "_HB_MEMBER", 10, 10, DECLARE_MEMBER },
|
||||
{ "_PROCREQ_", 9, 9, PROCREQ }
|
||||
};
|
||||
|
||||
#define _AS_ARRAY 1
|
||||
@@ -196,17 +196,17 @@ static const int s_asArrayTypes[] =
|
||||
|
||||
static const HB_LEX_KEY s_typetable[] =
|
||||
{
|
||||
{ "ANYTYPE", 4, 7, _AS_VARIANT },
|
||||
{ "ARRAY", 4, 5, _AS_ARRAY },
|
||||
{ "CODEBLOCK", 4, 9, _AS_BLOCK },
|
||||
{ "STRING", 4, 6, _AS_CHARACTER },
|
||||
{ "CHARACTER", 4, 9, _AS_CHARACTER },
|
||||
{ "CLASS", 4, 5, _AS_CLASS },
|
||||
{ "CODEBLOCK", 4, 9, _AS_BLOCK },
|
||||
{ "DATE", 4, 4, _AS_DATE },
|
||||
{ "LOGICAL", 4, 7, _AS_LOGICAL },
|
||||
{ "NUMERIC", 4, 7, _AS_NUMERIC },
|
||||
{ "OBJECT", 4, 6, _AS_OBJECT },
|
||||
{ "USUAL", 4, 5, _AS_VARIANT },
|
||||
{ "ANYTYPE", 4, 7, _AS_VARIANT }
|
||||
{ "STRING", 4, 6, _AS_CHARACTER },
|
||||
{ "USUAL", 4, 5, _AS_VARIANT }
|
||||
};
|
||||
|
||||
static int hb_comp_asType( PHB_PP_TOKEN pToken, BOOL fArray )
|
||||
|
||||
@@ -2949,34 +2949,22 @@ void hb_compGenPopAliasedVar( char * szVarName,
|
||||
{
|
||||
if( szAlias )
|
||||
{
|
||||
if( szAlias[ 0 ] == 'M' && szAlias[ 1 ] == '\0' )
|
||||
{ /* M->variable */
|
||||
int iLen = strlen( szAlias );
|
||||
if( szAlias[ 0 ] == 'M' && ( iLen == 1 ||
|
||||
( iLen >= 4 && iLen <= 6 &&
|
||||
memcmp( szAlias, "MEMVAR", iLen ) == 0 ) ) )
|
||||
{ /* M->variable or MEMV[A[R]]->variable */
|
||||
hb_compGenVarPCode( HB_P_POPMEMVAR, szVarName, HB_COMP_PARAM );
|
||||
}
|
||||
else if( iLen >= 4 && iLen <= 5 &&
|
||||
memcmp( szAlias, "FIELD", iLen ) == 0 )
|
||||
{ /* FIEL[D]->variable */
|
||||
hb_compGenVarPCode( HB_P_POPFIELD, szVarName, HB_COMP_PARAM );
|
||||
}
|
||||
else
|
||||
{
|
||||
int iCmp = strncmp( szAlias, "MEMVAR", 4 );
|
||||
if( iCmp == 0 )
|
||||
iCmp = strncmp( szAlias, "MEMVAR", strlen( szAlias ) );
|
||||
if( iCmp == 0 )
|
||||
{ /* MEMVAR-> or MEMVA-> or MEMV-> */
|
||||
hb_compGenVarPCode( HB_P_POPMEMVAR, szVarName, HB_COMP_PARAM );
|
||||
}
|
||||
else
|
||||
{ /* field variable */
|
||||
iCmp = strncmp( szAlias, "FIELD", 4 );
|
||||
if( iCmp == 0 )
|
||||
iCmp = strncmp( szAlias, "FIELD", strlen( szAlias ) );
|
||||
if( iCmp == 0 )
|
||||
{ /* FIELD-> */
|
||||
hb_compGenVarPCode( HB_P_POPFIELD, szVarName, HB_COMP_PARAM );
|
||||
}
|
||||
else
|
||||
{ /* database alias */
|
||||
hb_compGenPushSymbol( szAlias, FALSE, TRUE, HB_COMP_PARAM );
|
||||
hb_compGenVarPCode( HB_P_POPALIASEDFIELD, szVarName, HB_COMP_PARAM );
|
||||
}
|
||||
}
|
||||
{ /* database alias */
|
||||
hb_compGenPushSymbol( szAlias, FALSE, TRUE, HB_COMP_PARAM );
|
||||
hb_compGenVarPCode( HB_P_POPALIASEDFIELD, szVarName, HB_COMP_PARAM );
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -3197,38 +3185,26 @@ void hb_compGenPushAliasedVar( char * szVarName,
|
||||
{
|
||||
if( szAlias )
|
||||
{
|
||||
int iLen = strlen( szAlias );
|
||||
/* myalias->var
|
||||
* FIELD->var
|
||||
* MEMVAR->var
|
||||
*/
|
||||
if( szAlias[ 0 ] == 'M' && szAlias[ 1 ] == '\0' )
|
||||
{ /* M->variable */
|
||||
if( szAlias[ 0 ] == 'M' && ( iLen == 1 ||
|
||||
( iLen >= 4 && iLen <= 6 &&
|
||||
memcmp( szAlias, "MEMVAR", iLen ) == 0 ) ) )
|
||||
{ /* M->variable or MEMV[A[R]]->variable */
|
||||
hb_compGenVarPCode( HB_P_PUSHMEMVAR, szVarName, HB_COMP_PARAM );
|
||||
}
|
||||
else if( iLen >= 4 && iLen <= 5 &&
|
||||
memcmp( szAlias, "FIELD", iLen ) == 0 )
|
||||
{ /* FIEL[D]->variable */
|
||||
hb_compGenVarPCode( HB_P_PUSHFIELD, szVarName, HB_COMP_PARAM );
|
||||
}
|
||||
else
|
||||
{
|
||||
int iCmp = strncmp( szAlias, "MEMVAR", 4 );
|
||||
if( iCmp == 0 )
|
||||
iCmp = strncmp( szAlias, "MEMVAR", strlen( szAlias ) );
|
||||
if( iCmp == 0 )
|
||||
{ /* MEMVAR-> or MEMVA-> or MEMV-> */
|
||||
hb_compGenVarPCode( HB_P_PUSHMEMVAR, szVarName, HB_COMP_PARAM );
|
||||
}
|
||||
else
|
||||
{ /* field variable */
|
||||
iCmp = strncmp( szAlias, "FIELD", 4 );
|
||||
if( iCmp == 0 )
|
||||
iCmp = strncmp( szAlias, "FIELD", strlen( szAlias ) );
|
||||
if( iCmp == 0 )
|
||||
{ /* FIELD-> */
|
||||
hb_compGenVarPCode( HB_P_PUSHFIELD, szVarName, HB_COMP_PARAM );
|
||||
}
|
||||
else
|
||||
{ /* database alias */
|
||||
hb_compGenPushSymbol( szAlias, FALSE, TRUE, HB_COMP_PARAM );
|
||||
hb_compGenVarPCode( HB_P_PUSHALIASEDFIELD, szVarName, HB_COMP_PARAM );
|
||||
}
|
||||
}
|
||||
{ /* database alias */
|
||||
hb_compGenPushSymbol( szAlias, FALSE, TRUE, HB_COMP_PARAM );
|
||||
hb_compGenVarPCode( HB_P_PUSHALIASEDFIELD, szVarName, HB_COMP_PARAM );
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -3289,7 +3265,6 @@ void hb_compGenPushFunRef( char * szFunName, HB_COMP_DECL )
|
||||
TRUE, FALSE, HB_COMP_PARAM );
|
||||
}
|
||||
|
||||
|
||||
/* generates the pcode to push a long number on the virtual machine stack */
|
||||
void hb_compGenPushLong( HB_LONG lNumber, HB_COMP_DECL )
|
||||
{
|
||||
@@ -3716,6 +3691,14 @@ BOOL hb_compIsJump( HB_COMP_DECL, PFUNCTION pFunc, ULONG ulPos )
|
||||
ulJumpAddr += HB_PCODE_MKSHORT( &pFunc->pCode[ ulJumpAddr + 1 ] );
|
||||
break;
|
||||
|
||||
/* Jump can be replaced by series of NOOPs or POP and NOOPs
|
||||
* and not stripped yet
|
||||
*/
|
||||
case HB_P_NOOP:
|
||||
case HB_P_POP:
|
||||
ulJumpAddr = ulPos + 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
ulJumpAddr += HB_PCODE_MKINT24( &pFunc->pCode[ ulJumpAddr + 1 ] );
|
||||
break;
|
||||
|
||||
@@ -424,6 +424,89 @@ static HB_FIX_FUNC( hb_p_true )
|
||||
return 1;
|
||||
}
|
||||
|
||||
static HB_FIX_FUNC( hb_p_duplicate )
|
||||
{
|
||||
HB_COMP_DECL = cargo->HB_COMP_PARAM;
|
||||
|
||||
if( cargo->iNestedCodeblock == 0 && HB_COMP_ISSUPPORTED(HB_COMPFLAG_OPTJUMP) )
|
||||
{
|
||||
switch( pFunc->pCode[ lPCodePos + 1 ] )
|
||||
{
|
||||
case HB_P_JUMPTRUEFAR:
|
||||
case HB_P_JUMPFALSEFAR:
|
||||
if( pFunc->pCode[ lPCodePos + 5 ] == HB_P_POP )
|
||||
{
|
||||
BYTE * pAddr = &pFunc->pCode[ lPCodePos + 2 ];
|
||||
LONG lOffset = HB_PCODE_MKINT24( pAddr ), lLastOffset = 0;
|
||||
ULONG ulNewPos = lPCodePos + 1 + lOffset;
|
||||
BOOL fNot = FALSE, fRepeat = TRUE;
|
||||
|
||||
do
|
||||
{
|
||||
if( pFunc->pCode[ ulNewPos ] == HB_P_DUPLICATE )
|
||||
{
|
||||
if( lOffset > 0 )
|
||||
hb_p_duplicate( pFunc, ulNewPos, cargo );
|
||||
}
|
||||
|
||||
if( pFunc->pCode[ ulNewPos ] == HB_P_NOOP )
|
||||
{
|
||||
ulNewPos++;
|
||||
lOffset++;
|
||||
}
|
||||
else if( pFunc->pCode[ ulNewPos ] == HB_P_NOT )
|
||||
{
|
||||
ulNewPos++;
|
||||
lOffset++;
|
||||
fNot = !fNot;
|
||||
}
|
||||
else if( pFunc->pCode[ ulNewPos ] == HB_P_DUPLICATE &&
|
||||
( pFunc->pCode[ ulNewPos + 1 ] == HB_P_JUMPTRUEFAR ||
|
||||
pFunc->pCode[ ulNewPos + 1 ] == HB_P_JUMPFALSEFAR ) )
|
||||
{
|
||||
LONG lJump;
|
||||
if( pFunc->pCode[ ulNewPos + 1 ] != pFunc->pCode[ lPCodePos + 1 ] )
|
||||
fNot = !fNot;
|
||||
lJump = fNot ? 4 : HB_PCODE_MKINT24( &pFunc->pCode[ ulNewPos + 2 ] );
|
||||
lOffset += lJump + 1;
|
||||
ulNewPos = lPCodePos + 1 + lOffset;
|
||||
fRepeat = lJump > 0;
|
||||
}
|
||||
else
|
||||
fRepeat = FALSE;
|
||||
|
||||
if( !fNot )
|
||||
lLastOffset = lOffset;
|
||||
}
|
||||
while( fRepeat );
|
||||
|
||||
if( ( pFunc->pCode[ ulNewPos ] == HB_P_JUMPTRUEFAR ||
|
||||
pFunc->pCode[ ulNewPos ] == HB_P_JUMPFALSEFAR ) &&
|
||||
!hb_compIsJump( cargo->HB_COMP_PARAM, pFunc, lPCodePos + 1 ) &&
|
||||
!hb_compIsJump( cargo->HB_COMP_PARAM, pFunc, lPCodePos + 5 ) )
|
||||
{
|
||||
if( pFunc->pCode[ ulNewPos ] != pFunc->pCode[ lPCodePos + 1 ] )
|
||||
fNot = !fNot;
|
||||
if( fNot )
|
||||
lOffset += 4;
|
||||
else
|
||||
lOffset += HB_PCODE_MKINT24( &pFunc->pCode[ ulNewPos + 1 ] );
|
||||
|
||||
HB_PUT_LE_UINT24( pAddr, lOffset );
|
||||
hb_compNOOPfill( pFunc, lPCodePos, 1, FALSE, FALSE );
|
||||
hb_compNOOPfill( pFunc, lPCodePos + 5, 1, FALSE, FALSE );
|
||||
}
|
||||
else if( lLastOffset )
|
||||
{
|
||||
HB_PUT_LE_UINT24( pAddr, lLastOffset );
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static HB_FIX_FUNC( hb_p_not )
|
||||
{
|
||||
if( cargo->iNestedCodeblock == 0 )
|
||||
@@ -453,6 +536,41 @@ static HB_FIX_FUNC( hb_p_not )
|
||||
case HB_P_JUMPFALSEFAR:
|
||||
opcode = HB_P_JUMPTRUEFAR;
|
||||
break;
|
||||
/* This optimization will be enabled in the future in a little bit differ form */
|
||||
#if 0
|
||||
case HB_P_DUPLICATE:
|
||||
if( ( pFunc->pCode[ lPCodePos + 2 ] == HB_P_JUMPTRUEFAR ||
|
||||
pFunc->pCode[ lPCodePos + 2 ] == HB_P_JUMPFALSEFAR ) &&
|
||||
pFunc->pCode[ lPCodePos + 6 ] == HB_P_POP )
|
||||
{
|
||||
BYTE * pAddr = &pFunc->pCode[ lPCodePos + 3 ];
|
||||
LONG lOffset = HB_PCODE_MKINT24( pAddr );
|
||||
|
||||
if( lOffset > 0 )
|
||||
{
|
||||
hb_p_duplicate( pFunc, lPCodePos + 1, cargo );
|
||||
lOffset = HB_PCODE_MKINT24( pAddr );
|
||||
}
|
||||
|
||||
if( ( pFunc->pCode[ lPCodePos + 1 ] == HB_P_NOT ||
|
||||
( pFunc->pCode[ lPCodePos + 1 ] == HB_P_DUPLICATE &&
|
||||
pFunc->pCode[ lPCodePos + lOffset + 2 ] == HB_P_NOT ) ) &&
|
||||
! hb_compIsJump( cargo->HB_COMP_PARAM, pFunc, lPCodePos + 1 ) )
|
||||
{
|
||||
hb_compNOOPfill( pFunc, lPCodePos, 1, FALSE, FALSE );
|
||||
if( pFunc->pCode[ lPCodePos + 2 ] == HB_P_JUMPTRUEFAR )
|
||||
pFunc->pCode[ lPCodePos + 2 ] = HB_P_JUMPFALSEFAR;
|
||||
else
|
||||
pFunc->pCode[ lPCodePos + 2 ] = HB_P_JUMPTRUEFAR;
|
||||
if( pFunc->pCode[ lPCodePos + 1 ] == HB_P_DUPLICATE )
|
||||
{
|
||||
++lOffset;
|
||||
HB_PUT_LE_UINT24( pAddr, lOffset );
|
||||
}
|
||||
}
|
||||
}
|
||||
/* no break; */
|
||||
#endif
|
||||
default:
|
||||
opcode = HB_P_LAST_PCODE;
|
||||
break;
|
||||
@@ -471,53 +589,6 @@ static HB_FIX_FUNC( hb_p_not )
|
||||
return 1;
|
||||
}
|
||||
|
||||
static HB_FIX_FUNC( hb_p_duplicate )
|
||||
{
|
||||
HB_COMP_DECL = cargo->HB_COMP_PARAM;
|
||||
|
||||
if( cargo->iNestedCodeblock == 0 && HB_COMP_ISSUPPORTED(HB_COMPFLAG_OPTJUMP) )
|
||||
{
|
||||
switch( pFunc->pCode[ lPCodePos + 1 ] )
|
||||
{
|
||||
case HB_P_JUMPTRUEFAR:
|
||||
case HB_P_JUMPFALSEFAR:
|
||||
if( pFunc->pCode[ lPCodePos + 5 ] == HB_P_POP )
|
||||
{
|
||||
BYTE * pAddr = &pFunc->pCode[ lPCodePos + 2 ];
|
||||
LONG lOffset = HB_PCODE_MKINT24( pAddr );
|
||||
ULONG ulNewPos = lPCodePos + 1 + lOffset;
|
||||
|
||||
if( lOffset > 0 && pFunc->pCode[ ulNewPos ] == HB_P_DUPLICATE )
|
||||
{
|
||||
hb_p_duplicate( pFunc, ulNewPos, cargo );
|
||||
if( pFunc->pCode[ ulNewPos ] == HB_P_NOOP )
|
||||
{
|
||||
ulNewPos++;
|
||||
lOffset++;
|
||||
}
|
||||
}
|
||||
|
||||
if( ( pFunc->pCode[ ulNewPos ] == HB_P_JUMPTRUEFAR ||
|
||||
pFunc->pCode[ ulNewPos ] == HB_P_JUMPFALSEFAR ) &&
|
||||
!hb_compIsJump( cargo->HB_COMP_PARAM, pFunc, lPCodePos + 1 ) &&
|
||||
!hb_compIsJump( cargo->HB_COMP_PARAM, pFunc, lPCodePos + 5 ) )
|
||||
{
|
||||
if( pFunc->pCode[ ulNewPos ] == pFunc->pCode[ lPCodePos + 1 ] )
|
||||
lOffset += HB_PCODE_MKINT24( &pFunc->pCode[ ulNewPos + 1 ] );
|
||||
else
|
||||
lOffset += 4;
|
||||
|
||||
HB_PUT_LE_UINT24( pAddr, lOffset );
|
||||
hb_compNOOPfill( pFunc, lPCodePos, 1, FALSE, FALSE );
|
||||
hb_compNOOPfill( pFunc, lPCodePos + 5, 1, FALSE, FALSE );
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static HB_FIX_FUNC( hb_p_jumpfar )
|
||||
{
|
||||
HB_COMP_DECL = cargo->HB_COMP_PARAM;
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
#include "hbcomp.h"
|
||||
|
||||
/* NOTE: iMinParam = -1, means no checking
|
||||
/* NOTE: iMinParam = -1, means no lower limit
|
||||
* iMaxParam = -1, means no upper limit
|
||||
*/
|
||||
|
||||
@@ -37,8 +37,11 @@ typedef struct
|
||||
char * cFuncName; /* function name */
|
||||
int iMinParam; /* min no of parms it needs */
|
||||
int iMaxParam; /* max no of parms need */
|
||||
} HB_FUNCINFO, * HB_PFUNCINFO;
|
||||
} HB_FUNCINFO, * PHB_FUNCINFO;
|
||||
|
||||
|
||||
/* NOTE: THIS TABLE MUST BE SORTED ALPHABETICALLY
|
||||
*/
|
||||
static HB_FUNCINFO hb_StdFunc[] =
|
||||
{
|
||||
{ "AADD" , 2, 2 },
|
||||
@@ -111,56 +114,64 @@ static HB_FUNCINFO hb_StdFunc[] =
|
||||
{ "VAL" , 1, 1 },
|
||||
{ "VALTYPE" , 1, 1 },
|
||||
{ "WORD" , 1, 1 },
|
||||
{ "YEAR" , 1, 1 },
|
||||
{ 0 , 0, 0 }
|
||||
{ "YEAR" , 1, 1 }
|
||||
};
|
||||
|
||||
#define HB_STD_FUNCOUNT sizeof( hb_StdFunc ) / sizeof( HB_FUNCINFO )
|
||||
|
||||
BOOL hb_compFunCallCheck( HB_COMP_DECL, char * szFuncCall, int iArgs )
|
||||
{
|
||||
HB_FUNCINFO * f = hb_StdFunc;
|
||||
int i = 0;
|
||||
int iPos = -1;
|
||||
int iCmp;
|
||||
unsigned int uiFirst = 0, uiLast = HB_STD_FUNCOUNT - 1, uiMiddle;
|
||||
int iLen = ( int ) strlen( szFuncCall ), iCmp;
|
||||
|
||||
while( f[ i ].cFuncName )
|
||||
/* Respect 4 or more letters shortcuts
|
||||
* SECO() is not allowed because of Clipper function SECONDS()
|
||||
* however SECO32() is a valid name.
|
||||
*/
|
||||
if( iLen < 4 )
|
||||
iLen = 4;
|
||||
do
|
||||
{
|
||||
iCmp = strncmp( szFuncCall, f[ i ].cFuncName, 4 );
|
||||
if( iCmp == 0 )
|
||||
iCmp = strncmp( szFuncCall, f[ i ].cFuncName, strlen( szFuncCall ) );
|
||||
if( iCmp == 0 )
|
||||
{
|
||||
iPos = i;
|
||||
break;
|
||||
}
|
||||
uiMiddle = ( uiFirst + uiLast ) >> 1;
|
||||
iCmp = strncmp( szFuncCall, hb_StdFunc[ uiMiddle ].cFuncName, iLen );
|
||||
if( iCmp <= 0 )
|
||||
uiLast = uiMiddle;
|
||||
else
|
||||
++i;
|
||||
uiFirst = uiMiddle + 1;
|
||||
}
|
||||
while( uiFirst < uiLast );
|
||||
|
||||
if( iPos >= 0 && ( f[ iPos ].iMinParam != -1 ) )
|
||||
if( uiFirst != uiMiddle )
|
||||
iCmp = strncmp( szFuncCall, hb_StdFunc[ uiFirst ].cFuncName, iLen );
|
||||
|
||||
if( iCmp == 0 )
|
||||
{
|
||||
if( iArgs < f[ iPos ].iMinParam || ( f[ iPos ].iMaxParam != -1 && iArgs > f[ iPos ].iMaxParam ) )
|
||||
{
|
||||
if( HB_COMP_ISSUPPORTED( HB_COMPFLAG_HARBOUR ) )
|
||||
{
|
||||
char szMsg[ 40 ];
|
||||
PHB_FUNCINFO pFunc = &hb_StdFunc[ uiFirst ];
|
||||
|
||||
if( f[ iPos ].iMaxParam == -1 )
|
||||
snprintf( szMsg, sizeof( szMsg ), "\nPassed: %i, expected: at least %i", iArgs, f[ iPos ].iMinParam );
|
||||
else if( f[ iPos ].iMinParam == f[ iPos ].iMaxParam )
|
||||
snprintf( szMsg, sizeof( szMsg ), "\nPassed: %i, expected: %i", iArgs, f[ iPos ].iMinParam );
|
||||
if( ( pFunc->iMinParam != -1 && iArgs < pFunc->iMinParam ) ||
|
||||
( pFunc->iMaxParam != -1 && iArgs > pFunc->iMaxParam ) )
|
||||
{
|
||||
char szMsg[ 64 ];
|
||||
|
||||
if( HB_COMP_ISSUPPORTED( HB_COMPFLAG_HARBOUR ) )
|
||||
{
|
||||
if( pFunc->iMinParam == pFunc->iMaxParam )
|
||||
snprintf( szMsg, sizeof( szMsg ), "\nPassed: %i, expected: %i", iArgs, pFunc->iMinParam );
|
||||
else if( pFunc->iMaxParam == -1 )
|
||||
snprintf( szMsg, sizeof( szMsg ), "\nPassed: %i, expected at least: %i", iArgs, pFunc->iMinParam );
|
||||
else if( pFunc->iMinParam == -1 )
|
||||
snprintf( szMsg, sizeof( szMsg ), "\nPassed: %i, expected less then: %i", iArgs, pFunc->iMaxParam );
|
||||
else
|
||||
snprintf( szMsg, sizeof( szMsg ), "\nPassed: %i, expected from: %i to: %i", iArgs, pFunc->iMinParam, pFunc->iMaxParam );
|
||||
}
|
||||
else
|
||||
snprintf( szMsg, sizeof( szMsg ), "\nPassed: %i, expected: %i - %i", iArgs, f[ iPos ].iMinParam, f[ iPos ].iMaxParam );
|
||||
szMsg[ 0 ] = '\0';
|
||||
|
||||
hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E', HB_COMP_ERR_CHECKING_ARGS, szFuncCall, szMsg );
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Clipper way */
|
||||
hb_compGenError( HB_COMP_PARAM, hb_comp_szErrors, 'E', HB_COMP_ERR_CHECKING_ARGS, szFuncCall, NULL );
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -60,44 +60,50 @@ HB_FUNC( MAX )
|
||||
PHB_ITEM p1 = hb_param( 1, HB_IT_ANY );
|
||||
PHB_ITEM p2 = hb_param( 2, HB_IT_ANY );
|
||||
|
||||
if( HB_IS_NUMINT( p1 ) && HB_IS_NUMINT( p2 ) )
|
||||
if( p1 && p2 )
|
||||
{
|
||||
HB_LONG l1 = hb_itemGetNInt( p1 );
|
||||
HB_LONG l2 = hb_itemGetNInt( p2 );
|
||||
|
||||
hb_retnint( l1 >= l2 ? l1 : l2 );
|
||||
if( HB_IS_NUMINT( p1 ) && HB_IS_NUMINT( p2 ) )
|
||||
{
|
||||
HB_LONG l1 = hb_itemGetNInt( p1 );
|
||||
HB_LONG l2 = hb_itemGetNInt( p2 );
|
||||
|
||||
hb_retnint( l1 >= l2 ? l1 : l2 );
|
||||
return;
|
||||
}
|
||||
else if( HB_IS_NUMERIC( p1 ) && HB_IS_NUMERIC( p2 ) )
|
||||
{
|
||||
double d1 = hb_itemGetND( p1 );
|
||||
double d2 = hb_itemGetND( p2 );
|
||||
|
||||
int iDec1;
|
||||
int iDec2;
|
||||
|
||||
hb_itemGetNLen( p1, NULL, &iDec1 );
|
||||
hb_itemGetNLen( p2, NULL, &iDec2 );
|
||||
|
||||
if( d1 >= d2 )
|
||||
hb_retndlen( d1, 0, iDec1 );
|
||||
else
|
||||
hb_retndlen( d2, 0, iDec2 );
|
||||
return;
|
||||
}
|
||||
else if( HB_IS_LOGICAL( p1 ) && HB_IS_LOGICAL( p2 ) )
|
||||
{
|
||||
BOOL b1 = hb_itemGetL( p1 );
|
||||
BOOL b2 = hb_itemGetL( p2 );
|
||||
|
||||
hb_retl( b1 >= b2 ? b1 : b2 );
|
||||
return;
|
||||
}
|
||||
else if( HB_IS_DATE( p1 ) && HB_IS_DATE( p2 ) )
|
||||
{
|
||||
char szDate[ 9 ];
|
||||
|
||||
hb_retds( hb_itemGetDL( p1 ) >= hb_itemGetDL( p2 ) ? hb_pardsbuff( szDate, 1 ) : hb_pardsbuff( szDate, 2 ) );
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if( HB_IS_NUMERIC( p1 ) && HB_IS_NUMERIC( p2 ) )
|
||||
{
|
||||
double d1 = hb_itemGetND( p1 );
|
||||
double d2 = hb_itemGetND( p2 );
|
||||
|
||||
int iDec1;
|
||||
int iDec2;
|
||||
|
||||
hb_itemGetNLen( p1, NULL, &iDec1 );
|
||||
hb_itemGetNLen( p2, NULL, &iDec2 );
|
||||
|
||||
if( d1 >= d2 )
|
||||
hb_retndlen( d1, 0, iDec1 );
|
||||
else
|
||||
hb_retndlen( d2, 0, iDec2 );
|
||||
}
|
||||
else if( HB_IS_LOGICAL( p1 ) && HB_IS_LOGICAL( p2 ) )
|
||||
{
|
||||
BOOL b1 = hb_itemGetL( p1 );
|
||||
BOOL b2 = hb_itemGetL( p2 );
|
||||
|
||||
hb_retl( b1 >= b2 ? b1 : b2 );
|
||||
}
|
||||
else if( HB_IS_DATE( p1 ) && HB_IS_DATE( p2 ) )
|
||||
{
|
||||
char szDate[ 9 ];
|
||||
|
||||
hb_retds( hb_itemGetDL( p1 ) >= hb_itemGetDL( p2 ) ? hb_pardsbuff( szDate, 1 ) : hb_pardsbuff( szDate, 2 ) );
|
||||
}
|
||||
else
|
||||
hb_errRT_BASE_SubstR( EG_ARG, 1093, NULL, "MAX", 2, hb_paramError( 1 ), hb_paramError( 2 ) );
|
||||
hb_errRT_BASE_SubstR( EG_ARG, 1093, NULL, "MAX", 2, hb_paramError( 1 ), hb_paramError( 2 ) );
|
||||
}
|
||||
|
||||
/* returns the minimum of two date or numerics */
|
||||
@@ -106,43 +112,50 @@ HB_FUNC( MIN )
|
||||
PHB_ITEM p1 = hb_param( 1, HB_IT_ANY );
|
||||
PHB_ITEM p2 = hb_param( 2, HB_IT_ANY );
|
||||
|
||||
if( HB_IS_NUMINT( p1 ) && HB_IS_NUMINT( p2 ) )
|
||||
if( p1 && p2 )
|
||||
{
|
||||
HB_LONG l1 = hb_itemGetNInt( p1 );
|
||||
HB_LONG l2 = hb_itemGetNInt( p2 );
|
||||
|
||||
hb_retnint( l1 <= l2 ? l1 : l2 );
|
||||
if( HB_IS_NUMINT( p1 ) && HB_IS_NUMINT( p2 ) )
|
||||
{
|
||||
HB_LONG l1 = hb_itemGetNInt( p1 );
|
||||
HB_LONG l2 = hb_itemGetNInt( p2 );
|
||||
|
||||
hb_retnint( l1 <= l2 ? l1 : l2 );
|
||||
return;
|
||||
}
|
||||
else if( HB_IS_NUMERIC( p1 ) && HB_IS_NUMERIC( p2 ) )
|
||||
{
|
||||
double d1 = hb_itemGetND( p1 );
|
||||
double d2 = hb_itemGetND( p2 );
|
||||
|
||||
int iDec1;
|
||||
int iDec2;
|
||||
|
||||
hb_itemGetNLen( p1, NULL, &iDec1 );
|
||||
hb_itemGetNLen( p2, NULL, &iDec2 );
|
||||
|
||||
if( d1 <= d2 )
|
||||
hb_retndlen( d1, 0, iDec1 );
|
||||
else
|
||||
hb_retndlen( d2, 0, iDec2 );
|
||||
return;
|
||||
}
|
||||
else if( HB_IS_LOGICAL( p1 ) && HB_IS_LOGICAL( p2 ) )
|
||||
{
|
||||
BOOL b1 = hb_itemGetL( p1 );
|
||||
BOOL b2 = hb_itemGetL( p2 );
|
||||
|
||||
hb_retl( b1 <= b2 ? b1 : b2 );
|
||||
return;
|
||||
}
|
||||
else if( HB_IS_DATE( p1 ) && HB_IS_DATE( p2 ) )
|
||||
{
|
||||
char szDate[ 9 ];
|
||||
|
||||
hb_retds( hb_itemGetDL( p1 ) <= hb_itemGetDL( p2 ) ? hb_pardsbuff( szDate, 1 ) : hb_pardsbuff( szDate, 2 ) );
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if( HB_IS_NUMERIC( p1 ) && HB_IS_NUMERIC( p2 ) )
|
||||
{
|
||||
double d1 = hb_itemGetND( p1 );
|
||||
double d2 = hb_itemGetND( p2 );
|
||||
|
||||
int iDec1;
|
||||
int iDec2;
|
||||
|
||||
hb_itemGetNLen( p1, NULL, &iDec1 );
|
||||
hb_itemGetNLen( p2, NULL, &iDec2 );
|
||||
|
||||
if( d1 <= d2 )
|
||||
hb_retndlen( d1, 0, iDec1 );
|
||||
else
|
||||
hb_retndlen( d2, 0, iDec2 );
|
||||
}
|
||||
else if( HB_IS_LOGICAL( p1 ) && HB_IS_LOGICAL( p2 ) )
|
||||
{
|
||||
BOOL b1 = hb_itemGetL( p1 );
|
||||
BOOL b2 = hb_itemGetL( p2 );
|
||||
|
||||
hb_retl( b1 <= b2 ? b1 : b2 );
|
||||
}
|
||||
else if( HB_IS_DATE( p1 ) && HB_IS_DATE( p2 ) )
|
||||
{
|
||||
char szDate[ 9 ];
|
||||
|
||||
hb_retds( hb_itemGetDL( p1 ) <= hb_itemGetDL( p2 ) ? hb_pardsbuff( szDate, 1 ) : hb_pardsbuff( szDate, 2 ) );
|
||||
}
|
||||
else
|
||||
hb_errRT_BASE_SubstR( EG_ARG, 1092, NULL, "MIN", 2, hb_paramError( 1 ), hb_paramError( 2 ) );
|
||||
hb_errRT_BASE_SubstR( EG_ARG, 1092, NULL, "MIN", 2, hb_paramError( 1 ), hb_paramError( 2 ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -1615,7 +1615,8 @@ HB_EXPORT int hb_itemStrCmp( PHB_ITEM pFirst, PHB_ITEM pSecond, BOOL bForceExact
|
||||
if( ulMinLen )
|
||||
{
|
||||
if( hb_cdp_page->lSort )
|
||||
iRet = hb_cdpcmp( szFirst,ulLenFirst,szSecond,ulLenSecond,hb_cdp_page,hb_set.HB_SET_EXACT || bForceExact );
|
||||
iRet = hb_cdpcmp( szFirst, ulLenFirst, szSecond, ulLenSecond,
|
||||
hb_cdp_page, hb_set.HB_SET_EXACT || bForceExact );
|
||||
else
|
||||
{
|
||||
do
|
||||
@@ -1630,11 +1631,11 @@ HB_EXPORT int hb_itemStrCmp( PHB_ITEM pFirst, PHB_ITEM pSecond, BOOL bForceExact
|
||||
}
|
||||
while( --ulMinLen );
|
||||
|
||||
if( hb_set.HB_SET_EXACT || bForceExact || ulLenSecond > ulLenFirst )
|
||||
/* If equal and length is different ! */
|
||||
if( !iRet && ulLenFirst != ulLenSecond )
|
||||
{
|
||||
/* Force an exact comparison */
|
||||
if( !iRet && ulLenFirst != ulLenSecond )
|
||||
/* If length is different ! */
|
||||
/* Force an exact comparison? */
|
||||
if( hb_set.HB_SET_EXACT || bForceExact || ulLenSecond > ulLenFirst )
|
||||
iRet = ( ulLenFirst < ulLenSecond ) ? -1 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user