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:
Przemyslaw Czerpak
2007-01-05 07:41:20 +00:00
parent 647e9281bf
commit 9d263b1141
12 changed files with 456 additions and 389 deletions

View File

@@ -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

View File

@@ -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 */

View File

@@ -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 );
}

View File

@@ -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:

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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 )

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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 ) );
}

View File

@@ -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;
}
}