2006-02-14 11:40 UTC+0100 Ryszard Glab <rglab@imid.med.pl>

* include/hbapiitm.h
   * include/hbcomp.h
   * include/hbexpra.c
   * include/hbexprb.c
   * include/hbexprc.c
   * include/hbexprop.h
   * include/hbpcode.h
   * source/common/expropt1.c
   * source/common/hbfsapi.c
   * source/compiler/expropta.c
   * source/compiler/exproptb.c
   * source/compiler/exproptc.c
   * source/compiler/genc.c
   * source/compiler/harbour.c
   * source/compiler/harbour.l
   * source/compiler/harbour.y
   * source/compiler/hbdead.c
   * source/compiler/hbfix.c
   * source/compiler/hbpcode.c
   * source/compiler/hbstripl.c
   * source/macro/macro.y
   * source/macro/macroa.c
   * source/macro/macrob.c
   * source/macro/macroc.c
   * source/pp/ppcore.c
   * source/vm/hvm.c
   * source/vm/itemapi.c
      * fixed many more memory leaks in the compiler
        (the Harbour code compiles itself with no memory leaks).
        However there are still leaks when the compiler aborts
        compilation due to errors.
      + added optimalization of '+=' '-=' '*=' '/=' operators
      + added hb_itemGetNDDec(),
        hb_itemPutHBLong(),
        hb_itemPutNumType()
        borrowed from xHarbour

      NOTE: new pcodes:
      HB_[PLUS|MINUS|MULT|DIV]EQ
      HB_[PLUS|MINUS|MULT|DIV]EQPOP
      recompile all sources.
This commit is contained in:
Ryszard Glab
2006-02-14 10:26:58 +00:00
parent e13b1db80e
commit 6f0e36f665
29 changed files with 901 additions and 263 deletions

View File

@@ -8,6 +8,49 @@
2002-12-01 13:30 UTC+0100 Foo Bar <foo.bar@foobar.org>
*/
* fixed <-x-> match marker
2006-02-14 11:40 UTC+0100 Ryszard Glab <rglab@imid.med.pl>
* include/hbapiitm.h
* include/hbcomp.h
* include/hbexpra.c
* include/hbexprb.c
* include/hbexprc.c
* include/hbexprop.h
* include/hbpcode.h
* source/common/expropt1.c
* source/common/hbfsapi.c
* source/compiler/expropta.c
* source/compiler/exproptb.c
* source/compiler/exproptc.c
* source/compiler/genc.c
* source/compiler/harbour.c
* source/compiler/harbour.l
* source/compiler/harbour.y
* source/compiler/hbdead.c
* source/compiler/hbfix.c
* source/compiler/hbpcode.c
* source/compiler/hbstripl.c
* source/macro/macro.y
* source/macro/macroa.c
* source/macro/macrob.c
* source/macro/macroc.c
* source/pp/ppcore.c
* source/vm/hvm.c
* source/vm/itemapi.c
* fixed many more memory leaks in the compiler
(the Harbour code compiles itself with no memory leaks).
However there are still leaks when the compiler aborts
compilation due to errors.
+ added optimalization of '+=' '-=' '*=' '/=' operators
+ added hb_itemGetNDDec(),
hb_itemPutHBLong(),
hb_itemPutNumType()
borrowed from xHarbour
NOTE: new pcodes:
HB_[PLUS|MINUS|MULT|DIV]EQ
HB_[PLUS|MINUS|MULT|DIV]EQPOP
recompile all sources.
2006-02-12 14:33 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl)
* harbour/include/hbapi.h
* harbour/include/hbdefs.h

View File

@@ -85,6 +85,7 @@ extern HB_EXPORT char * hb_itemGetDS ( PHB_ITEM pItem, char * szDate );
extern HB_EXPORT long hb_itemGetDL ( PHB_ITEM pItem );
extern HB_EXPORT BOOL hb_itemGetL ( PHB_ITEM pItem );
extern HB_EXPORT double hb_itemGetND ( PHB_ITEM pItem );
extern HB_EXPORT double hb_itemGetNDDec ( PHB_ITEM pItem, int * piDec );
extern HB_EXPORT int hb_itemGetNI ( PHB_ITEM pItem );
extern HB_EXPORT long hb_itemGetNL ( PHB_ITEM pItem );
extern HB_EXPORT HB_LONG hb_itemGetNInt ( PHB_ITEM pItem );
@@ -103,6 +104,7 @@ extern HB_EXPORT void hb_itemSetCMemo ( PHB_ITEM pItem );
extern HB_EXPORT PHB_ITEM hb_itemPutD ( PHB_ITEM pItem, int iYear, int iMonth, int iDay );
extern HB_EXPORT PHB_ITEM hb_itemPutDS ( PHB_ITEM pItem, const char * szDate );
extern HB_EXPORT PHB_ITEM hb_itemPutDL ( PHB_ITEM pItem, long lJulian );
extern HB_EXPORT PHB_ITEM hb_itemPutHBLong( PHB_ITEM pItem, HB_LONG lNumber );
extern HB_EXPORT PHB_ITEM hb_itemPutL ( PHB_ITEM pItem, BOOL bValue );
extern HB_EXPORT PHB_ITEM hb_itemPutND ( PHB_ITEM pItem, double dNumber );
extern HB_EXPORT PHB_ITEM hb_itemPutNI ( PHB_ITEM pItem, int iNumber );
@@ -111,8 +113,10 @@ extern HB_EXPORT PHB_ITEM hb_itemPutNInt ( PHB_ITEM pItem, HB_LONG lNumber );
extern HB_EXPORT PHB_ITEM hb_itemPutNIntLen( PHB_ITEM pItem, HB_LONG lNumber, int iWidth );
extern HB_EXPORT PHB_ITEM hb_itemPutNLen ( PHB_ITEM pItem, double dNumber, int iWidth, int iDec );
extern HB_EXPORT PHB_ITEM hb_itemPutNDLen ( PHB_ITEM pItem, double dNumber, int iWidth, int iDec );
extern HB_EXPORT PHB_ITEM hb_itemPutNDDec ( PHB_ITEM pItem, double dNumber, int iDec );
extern HB_EXPORT PHB_ITEM hb_itemPutNILen ( PHB_ITEM pItem, int iNumber, int iWidth );
extern HB_EXPORT PHB_ITEM hb_itemPutNLLen ( PHB_ITEM pItem, long lNumber, int iWidth );
extern HB_EXPORT PHB_ITEM hb_itemPutNumType( PHB_ITEM pItem, double dNumber, int iDec, int iType1, int iType2 );
extern HB_EXPORT PHB_ITEM hb_itemPutPtr ( PHB_ITEM pItem, void * pValue );
extern HB_EXPORT BOOL hb_itemRelease ( PHB_ITEM pItem );
extern HB_EXPORT PHB_ITEM hb_itemReturn ( PHB_ITEM pItem );

View File

@@ -464,6 +464,7 @@ extern void hb_compCodeTraceMarkDead( PFUNCTION pFunc );
extern int hb_compYACCMain( char * szName );
#endif
extern BOOL hb_compInclude( char * szFileName, HB_PATHNAMES * pSearchPath ); /* end #include support */
extern void hb_compParserStop( void ); /* cleanup the bison parser */
extern char * hb_comp_buffer; /* yacc input buffer */

View File

@@ -381,10 +381,20 @@ HB_EXPR_PTR hb_compExprNewFunCall( HB_EXPR_PTR pName, HB_EXPR_PTR pParms )
if( ( strcmp( "EVAL", pName->value.asSymbol ) == 0 ) && iCount )
{
HB_EXPR_PTR pEval;
/* Optimize Eval( bBlock, [ArgList] ) to: bBlock:Eval( [ArgList] ) */
return hb_compExprNewMethodCall( hb_compExprNewSend( pParms->value.asList.pExprList,
hb_strdup( "EVAL" ) ),
hb_compExprNewArgList( pParms->value.asList.pExprList->pNext ) );
pEval = hb_compExprNewMethodCall(
#ifndef HB_MACRO_SUPPORT
hb_compExprNewSend( pParms->value.asList.pExprList, hb_compIdentifierNew( "EVAL", TRUE ) ),
#else
hb_compExprNewSend( pParms->value.asList.pExprList, "EVAL" ),
#endif
hb_compExprNewArgList( pParms->value.asList.pExprList->pNext ) );
pParms->value.asList.pExprList = NULL;
HB_EXPR_PCODE1( hb_compExprDelete, pParms );
HB_EXPR_PCODE1( hb_compExprDelete, pName );
return pEval;
}
else if( HB_COMP_ISSUPPORTED( HB_COMPFLAG_XBASE ) &&
(( strcmp( "__DBLIST", pName->value.asSymbol ) == 0 ) && iCount >= 10) )
@@ -484,6 +494,7 @@ HB_EXPR_PTR hb_compExprNewFunCall( HB_EXPR_PTR pName, HB_EXPR_PTR pParms )
if( pArg->ExprType == HB_ET_ARRAYAT )
{
HB_EXPR_PTR pIndex, pVar;
HB_EXPR_PTR pBase;
#ifdef HB_MACRO_SUPPORT
HB_XFREE( pName->value.asSymbol );
@@ -495,6 +506,7 @@ HB_EXPR_PTR hb_compExprNewFunCall( HB_EXPR_PTR pName, HB_EXPR_PTR pParms )
* ((a->[ i ])->[ j ])
*/
pVar = HB_EXPR_USE( pArg->value.asList.pExprList, HB_EA_REDUCE );
pBase = pVar;
pIndex = HB_EXPR_USE( pArg->value.asList.pIndex, HB_EA_REDUCE );
pIndex->pNext = NULL;
while( pVar->ExprType == HB_ET_ARRAYAT )
@@ -532,7 +544,7 @@ HB_EXPR_PTR hb_compExprNewFunCall( HB_EXPR_PTR pName, HB_EXPR_PTR pParms )
hb_compExprClear( pArg );
/* Create an array with index elements
*/
pIndex = hb_compExprNewArray( hb_compExprNewList( pIndex ) );
pIndex = HB_EXPR_PCODE1(hb_compExprNewArray, hb_compExprNewList( pIndex ) );
/* The array with index elements have to be the sixth argument
* of __GETA() call
*/
@@ -570,6 +582,8 @@ HB_EXPR_PTR hb_compExprNewFunCall( HB_EXPR_PTR pName, HB_EXPR_PTR pParms )
}
}
}
pBase->value.asList.pExprList = NULL;
hb_compExprClear( pBase );
}
else if( pArg->ExprType == HB_ET_MACRO )
{
@@ -760,6 +774,50 @@ HB_EXPR_PTR hb_compExprNewString( char *szValue )
return pExpr;
}
/* Creates a new literal array { item1, item2, ... itemN }
* 'pArrList' is a list of array elements
*/
#ifdef HB_MACRO_SUPPORT
HB_EXPR_PTR hb_compExprNewArray( HB_EXPR_PTR pArrList, HB_MACRO_DECL )
#else
HB_EXPR_PTR hb_compExprNewArray( HB_EXPR_PTR pArrList )
#endif
{
HB_EXPR_PTR pExpr;
HB_TRACE(HB_TR_DEBUG, ("hb_compExprNewArray()"));
pArrList->ExprType = HB_ET_ARRAY; /* change type from ET_LIST */
pArrList->ValType = HB_EV_ARRAY;
pArrList->ulLength = 0;
pExpr = pArrList->value.asList.pExprList; /* get first element on the list */
/* Now we need to replace all EO_NONE expressions with ET_NIL expressions
* If EO_NONE is the first expression and there is no more expressions
* then it is an empty array {} and ET_NIL cannot be used
*/
if( pExpr->ExprType == HB_ET_NONE && pExpr->pNext == NULL )
{
pArrList->value.asList.pExprList = NULL;
HB_EXPR_PCODE1( hb_compExprDelete, pExpr );
}
else
{
/* there are at least one non-empty element specified
*/
while( pExpr )
{
/* if empty element was specified replace it with NIL value */
if( pExpr->ExprType == HB_ET_NONE )
pExpr->ExprType = HB_ET_NIL;
pExpr = pExpr->pNext;
++pArrList->ulLength;
}
}
pArrList->value.asList.pIndex = NULL;
return pArrList;
}
/* Creates new array access expression
* pArray[ pIndex ]
@@ -1054,11 +1112,12 @@ HB_EXPR_PTR hb_compExprSetGetBlock( HB_EXPR_PTR pExpr )
/* create {|var| expression
* NOTE: this is not a valid variable name so there will be no collisions
*/
pIIF =hb_compExprNewVar( hb_strdup("~1") );
/* create var==NIL */
#ifdef HB_MACRO_SUPPORT
pIIF =hb_compExprNewVar( hb_strdup("~1") );
pIIF = hb_compExprSetOperand( hb_compExprNewEQ( pIIF ), hb_compExprNewNil(), HB_MACRO_PARAM );
#else
pIIF =hb_compExprNewVar( hb_compIdentifierNew("~1",TRUE) );
pIIF = hb_compExprSetOperand( hb_compExprNewEQ( pIIF ), hb_compExprNewNil() );
#endif
/* create ( var==NIL, */
@@ -1066,7 +1125,11 @@ HB_EXPR_PTR hb_compExprSetGetBlock( HB_EXPR_PTR pExpr )
/* create ( var==NIL, <pExpr>, */
pIIF = hb_compExprAddListExpr( pIIF, pExpr );
/* create var */
#ifdef HB_MACRO_SUPPORT
pSet =hb_compExprNewVar( hb_strdup("~1") );
#else
pSet =hb_compExprNewVar( hb_compIdentifierNew("~1",TRUE) );
#endif
/* create <pExpr>:=var */
pSet = hb_compExprAssign( hb_compExprClone( pExpr ), pSet );
/* create ( var==nil, <pExpr>, <pExpr>:=var ) */

View File

@@ -487,7 +487,11 @@ static HB_EXPR_FUNC( hb_compExprUseCodeblock )
HB_EXPR_PTR pNext;
hb_compExprCBVarDel( pSelf->value.asCodeblock.pLocals );
if( pSelf->value.asCodeblock.string )
{
HB_XFREE( pSelf->value.asCodeblock.string );
}
/* Delete all expressions of the block.
*/
while( pExp )
@@ -1853,11 +1857,8 @@ static HB_EXPR_FUNC( hb_compExprUseAliasVar )
case HB_EA_DELETE:
HB_EXPR_PCODE1( hb_compExprDelete, pSelf->value.asAlias.pAlias );
/* NOTE: variable name is released only during macro compilation */
#if defined( HB_MACRO_SUPPORT )
if( pSelf->value.asAlias.pVar )
HB_EXPR_PCODE1( hb_compExprDelete, pSelf->value.asAlias.pVar );
#endif
break;
}
return pSelf;
@@ -2005,7 +2006,12 @@ static HB_EXPR_FUNC( hb_compExprUseRTVariable )
case HB_EA_PUSH_POP:
case HB_EA_STATEMENT:
break;
case HB_EA_DELETE:
#if ! defined( HB_MACRO_SUPPORT )
if( ! pSelf->value.asRTVar.szName )
HB_EXPR_PCODE1( hb_compExprDelete, pSelf->value.asRTVar.pMacro );
#endif
break;
}
return pSelf;
@@ -2143,16 +2149,17 @@ static HB_EXPR_FUNC( hb_compExprUseSend )
*/
hb_compWarnMeaningless( pSelf );
}
break;
case HB_EA_DELETE:
#if defined( HB_MACRO_SUPPORT )
{
HB_EXPR_PCODE1( hb_compExprDelete, pSelf->value.asMessage.pObject );
if( pSelf->value.asMessage.pParms )
HB_EXPR_PCODE1( hb_compExprDelete, pSelf->value.asMessage.pParms );
#if defined( HB_MACRO_SUPPORT )
HB_XFREE( pSelf->value.asMessage.szMessage );
}
#endif
}
break;
}
return pSelf;

View File

@@ -144,21 +144,81 @@ void hb_compExprPushOperEq( HB_EXPR_PTR pSelf, BYTE bOpEq )
/* call pop message with one argument */
HB_EXPR_GENPCODE2( hb_compGenPCode2, HB_P_SENDSHORT, 1, ( BOOL ) 1 );
return;
}
/* TODO: add a special code for arrays to correctly handle a[ i++ ]++
*/
else
else if( ( bOpEq == HB_P_PLUS || bOpEq == HB_P_MINUS ||
bOpEq == HB_P_MULT || bOpEq == HB_P_DIVIDE ) &&
( pSelf->value.asOperator.pLeft->ExprType == HB_ET_VARIABLE ) )
{
/* push old value */
HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE );
/* push increment value */
HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE );
/* perform operation and duplicate the new value */
HB_EXPR_GENPCODE1( hb_compGenPCode1, bOpEq );
HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_DUPLICATE );
/* pop the new value into variable and leave the copy on the stack */
HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_POP_PCODE );
/* NOTE: direct type change */
pSelf->value.asOperator.pLeft->ExprType = HB_ET_VARREF;
if( pSelf->value.asOperator.pRight->ExprType == HB_ET_NUMERIC ||
pSelf->value.asOperator.pRight->ExprType == HB_ET_STRING ||
pSelf->value.asOperator.pRight->ExprType == HB_ET_VARIABLE )
{
HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE );
if( pSelf->value.asOperator.pRight->ExprType == HB_ET_VARIABLE )
{
/* NOTE: direct type change */
pSelf->value.asOperator.pRight->ExprType = HB_ET_VARREF;
}
HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE );
switch( bOpEq )
{
case HB_P_PLUS:
bOpEq = HB_P_PLUSEQ;
break;
case HB_P_MINUS:
bOpEq = HB_P_MINUSEQ;
break;
case HB_P_MULT:
bOpEq = HB_P_MULTEQ;
break;
case HB_P_DIVIDE:
bOpEq = HB_P_DIVEQ;
break;
}
HB_EXPR_GENPCODE1( hb_compGenPCode1, bOpEq );
return;
}
else if( pSelf->value.asOperator.pRight->ExprType == HB_ET_VARIABLE )
{
HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE );
/* NOTE: direct type change */
pSelf->value.asOperator.pRight->ExprType = HB_ET_VARREF;
HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE );
switch( bOpEq )
{
case HB_P_PLUS:
bOpEq = HB_P_PLUSEQ;
break;
case HB_P_MINUS:
bOpEq = HB_P_MINUSEQ;
break;
case HB_P_MULT:
bOpEq = HB_P_MULTEQ;
break;
case HB_P_DIVIDE:
bOpEq = HB_P_DIVEQ;
break;
}
HB_EXPR_GENPCODE1( hb_compGenPCode1, bOpEq );
return;
}
}
/* push old value */
HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE );
/* push increment value */
HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE );
/* perform operation and duplicate the new value */
HB_EXPR_GENPCODE1( hb_compGenPCode1, bOpEq );
HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_DUPLICATE );
/* pop the new value into variable and leave the copy on the stack */
HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_POP_PCODE );
}
/* Generates pcodes for <operator>= syntax
@@ -198,18 +258,75 @@ void hb_compExprUseOperEq( HB_EXPR_PTR pSelf, BYTE bOpEq )
/* pop the unneeded value from the stack */
HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_POP );
return;
}
else
/* TODO: add a special code for arrays to correctly handle a[ i++ ]++
*/
else if( ( bOpEq == HB_P_PLUS || bOpEq == HB_P_MINUS ||
bOpEq == HB_P_MULT || bOpEq == HB_P_DIVIDE ) &&
( pSelf->value.asOperator.pLeft->ExprType == HB_ET_VARIABLE ) )
{
/* push old value */
HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE );
/* push increment value */
HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE );
/* add */
HB_EXPR_GENPCODE1( hb_compGenPCode1, bOpEq );
/* pop the new value into variable and remove it from the stack */
HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_POP_PCODE );
/* NOTE: direct type change */
pSelf->value.asOperator.pLeft->ExprType = HB_ET_VARREF;
if( pSelf->value.asOperator.pRight->ExprType == HB_ET_NUMERIC ||
pSelf->value.asOperator.pRight->ExprType == HB_ET_STRING )
{
HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE );
HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE );
switch( bOpEq )
{
case HB_P_PLUS:
bOpEq = HB_P_PLUSEQPOP;
break;
case HB_P_MINUS:
bOpEq = HB_P_MINUSEQPOP;
break;
case HB_P_MULT:
bOpEq = HB_P_MULTEQPOP;
break;
case HB_P_DIVIDE:
bOpEq = HB_P_DIVEQPOP;
break;
}
HB_EXPR_GENPCODE1( hb_compGenPCode1, bOpEq );
return;
}
else if( pSelf->value.asOperator.pRight->ExprType == HB_ET_VARIABLE )
{
HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE );
/* NOTE: direct type change */
pSelf->value.asOperator.pRight->ExprType = HB_ET_VARREF;
HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE );
switch( bOpEq )
{
case HB_P_PLUS:
bOpEq = HB_P_PLUSEQPOP;
break;
case HB_P_MINUS:
bOpEq = HB_P_MINUSEQPOP;
break;
case HB_P_MULT:
bOpEq = HB_P_MULTEQPOP;
break;
case HB_P_DIVIDE:
bOpEq = HB_P_DIVEQPOP;
break;
}
HB_EXPR_GENPCODE1( hb_compGenPCode1, bOpEq );
return;
}
}
/* push old value */
HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_PUSH_PCODE );
/* push increment value */
HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE );
/* add */
HB_EXPR_GENPCODE1( hb_compGenPCode1, bOpEq );
/* pop the new value into variable and remove it from the stack */
HB_EXPR_USE( pSelf->value.asOperator.pLeft, HB_EA_POP_PCODE );
}
/* Generates the pcodes for pre- increment/decrement expressions
@@ -513,6 +630,8 @@ HB_EXPR_PTR hb_compExprReducePlusStrings( HB_EXPR_PTR pLeft, HB_EXPR_PTR pRight,
memcpy( szString + pLeft->ulLength, pRight->value.asString.string, pRight->ulLength );
pLeft->ulLength += pRight->ulLength;
szString[ pLeft->ulLength ] = '\0';
if( pLeft->value.asString.dealloc )
hb_xfree( pLeft->value.asString.string );
pLeft->value.asString.string = szString;
pLeft->value.asString.dealloc = TRUE;
hb_compExprFree( pRight, HB_MACRO_PARAM );

View File

@@ -315,7 +315,6 @@ HB_EXPR_PTR hb_compExprNewString( char * );
HB_EXPR_PTR hb_compExprNewLogical( int );
HB_EXPR_PTR hb_compExprNewSelf( void );
HB_EXPR_PTR hb_compExprNewCodeBlock( char *, BOOL, BOOL );
HB_EXPR_PTR hb_compExprNewArray( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewVar( char * );
HB_EXPR_PTR hb_compExprNewAliasVar( HB_EXPR_PTR, HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewAliasExpr( HB_EXPR_PTR, HB_EXPR_PTR );
@@ -394,6 +393,7 @@ BOOL hb_compExprIsValidMacro( char *, BOOL *, HB_MACRO_DECL );
#ifdef HB_MACRO_SUPPORT
HB_EXPR_PTR hb_compExprNewArray( HB_EXPR_PTR, HB_MACRO_DECL );
HB_EXPR_PTR hb_compExprNewArrayAt( HB_EXPR_PTR, HB_EXPR_PTR, HB_MACRO_DECL );
HB_EXPR_PTR hb_compExprSetOperand( HB_EXPR_PTR, HB_EXPR_PTR, HB_MACRO_DECL );
HB_EXPR_PTR hb_compExprGenPop( HB_EXPR_PTR, HB_MACRO_DECL );
@@ -406,6 +406,7 @@ HB_EXPR_PTR hb_compExprSetGetBlock( HB_EXPR_PTR pExpr, HB_MACRO_DECL );
#else
HB_EXPR_PTR hb_compExprNewArray( HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprNewArrayAt( HB_EXPR_PTR, HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprSetOperand( HB_EXPR_PTR, HB_EXPR_PTR );
HB_EXPR_PTR hb_compExprGenPop( HB_EXPR_PTR );

View File

@@ -205,8 +205,17 @@ typedef enum
HB_P_ENUMEND, /* 131 End of FOR EACH loop */
HB_P_SWITCH, /* 132 SWITCH using long values */
HB_P_PUSHDATE, /* 133 places a data constant value on the virtual machine stack */
/* optimalization of inlined math operations */
HB_P_PLUSEQPOP, /* 134 adds a value to the variable reference */
HB_P_MINUSEQPOP, /* 135 subs a value from the variable reference */
HB_P_MULTEQPOP, /* 136 multiplies a variable reference by a value */
HB_P_DIVEQPOP, /* 137 divides the var reference by a value */
HB_P_PLUSEQ, /* 138 adds a value to the variable reference, leave result on the stack */
HB_P_MINUSEQ, /* 139 subs a value from the variable reference, leave result on the stack */
HB_P_MULTEQ, /* 140 multiplies a variable reference by a value, leave result on the stack */
HB_P_DIVEQ, /* 141 divides the var reference by a value, leave result on the stack */
/* NOTE: This have to be the last definition */
HB_P_LAST_PCODE /* 134 this defines the number of defined pcodes */
HB_P_LAST_PCODE /* 142 this defines the number of defined pcodes */
} HB_PCODE;
#endif /* HB_PCODE_H_ */

View File

@@ -377,45 +377,6 @@ HB_EXPR_PTR hb_compExprNewRef( HB_EXPR_PTR pRefer )
return pExpr;
}
/* Creates a new literal array { item1, item2, ... itemN }
* 'pArrList' is a list of array elements
*/
HB_EXPR_PTR hb_compExprNewArray( HB_EXPR_PTR pArrList )
{
HB_EXPR_PTR pExpr;
HB_TRACE(HB_TR_DEBUG, ("hb_compExprNewArray()"));
pArrList->ExprType = HB_ET_ARRAY; /* change type from ET_LIST */
pArrList->ValType = HB_EV_ARRAY;
pArrList->ulLength = 0;
pExpr = pArrList->value.asList.pExprList; /* get first element on the list */
/* Now we need to replace all EO_NONE expressions with ET_NIL expressions
* If EO_NONE is the first expression and there is no more expressions
* then it is an empty array {} and ET_NIL cannot be used
*/
if( pExpr->ExprType == HB_ET_NONE && pExpr->pNext == NULL )
{
pArrList->value.asList.pExprList = NULL;
}
else
{
/* there are at least one non-empty element specified
*/
while( pExpr )
{
/* if empty element was specified replace it with NIL value */
if( pExpr->ExprType == HB_ET_NONE )
pExpr->ExprType = HB_ET_NIL;
pExpr = pExpr->pNext;
++pArrList->ulLength;
}
}
pArrList->value.asList.pIndex = NULL;
return pArrList;
}
/* Creates new macro expression
*/
HB_EXPR_PTR hb_compExprNewMacro( HB_EXPR_PTR pMacroExpr, unsigned char cMacroOp, char * szName )

View File

@@ -94,10 +94,10 @@ void hb_fsFreeSearchPath( HB_PATHNAMES * pSearchList )
/* Only the first path holds an allocated string.
All of the other paths in the list are part of
that first string. */
hb_xfree( pSearchList->szPath );
while( pSearchList )
{
hb_xfree( pSearchList->szPath );
pNext = pSearchList->pNext;
hb_xfree( pSearchList );
pSearchList = pNext;

View File

@@ -60,6 +60,8 @@ C_SOURCES=\
C_MAIN=harbour.c
LIBS=\
ccmalloc \
dl \
pp \
common \

View File

@@ -5,6 +5,6 @@
/* hbexpra.c is also included from ../macro/macro.c
* However it produces a slighty different code if used in
* macro compiler (there is an additional parameter passed to some functions)
* 1.17 - ignore this magic number - this is used to force compilation
* 1.18 - ignore this magic number - this is used to force compilation
*/
#include "hbexpra.c"

View File

@@ -5,6 +5,6 @@
/* hbexprb.c is also included from ../macro/macro.c
* However it produces a slighty different code if used in
* macro compiler (there is an additional parameter passed to some functions)
* 1.15 - ignore this magic number - this is used to force compilation
* 1.16 - ignore this magic number - this is used to force compilation
*/
#include "hbexprb.c"

View File

@@ -5,6 +5,6 @@
/* hbexprc.c is also included from ../macro/macro.c
* However it produces a slighty different code if used in
* macro compiler (there is an additional parameter passed to some functions)
* 1.5 - ignore this magic number - this is used to force compilation
* 1.6 - ignore this magic number - this is used to force compilation
*/
#include "hbexprc.c"

View File

@@ -1925,6 +1925,79 @@ static HB_GENC_FUNC( hb_p_localnearaddint )
return 4;
}
static HB_GENC_FUNC( hb_p_pluseqpop )
{
HB_SYMBOL_UNUSED( pFunc );
HB_SYMBOL_UNUSED( lPCodePos );
fprintf( cargo->yyc, "\tHB_P_PLUSEQPOP,\n" );
return 1;
}
static HB_GENC_FUNC( hb_p_minuseqpop )
{
HB_SYMBOL_UNUSED( pFunc );
HB_SYMBOL_UNUSED( lPCodePos );
fprintf( cargo->yyc, "\tHB_P_MINUSEQPOP,\n" );
return 1;
}
static HB_GENC_FUNC( hb_p_multeqpop )
{
HB_SYMBOL_UNUSED( pFunc );
HB_SYMBOL_UNUSED( lPCodePos );
fprintf( cargo->yyc, "\tHB_P_MULTEQPOP,\n" );
return 1;
}
static HB_GENC_FUNC( hb_p_diveqpop )
{
HB_SYMBOL_UNUSED( pFunc );
HB_SYMBOL_UNUSED( lPCodePos );
fprintf( cargo->yyc, "\tHB_P_DIVEQPOP,\n" );
return 1;
}
static HB_GENC_FUNC( hb_p_pluseq )
{
HB_SYMBOL_UNUSED( pFunc );
HB_SYMBOL_UNUSED( lPCodePos );
fprintf( cargo->yyc, "\tHB_P_PLUSEQ,\n" );
return 1;
}
static HB_GENC_FUNC( hb_p_minuseq )
{
HB_SYMBOL_UNUSED( pFunc );
HB_SYMBOL_UNUSED( lPCodePos );
fprintf( cargo->yyc, "\tHB_P_MINUSEQ,\n" );
return 1;
}
static HB_GENC_FUNC( hb_p_multeq )
{
HB_SYMBOL_UNUSED( pFunc );
HB_SYMBOL_UNUSED( lPCodePos );
fprintf( cargo->yyc, "\tHB_P_MULTEQ,\n" );
return 1;
}
static HB_GENC_FUNC( hb_p_diveq )
{
HB_SYMBOL_UNUSED( pFunc );
HB_SYMBOL_UNUSED( lPCodePos );
fprintf( cargo->yyc, "\tHB_P_DIVEQ,\n" );
return 1;
}
/* NOTE: The order of functions have to match the order of opcodes
* mnemonics
*/
@@ -2067,7 +2140,16 @@ static HB_GENC_FUNC_PTR s_verbose_table[] = {
hb_p_enumprev,
hb_p_enumend,
hb_p_switch,
hb_p_pushdate
hb_p_pushdate,
/* optimalization of inlined math operations (+=, -= */
hb_p_pluseqpop,
hb_p_minuseqpop,
hb_p_multeqpop,
hb_p_diveqpop,
hb_p_pluseq,
hb_p_minuseq,
hb_p_multeq,
hb_p_diveq
};
static void hb_compGenCReadable( PFUNCTION pFunc, FILE * yyc )

View File

@@ -310,6 +310,8 @@ int main( int argc, char * argv[] )
hb_comp_pPpoPath = NULL;
}
hb_compParserStop();
if( hb_comp_iErrorCount > 0 )
iStatus = EXIT_FAILURE;
@@ -816,7 +818,8 @@ void hb_compVariableAdd( char * szVarName, BYTE cValueType )
{
PVAR pVar, pLastVar;
PFUNCTION pFunc = hb_comp_functions.pLast;
BOOL bFreeVar = TRUE;
HB_SYMBOL_UNUSED( cValueType );
if( ! hb_comp_bStartProc && hb_comp_functions.iCount <= 1 && hb_comp_iVarScope == VS_LOCAL )
@@ -902,6 +905,7 @@ void hb_compVariableAdd( char * szVarName, BYTE cValueType )
pLastVar = pLastVar->pNext;
pLastVar->pNext = pVar;
}
bFreeVar = FALSE;
}
switch( hb_comp_iVarScope )
@@ -919,7 +923,7 @@ void hb_compVariableAdd( char * szVarName, BYTE cValueType )
pSym = hb_compSymbolFind( szVarName, &wPos, HB_SYM_MEMVAR ); /* check if symbol exists already */
if( ! pSym )
pSym = hb_compSymbolAdd( hb_strdup( szVarName ), &wPos, HB_SYM_MEMVAR );
pSym = hb_compSymbolAdd( szVarName, &wPos, HB_SYM_MEMVAR );
pSym->cScope |= VS_MEMVAR;
@@ -956,6 +960,10 @@ void hb_compVariableAdd( char * szVarName, BYTE cValueType )
/*printf( "\nAdded Private: %s Type %c\n", pVar->szName, pVar->cType );*/
}
}
else if( bFreeVar )
{
hb_xfree( pVar );
}
break;
@@ -963,7 +971,7 @@ void hb_compVariableAdd( char * szVarName, BYTE cValueType )
{
pSym = hb_compSymbolFind( szVarName, &wPos, HB_SYM_MEMVAR ); /* check if symbol exists already */
if( ! pSym )
pSym = hb_compSymbolAdd( hb_strdup( szVarName ), &wPos, HB_SYM_MEMVAR );
pSym = hb_compSymbolAdd( szVarName, &wPos, HB_SYM_MEMVAR );
pSym->cScope |= VS_MEMVAR;
@@ -998,6 +1006,10 @@ void hb_compVariableAdd( char * szVarName, BYTE cValueType )
/*printf( "\nAdded Private: %s Type %c\n", pVar->szName, pVar->cType );*/
}
}
else if( bFreeVar )
{
hb_xfree( pVar );
}
break;
@@ -1005,8 +1017,12 @@ void hb_compVariableAdd( char * szVarName, BYTE cValueType )
{
pSym = hb_compSymbolFind( szVarName, &wPos, HB_SYM_MEMVAR ); /* check if symbol exists already */
if( ! pSym )
pSym = hb_compSymbolAdd( hb_strdup( szVarName ), &wPos, HB_SYM_MEMVAR );
pSym = hb_compSymbolAdd( szVarName, &wPos, HB_SYM_MEMVAR );
pSym->cScope |= VS_MEMVAR;
if( bFreeVar )
{
hb_xfree( pVar );
}
}
break;
@@ -1891,7 +1907,8 @@ void hb_compFunctionAdd( char * szFunName, HB_SYMBOLSCOPE cScope, int iType )
strcpy( szNewName, szFunName );
szNewName[ iLen ] ='$';
szNewName[ iLen+1 ] = '\0';
szFunName = szNewName;
szFunName = hb_compIdentifierNew( szNewName, TRUE );
hb_xfree( szNewName );
}
pFunc = hb_compFunctionFind( szFunName );
if( pFunc )
@@ -2121,7 +2138,7 @@ PCOMSYMBOL hb_compSymbolKill( PCOMSYMBOL pSym )
void hb_compGenBreak( void )
{
hb_compGenPushSymbol( hb_strdup("BREAK"), TRUE, FALSE );
hb_compGenPushSymbol( "BREAK", TRUE, FALSE );
hb_compGenPushNil();
}
@@ -3012,7 +3029,8 @@ void hb_compGenMessageData( char * szMsg ) /* generates an underscore-symbol nam
strcpy( szResult, "_" );
strcat( szResult, szMsg );
hb_compGenMessage( szResult );
hb_compGenMessage( hb_compIdentifierNew( szResult, TRUE ) );
hb_xfree( szResult );
}
static void hb_compCheckEarlyMacroEval( char *szVarName )
@@ -3190,7 +3208,7 @@ void hb_compGenPopAliasedVar( char * szVarName,
}
else
{ /* database alias */
hb_compGenPushSymbol( hb_strdup( szAlias ), FALSE, TRUE );
hb_compGenPushSymbol( szAlias, FALSE, TRUE );
hb_compGenVarPCode( HB_P_POPALIASEDFIELD, szVarName );
}
}
@@ -3446,7 +3464,7 @@ void hb_compGenPushAliasedVar( char * szVarName,
}
else
{ /* database alias */
hb_compGenPushSymbol( hb_strdup( szAlias ), FALSE, TRUE );
hb_compGenPushSymbol( szAlias, FALSE, TRUE );
hb_compGenVarPCode( HB_P_PUSHALIASEDFIELD, szVarName );
}
}
@@ -4342,7 +4360,7 @@ void hb_compStaticDefStart( void )
{
BYTE pBuffer[ 5 ];
hb_comp_pInitFunc = hb_compFunctionNew( hb_strdup("(_INITSTATICS)"), HB_FS_INIT );
hb_comp_pInitFunc = hb_compFunctionNew( hb_compIdentifierNew("(_INITSTATICS)", TRUE), HB_FS_INIT );
hb_comp_pInitFunc->pOwner = hb_comp_functions.pLast;
hb_comp_pInitFunc->bFlags = FUN_USES_STATICS | FUN_PROCEDURE;
hb_comp_pInitFunc->cScope = HB_FS_INIT | HB_FS_EXIT;
@@ -4495,7 +4513,7 @@ void hb_compCodeBlockEnd( void )
hb_compGenPCodeN( pBuffer, 3 + strlen( hb_comp_files.pLast->szFileName ) + strlen( pFunc->szName ), 0 );
hb_xfree( pBuffer );
/* generate the name of reference local variables */
/* generate the name of referenced local variables */
pVar = pCodeblock->pStatics;
iLocalPos = -1;
while( wLocalsCnt-- )
@@ -4520,7 +4538,16 @@ void hb_compCodeBlockEnd( void )
}
}
else
{
pVar = pCodeblock->pStatics;
while( pVar )
{
pFree = pVar;
pVar = pVar->pNext;
hb_xfree( ( void * ) pFree );
}
}
hb_compGenPCodeN( pCodeblock->pCode, pCodeblock->lPCodePos, ( BOOL ) 0 );
/* this fake-function is no longer needed */
@@ -4785,7 +4812,9 @@ int hb_compCompile( char * szPrg, int argc, char * argv[] )
/* Generate the starting procedure frame */
if( hb_comp_bStartProc )
hb_compFunctionAdd( hb_strupr( hb_strdup( hb_comp_pFileName->szName ) ), HB_FS_PUBLIC, FUN_PROCEDURE );
{
hb_compFunctionAdd( hb_compIdentifierNew( hb_comp_pFileName->szName, TRUE ), HB_FS_PUBLIC, FUN_PROCEDURE );
}
else
{
/* Don't pass the name of module if the code for starting procedure
@@ -4798,13 +4827,25 @@ int hb_compCompile( char * szPrg, int argc, char * argv[] )
yyparse();
/* Close processed file (it is opened in hb_compInclude() function ) */
fclose( yyin );
hb_comp_files.pLast = NULL;
/* fclose( yyin ); */
while( hb_comp_files.pLast )
{
PFILE pFile = hb_comp_files.pLast;
fclose( pFile->handle );
if( pFile->pBuffer )
hb_xfree( (void *) pFile->pBuffer );
hb_comp_files.pLast = pFile->pPrev;
hb_xfree( pFile );
}
hb_comp_files.pLast = NULL;
if( hb_comp_bPPO && hb_comp_yyppo )
{
fclose( hb_comp_yyppo );
hb_comp_yyppo = NULL;
if( hb_comp_pFilePpo )
hb_xfree( hb_comp_pFilePpo );
}
/* Saving main file. */
@@ -4920,6 +4961,7 @@ int hb_compCompile( char * szPrg, int argc, char * argv[] )
hb_compGenOutput( hb_comp_iLanguage );
}
hb_compParserStop();
}
else
{
@@ -5105,5 +5147,7 @@ int hb_compAutoOpen( char * szPrg, BOOL * pbSkipGen )
iStatus = EXIT_FAILURE;
}
hb_xfree( hb_comp_pFileName );
return iStatus;
}

View File

@@ -1,4 +1,4 @@
%{
%{
/*
* $Id$
*/
@@ -1718,17 +1718,22 @@ Separator {SpaceTab}
/* ************************************************************************ */
%}
{InvalidNumber} BEGIN INVALIDNUM_; yylval.string = hb_strupr( hb_strdup( yytext ) );
{InvalidNumber} BEGIN INVALIDNUM_; yylval.string = hb_strdup( yytext );
<INVALIDNUM_>("."|{Separator}+) {
BEGIN 0;
hb_xfree( yylval.string );
hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_NUMERIC_FORMAT, NULL, NULL );
}
<INVALIDNUM_>. {
int iRet;
char *pTmp = yylval.string;
BEGIN 0;
unput( yytext[ yyleng-1 ] );
unput( '.' );
yylval.string[ strlen(yylval.string) - 1 ] = '\0';
return yy_ConvertNumber( yylval.string );
iRet = yy_ConvertNumber( yylval.string );
hb_xfree( pTmp );
return iRet;
}
@@ -1748,19 +1753,21 @@ Separator {SpaceTab}
}
{MacroEnd} {
yylval.string = hb_strupr( hb_strdup( yytext ) );
/* yylval.string = hb_strupr( hb_strdup( yytext ) );*/
yylval.string = yytext;
hb_comp_iState = MACROTEXT;
return MACROTEXT;
}
{MacroId} {
yylval.string = hb_strupr( hb_strdup( yytext ) );
/* yylval.string = hb_strupr( hb_strdup( yytext ) );*/
yylval.string = yytext;
hb_comp_iState = MACROTEXT;
return MACROTEXT;
}
{MacroTxt} {
yylval.string = hb_strupr( hb_strdup( yytext ) );
/* yylval.string = hb_strupr( hb_strdup( yytext ) );*/
hb_comp_iState = MACROTEXT;
return MACROTEXT;
}
@@ -1831,3 +1838,4 @@ static int yy_ConvertDate( char * szBuffer )
return NUM_DATE;
}

View File

@@ -432,7 +432,7 @@ Statement : ExecFlow { hb_comp_bDontGenLineNum = TRUE; } CrlfStmnt { }
{
hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_EXIT_IN_SEQUENCE, "RETURN", NULL );
}
hb_compExprGenPush( $3 ); /* TODO: check if return value agree with declared value */
hb_compExprDelete( hb_compExprGenPush( $3 ) ); /* TODO: check if return value agree with declared value */
hb_compGenPCode2( HB_P_RETVALUE, HB_P_ENDPROC, ( BOOL ) 1 );
if( hb_comp_functions.pLast->bFlags & FUN_PROCEDURE )
{ /* procedure returns a value */
@@ -444,10 +444,10 @@ Statement : ExecFlow { hb_comp_bDontGenLineNum = TRUE; } CrlfStmnt { }
}
| PUBLIC { hb_compLinePushIfInside(); hb_comp_iVarScope = VS_PUBLIC; }
ExtVarList
{ hb_compRTVariableGen( "__MVPUBLIC" ); hb_comp_cVarType = ' '; hb_comp_iVarScope = VS_NONE; } Crlf
{ hb_compRTVariableGen( hb_compIdentifierNew("__MVPUBLIC",TRUE) ); hb_comp_cVarType = ' '; hb_comp_iVarScope = VS_NONE; } Crlf
| PRIVATE { hb_compLinePushIfInside(); hb_comp_iVarScope = VS_PRIVATE; }
ExtVarList
{ hb_compRTVariableGen( "__MVPRIVATE" ); hb_comp_cVarType = ' '; hb_comp_iVarScope = VS_NONE; } Crlf
{ hb_compRTVariableGen( hb_compIdentifierNew("__MVPRIVATE",TRUE) ); hb_comp_cVarType = ' '; hb_comp_iVarScope = VS_NONE; } Crlf
| EXIT { hb_comp_bDontGenLineNum = !hb_comp_bDebugInfo; } CrlfStmnt { hb_compLoopExit(); hb_comp_functions.pLast->bFlags |= FUN_BREAK_CODE; }
| LOOP { hb_comp_bDontGenLineNum = !hb_comp_bDebugInfo; } CrlfStmnt { hb_compLoopLoop(); hb_comp_functions.pLast->bFlags |= FUN_BREAK_CODE; }
@@ -1385,10 +1385,10 @@ DummyArgument : EmptyExpression {}
FormalList : IdentName AsType { hb_compDeclaredParameterAdd( $1, hb_comp_cVarType ); }
| '@' IdentName AsType { hb_compDeclaredParameterAdd( $2, hb_comp_cVarType + VT_OFFSET_BYREF ); }
| '@' IdentName '(' DummyArgList ')' { hb_compDeclaredParameterAdd( $2, 'F' ); }
| '@' IdentName '(' DummyArgList ')' { hb_compDeclaredParameterAdd( $2, 'F' ); hb_compExprDelete( $<asExpr>4 );}
| FormalList ',' IdentName AsType { hb_compDeclaredParameterAdd( $3, hb_comp_cVarType ); }
| FormalList ',' '@' IdentName AsType { hb_compDeclaredParameterAdd( $4, hb_comp_cVarType + VT_OFFSET_BYREF ); }
| FormalList ',' '@' IdentName '(' DummyArgList ')' { hb_compDeclaredParameterAdd( $4, 'F' ); }
| FormalList ',' '@' IdentName '(' DummyArgList ')' { hb_compDeclaredParameterAdd( $4, 'F' ); hb_compExprDelete( $<asExpr>6 ); }
;
OptList : OPTIONAL IdentName AsType { hb_compDeclaredParameterAdd( $2, hb_comp_cVarType + VT_OFFSET_OPTIONAL ); }
@@ -2021,6 +2021,19 @@ int yywrap( void ) /* handles the EOF of the currently processed file */
return 0;
}
void hb_compParserStop( void )
{
if( hb_comp_buffer )
{
#ifdef __cplusplus
yy_delete_buffer( (YY_BUFFER_STATE) hb_comp_buffer );
#else
yy_delete_buffer( (void *) hb_comp_buffer );
#endif
hb_comp_buffer = NULL;
}
}
/* ************************************************************************* */
/*
@@ -2211,11 +2224,14 @@ static void * hb_compElseIfGen( void * pFirst, ULONG ulOffset )
static void hb_compElseIfFix( void * pFixElseIfs )
{
PELSEIF pFix = ( PELSEIF ) pFixElseIfs;
PELSEIF pDel;
while( pFix )
{
hb_compGenJumpHere( pFix->ulOffset );
pDel = pFix;
pFix = pFix->pNext;
hb_xfree( pDel );
}
}
@@ -2247,7 +2263,7 @@ static void hb_compRTVariableGen( char * szCreateFun )
HB_RTVAR_PTR pDel;
/* generate the function call frame */
hb_compGenPushSymbol( hb_strdup( szCreateFun ), TRUE, FALSE );
hb_compGenPushSymbol( szCreateFun, TRUE, FALSE );
hb_compGenPushNil();
/* push variable names to create */

View File

@@ -488,7 +488,16 @@ static PHB_CODETRACE_FUNC s_codeTraceFuncTable[ HB_P_LAST_PCODE ] =
hb_p_default, /* HB_P_ENUMPREV */
hb_p_default, /* HB_P_ENUMEND */
hb_p_switch, /* HB_P_SWITCH */
hb_p_default /* HB_P_PUSHDATE */
hb_p_default, /* HB_P_PUSHDATE */
/* optimalization of inlined math operations */
hb_p_default, /* HB_P_PLUSEQPOP */
hb_p_default, /* HB_P_MINUSEQPOP */
hb_p_default, /* HB_P_MULTEQPOP */
hb_p_default, /* HB_P_DIVEQPOP */
hb_p_default, /* HB_P_PLUSEQ */
hb_p_default, /* HB_P_MINUSEQ */
hb_p_default, /* HB_P_MULTEQ */
hb_p_default, /* HB_P_DIVEQ */
};
void hb_compCodeTraceMarkDead( PFUNCTION pFunc )

View File

@@ -539,7 +539,15 @@ static HB_FIX_FUNC_PTR s_fixlocals_table[] =
NULL, /* HB_P_ENUMPREV */
NULL, /* HB_P_ENUMEND */
NULL, /* HB_P_SWITCH */
NULL /* HB_P_PUSHDATE */
NULL, /* HB_P_PUSHDATE */
NULL, /* HB_P_PLUSEQPOP */
NULL, /* HB_P_MINUSEQPOP */
NULL, /* HB_P_MULTEQPOP */
NULL, /* HB_P_DIVEQPOP */
NULL, /* HB_P_PLUSEQ */
NULL, /* HB_P_MINUSEQ */
NULL, /* HB_P_MULTEQ */
NULL /* HB_P_DIVEQ */
};
void hb_compFixFuncPCode( PFUNCTION pFunc )

View File

@@ -178,7 +178,16 @@ const BYTE hb_comp_pcode_len[] = {
1, /* HB_P_ENUMPREV */
1, /* HB_P_ENUMEND */
3, /* HB_P_SWITCH */
5 /* HB_P_PUSHDATE, */
5, /* HB_P_PUSHDATE, */
/* optimalization of inlined math operations */
1, /* HB_P_PLUSEQPOP, */
1, /* HB_P_MINUSEQPOP, */
1, /* HB_P_MULTEQPOP, */
1, /* HB_P_DIVEQPOP, */
1, /* HB_P_PLUSEQ, */
1, /* HB_P_MINUSEQ, */
1, /* HB_P_MULTEQ, */
1 /* HB_P_DIVEQ, */
};
void hb_compPCodeEval( PFUNCTION pFunc, HB_PCODE_FUNC_PTR * pFunctions, void * cargo )

View File

@@ -269,7 +269,16 @@ static PHB_STRIP_FUNC s_stripLines_table[] =
NULL, /* HB_P_ENUMPREV */
NULL, /* HB_P_ENUMEND */
NULL, /* HB_P_SWITCH */
NULL /* HB_P_PUSHDATE */
NULL, /* HB_P_PUSHDATE */
/* optimalization of inlined math operations */
NULL, /* HB_P_PLUSEQPOP */
NULL, /* HB_P_MINUSEQPOP */
NULL, /* HB_P_MULTEQPOP */
NULL, /* HB_P_DIVEQPOP */
NULL, /* HB_P_PLUSEQ */
NULL, /* HB_P_MINUSEQ */
NULL, /* HB_P_MULTEQ */
NULL /* HB_P_DIVEQ */
};
void hb_compStripFuncLines( PFUNCTION pFunc )

View File

@@ -299,7 +299,7 @@ SelfValue : SELF { $$ = hb_compExprNewSelf(); }
/* Literal array
*/
Array : '{' ElemList '}' { $$ = hb_compExprNewArray( $2 ); }
Array : '{' ElemList '}' { $$ = hb_compExprNewArray( $2, HB_MACRO_PARAM ); }
;
/* Literal array access

View File

@@ -5,7 +5,7 @@
/* hbexpra.c is also included from ../compiler/expropta.c
* However it produces a slighty different code if used in
* macro compiler (there is an additional parameter passed to some functions)
* 1.17 - ignore this magic number - this is used to force compilation
* 1.18 - ignore this magic number - this is used to force compilation
*/
#define HB_MACRO_SUPPORT

View File

@@ -5,7 +5,7 @@
/* hbexprb.c is also included from ../compiler/exproptb.c
* However it produces a slighty different code if used in
* macro compiler (there is an additional parameter passed to some functions)
* 1.14 - ignore this magic number - this is used to force compilation
* 1.15 - ignore this magic number - this is used to force compilation
*/
#define HB_MACRO_SUPPORT

View File

@@ -5,7 +5,7 @@
/* hbexprc.c is also included from ../compiler/exproptc.c
* However it produces a slighty different code if used in
* macro compiler (there is an additional parameter passed to some functions)
* 1.4 - ignore this magic number - this is used to force compilation
* 1.5 - ignore this magic number - this is used to force compilation
*/
#define HB_MACRO_SUPPORT

View File

@@ -376,7 +376,6 @@ void hb_pp_Free( void )
hb_xfree( (void *)hb_pp_aCondCompile );
hb_pp_aCondCompile = NULL;
}
}
void hb_pp_Init( void )

View File

@@ -108,15 +108,15 @@ HB_FUNC_EXTERN( SYSINIT );
/* Operators (mathematical / character / misc) */
static void hb_vmNegate( void ); /* negates (-) the latest value on the stack */
static void hb_vmPlus( void ); /* sums the latest two values on the stack, removes them and leaves the result */
static void hb_vmMinus( void ); /* substracts the latest two values on the stack, removes them and leaves the result */
static void hb_vmMult( void ); /* multiplies the latest two values on the stack, removes them and leaves the result */
static void hb_vmDivide( void ); /* divides the latest two values on the stack, removes them and leaves the result */
static void hb_vmModulus( void ); /* calculates the modulus of latest two values on the stack, removes them and leaves the result */
static void hb_vmPower( void ); /* power the latest two values on the stack, removes them and leaves the result */
static void hb_vmInc( void ); /* increment the latest numeric value on the stack */
static void hb_vmDec( void ); /* decrements the latest numeric value on the stack */
static void hb_vmFuncPtr( void ); /* pushes a function address pointer. Removes the symbol from the satck */
static void hb_vmPlus( HB_ITEM_PTR pResult, HB_ITEM_PTR pItem1, HB_ITEM_PTR pItem2, int iPopCnt ); /* sums the latest two values on the stack, removes them and leaves the result */
static void hb_vmMinus( HB_ITEM_PTR pResult, HB_ITEM_PTR pItem1, HB_ITEM_PTR pItem2, int iPopCnt ); /* substracts the latest two values on the stack, removes them and leaves the result */
static void hb_vmMult( HB_ITEM_PTR pResult, HB_ITEM_PTR pItem1, HB_ITEM_PTR pItem2, int iPopCnt ); /* multiplies the latest two values on the stack, removes them and leaves the result */
static void hb_vmDivide( HB_ITEM_PTR pResult, HB_ITEM_PTR pItem1, HB_ITEM_PTR pItem2, int iPopCnt ); /* divides the latest two values on the stack, removes them and leaves the result */
/* Operators (relational) */
static void hb_vmEqual( BOOL bExact ); /* checks if the two latest values on the stack are equal, removes both and leaves result */
@@ -146,7 +146,7 @@ static void hb_vmArrayGen( ULONG ulElements ); /* generates an ulElements Arr
static void hb_vmArrayNew( HB_ITEM_PTR, USHORT ); /* creates array */
/* Object */
static void hb_vmOperatorCall( PHB_ITEM, PHB_ITEM, char * ); /* call an overloaded operator */
static void hb_vmOperatorCall( HB_ITEM_PTR, PHB_ITEM, PHB_ITEM, char * ); /* call an overloaded operator */
static void hb_vmOperatorCallUnary( PHB_ITEM, char * ); /* call an overloaded unary operator */
/* Database */
@@ -660,24 +660,119 @@ HB_EXPORT void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols )
break;
case HB_P_PLUS:
hb_vmPlus();
hb_vmPlus( hb_stackItemFromTop( -2 ), hb_stackItemFromTop( -2 ), hb_stackItemFromTop( -1 ), 1 );
w++;
break;
case HB_P_PLUSEQ:
{
HB_ITEM_PTR pResult;
pResult = hb_itemUnRef( hb_stackItemFromTop( -2 ) );
hb_vmPlus( pResult, pResult, hb_itemUnRef( hb_stackItemFromTop( -1 ) ), 2 );
hb_itemCopy( hb_stackTopItem(), pResult );
hb_stackPush();
}
w++;
break;
case HB_P_PLUSEQPOP:
{
HB_ITEM_PTR pResult;
pResult = hb_itemUnRef( hb_stackItemFromTop( -2 ) );
hb_vmPlus( pResult, pResult, hb_itemUnRef( hb_stackItemFromTop( -1 ) ), 2 );
}
w++;
break;
/*
case HB_P_MINUS:
hb_vmMinus();
w++;
break;
*/
case HB_P_MINUS:
hb_vmMinus( hb_stackItemFromTop( -2 ), hb_stackItemFromTop( -2 ), hb_stackItemFromTop( -1 ), 1 );
w++;
break;
case HB_P_MINUSEQ:
{
HB_ITEM_PTR pResult;
pResult = hb_itemUnRef( hb_stackItemFromTop( -2 ) );
hb_vmMinus( pResult, pResult, hb_itemUnRef( hb_stackItemFromTop( -1 ) ), 2 );
hb_itemCopy( hb_stackTopItem(), pResult );
hb_stackPush();
}
w++;
break;
case HB_P_MINUSEQPOP:
{
HB_ITEM_PTR pResult;
pResult = hb_itemUnRef( hb_stackItemFromTop( -2 ) );
hb_vmMinus( pResult, pResult, hb_itemUnRef( hb_stackItemFromTop( -1 ) ), 2 );
}
w++;
break;
/*
case HB_P_MULT:
hb_vmMult();
w++;
break;
*/
case HB_P_MULT:
hb_vmMult( hb_stackItemFromTop( -2 ), hb_stackItemFromTop( -2 ), hb_stackItemFromTop( -1 ), 1 );
w++;
break;
case HB_P_MULTEQ:
{
HB_ITEM_PTR pResult;
pResult = hb_itemUnRef( hb_stackItemFromTop( -2 ) );
hb_vmMult( pResult, pResult, hb_itemUnRef( hb_stackItemFromTop( -1 ) ), 2 );
hb_itemCopy( hb_stackTopItem(), pResult );
hb_stackPush();
}
w++;
break;
case HB_P_MULTEQPOP:
{
HB_ITEM_PTR pResult;
pResult = hb_itemUnRef( hb_stackItemFromTop( -2 ) );
hb_vmMult( pResult, pResult, hb_itemUnRef( hb_stackItemFromTop( -1 ) ), 2 );
}
w++;
break;
/*
case HB_P_DIVIDE:
hb_vmDivide();
w++;
break;
*/
case HB_P_DIVIDE:
hb_vmDivide( hb_stackItemFromTop( -2 ), hb_stackItemFromTop( -2 ), hb_stackItemFromTop( -1 ), 1 );
w++;
break;
case HB_P_DIVEQ:
{
HB_ITEM_PTR pResult;
pResult = hb_itemUnRef( hb_stackItemFromTop( -2 ) );
hb_vmDivide( pResult, pResult, hb_itemUnRef( hb_stackItemFromTop( -1 ) ), 2 );
hb_itemCopy( hb_stackTopItem(), pResult );
hb_stackPush();
}
w++;
break;
case HB_P_DIVEQPOP:
{
HB_ITEM_PTR pResult;
pResult = hb_itemUnRef( hb_stackItemFromTop( -2 ) );
hb_vmDivide( pResult, pResult, hb_itemUnRef( hb_stackItemFromTop( -1 ) ), 2 );
}
w++;
break;
case HB_P_MODULUS:
hb_vmModulus();
@@ -1998,15 +2093,9 @@ static void hb_vmNegate( void )
}
}
static void hb_vmPlus( void )
static void hb_vmPlus( HB_ITEM_PTR pResult, HB_ITEM_PTR pItem1, HB_ITEM_PTR pItem2, int iPopCnt )
{
PHB_ITEM pItem1;
PHB_ITEM pItem2;
HB_TRACE(HB_TR_DEBUG, ("hb_vmPlus()"));
pItem1 = hb_stackItemFromTop( -2 );
pItem2 = hb_stackItemFromTop( -1 );
HB_TRACE(HB_TR_DEBUG, ("hb_vmPlus(%p,%p,%p,%i)", pResult, pItem1, pItem2, iPopCnt));
if( HB_IS_NUMINT( pItem1 ) && HB_IS_NUMINT( pItem2 ) )
{
@@ -2014,26 +2103,30 @@ static void hb_vmPlus( void )
HB_LONG lNumber2 = HB_ITEM_GET_NUMINTRAW( pItem2 );
HB_LONG lResult = lNumber1 + lNumber2;
hb_stackDec();
pItem2->type = HB_IT_NIL;
if ( lNumber2 >= 0 ? lResult >= lNumber1 : lResult < lNumber1 )
{
HB_ITEM_PUT_NUMINTRAW( pItem1, lResult );
hb_itemPutNInt( pResult, lResult );
}
else
{
hb_itemPutNDDec( pResult, ( double ) lNumber1 + ( double ) lNumber2, 0 );
}
while( iPopCnt-- > 0 )
{
hb_stackDec();
hb_vmPushDouble( ( double ) lNumber1 + ( double ) lNumber2, 0 );
}
}
else if( HB_IS_NUMERIC( pItem1 ) && HB_IS_NUMERIC( pItem2 ) )
{
int iDec2, iDec1, iType2 = pItem2->type, iType1 = pItem2->type;
double dNumber2 = hb_vmPopDouble( &iDec2 );
double dNumber1 = hb_vmPopDouble( &iDec1 );
double dNumber1 = hb_itemGetNDDec( pItem1, &iDec1 );
double dNumber2 = hb_itemGetNDDec( pItem2, &iDec2 );
hb_vmPushNumType( dNumber1 + dNumber2, ( ( iDec1 > iDec2 ) ? iDec1 : iDec2 ), iType1, iType2 );
hb_itemPutNumType( pResult, dNumber1 + dNumber2, ( ( iDec1 > iDec2 ) ? iDec1 : iDec2 ), iType1, iType2 );
while( iPopCnt-- > 0 )
{
hb_stackDec();
}
}
else if( HB_IS_STRING( pItem1 ) && HB_IS_STRING( pItem2 ) )
{
@@ -2046,52 +2139,60 @@ static void hb_vmPlus( void )
hb_xmemcpy( szNewString, pItem1->item.asString.value, ulLen1 );
hb_xmemcpy( szNewString + ulLen1, pItem2->item.asString.value, ulLen2 );
hb_itemPutCPtr( pItem1, szNewString, ulLen1 + ulLen2 );
hb_stackPop();
hb_itemPutCPtr( pResult, szNewString, ulLen1 + ulLen2 );
while( iPopCnt-- > 0 )
{
hb_stackPop();
}
}
else
hb_errRT_BASE( EG_STROVERFLOW, 1209, NULL, "+", 2, pItem1, pItem2 );
}
else if( HB_IS_DATE( pItem1 ) && HB_IS_DATE( pItem2 ) )
{
long lDate2 = hb_vmPopDate();
long lDate1 = hb_vmPopDate();
/* NOTE: This is not a bug. CA-Cl*pper does exactly that. */
hb_vmPushDate( lDate1 + lDate2 );
hb_itemPutDL( pResult, ( long ) hb_itemGetND( pItem1 ) + ( long ) hb_itemGetND( pItem2 ) );
while( iPopCnt-- > 0 )
{
hb_stackDec();
}
}
else if( HB_IS_DATE( pItem1 ) && HB_IS_NUMERIC( pItem2 ) )
{
long lNumber2 = ( long ) hb_vmPopNumber();
long lDate1 = hb_vmPopDate();
hb_vmPushDate( lDate1 + lNumber2 );
hb_itemPutND( pResult, ( long ) hb_itemGetND( pItem1 ) + ( long ) hb_itemGetND( pItem1 ) );
while( iPopCnt-- > 0 )
{
hb_stackDec();
}
}
else if( HB_IS_OBJECT( pItem1 ) && hb_objHasMsg( pItem1, "__OpPlus" ) )
hb_vmOperatorCall( pItem1, pItem2, "__OPPLUS" );
else
{
PHB_ITEM pResult = hb_errRT_BASE_Subst( EG_ARG, 1081, NULL, "+", 2, pItem1, pItem2 );
if( pResult )
hb_vmOperatorCall( pResult, pItem1, pItem2, "__OPPLUS" );
--iPopCnt; /* hb_vmOperatorCall pops pItem2 */
while( iPopCnt-- > 0 )
{
hb_stackPop();
}
}
else
{
PHB_ITEM pSubst = hb_errRT_BASE_Subst( EG_ARG, 1081, NULL, "+", 2, pItem1, pItem2 );
if( pSubst )
{
hb_itemForwardValue( pResult, pSubst );
hb_itemRelease( pSubst );
}
while( iPopCnt-- > 0 )
{
hb_stackPop();
hb_vmPush( pResult );
hb_itemRelease( pResult );
}
}
}
static void hb_vmMinus( void )
static void hb_vmMinus( HB_ITEM_PTR pResult, HB_ITEM_PTR pItem1, HB_ITEM_PTR pItem2, int iPopCnt )
{
PHB_ITEM pItem1;
PHB_ITEM pItem2;
HB_TRACE(HB_TR_DEBUG, ("hb_vmMinus()"));
pItem1 = hb_stackItemFromTop( -2 );
pItem2 = hb_stackItemFromTop( -1 );
HB_TRACE(HB_TR_DEBUG, ("hb_vmMinus(%p,%p,%p,%i)", pResult, pItem1, pItem2, iPopCnt));
if( HB_IS_NUMINT( pItem1 ) && HB_IS_NUMINT( pItem2 ) )
{
@@ -2099,40 +2200,46 @@ static void hb_vmMinus( void )
HB_LONG lNumber2 = HB_ITEM_GET_NUMINTRAW( pItem2 );
HB_LONG lResult = lNumber1 - lNumber2;
hb_stackDec();
pItem2->type = HB_IT_NIL;
if ( lNumber2 <= 0 ? lResult >= lNumber1 : lResult < lNumber1 )
if ( lNumber2 >= 0 ? lResult >= lNumber1 : lResult < lNumber1 )
{
HB_ITEM_PUT_NUMINTRAW( pItem1, lResult );
hb_itemPutNInt( pResult, lResult );
}
else
{
hb_itemPutNDDec( pResult, ( double ) lNumber1 - ( double ) lNumber2, 0 );
}
while( iPopCnt-- > 0 )
{
hb_stackDec();
hb_vmPushDouble( ( double ) lNumber1 - ( double ) lNumber2, 0 );
}
}
else if( HB_IS_NUMERIC( pItem1 ) && HB_IS_NUMERIC( pItem2 ) )
{
int iDec2, iDec1, iType2 = pItem2->type, iType1 = pItem1->type;
double dNumber2 = hb_vmPopDouble( &iDec2 );
double dNumber1 = hb_vmPopDouble( &iDec1 );
int iDec2, iDec1, iType2 = pItem2->type, iType1 = pItem2->type;
double dNumber1 = hb_itemGetNDDec( pItem1, &iDec1 );
double dNumber2 = hb_itemGetNDDec( pItem2, &iDec2 );
hb_vmPushNumType( dNumber1 - dNumber2, ( ( iDec1 > iDec2 ) ? iDec1 : iDec2 ), iType1, iType2 );
hb_itemPutNumType( pResult, dNumber1 - dNumber2, ( ( iDec1 > iDec2 ) ? iDec1 : iDec2 ), iType1, iType2 );
while( iPopCnt-- > 0 )
{
hb_stackDec();
}
}
else if( HB_IS_DATE( pItem1 ) && HB_IS_DATE( pItem2 ) )
{
long lDate2 = hb_vmPopDate();
long lDate1 = hb_vmPopDate();
hb_vmPushNumInt( lDate1 - lDate2 );
hb_itemPutNInt( pResult, ( long ) hb_itemGetND( pItem1 ) - ( long ) hb_itemGetND( pItem2 ) );
while( iPopCnt-- > 0 )
{
hb_stackDec();
}
}
else if( HB_IS_DATE( pItem1 ) && HB_IS_NUMERIC( pItem2 ) )
{
long lNumber2 = ( long ) hb_vmPopNumber();
long lDate1 = hb_vmPopDate();
hb_vmPushDate( lDate1 - lNumber2 );
hb_itemPutND( pResult, ( long ) hb_itemGetND( pItem1 ) - ( long ) hb_itemGetND( pItem1 ) );
while( iPopCnt-- > 0 )
{
hb_stackDec();
}
}
else if( HB_IS_STRING( pItem1 ) && HB_IS_STRING( pItem2 ) )
{
@@ -2150,37 +2257,43 @@ static void hb_vmMinus( void )
hb_xmemcpy( szNewString, pItem1->item.asString.value, ulLen1 );
hb_xmemcpy( szNewString + ulLen1, pItem2->item.asString.value, ulLen2 );
hb_xmemset( szNewString + ulLen1 + ulLen2, ' ', pItem1->item.asString.length - ulLen1 );
hb_itemPutCPtr( pItem1, szNewString, ulNewLen );
hb_stackPop();
hb_itemPutCPtr( pResult, szNewString, ulNewLen );
while( iPopCnt-- > 0 )
{
hb_stackPop();
}
}
else
hb_errRT_BASE( EG_STROVERFLOW, 1210, NULL, "-", 2, pItem1, pItem2 );
}
else if( HB_IS_OBJECT( pItem1 ) && hb_objHasMsg( pItem1, "__OpMinus" ) )
hb_vmOperatorCall( pItem1, pItem2, "__OPMINUS" );
else
{
PHB_ITEM pResult = hb_errRT_BASE_Subst( EG_ARG, 1082, NULL, "-", 2, pItem1, pItem2 );
if( pResult )
hb_vmOperatorCall( pResult, pItem1, pItem2, "__OPMINUS" );
--iPopCnt; /* hb_vmOperatorCall pops pItem2 */
while( iPopCnt-- > 0 )
{
hb_stackPop();
}
}
else
{
PHB_ITEM pSubst = hb_errRT_BASE_Subst( EG_ARG, 1082, NULL, "-", 2, pItem1, pItem2 );
if( pSubst )
{
hb_itemForwardValue( pResult, pSubst );
hb_itemRelease( pSubst );
}
while( iPopCnt-- > 0 )
{
hb_stackPop();
hb_vmPush( pResult );
hb_itemRelease( pResult );
}
}
}
static void hb_vmMult( void )
static void hb_vmMult( HB_ITEM_PTR pResult, HB_ITEM_PTR pItem1, HB_ITEM_PTR pItem2, int iPopCnt )
{
PHB_ITEM pItem1;
PHB_ITEM pItem2;
HB_TRACE(HB_TR_DEBUG, ("hb_vmMult()"));
pItem1 = hb_stackItemFromTop( -2 );
pItem2 = hb_stackItemFromTop( -1 );
HB_TRACE(HB_TR_DEBUG, ("hb_vmMinus(%p,%p,%p,%i)", pResult, pItem1, pItem2, iPopCnt));
/* if( HB_IS_NUMINT( pItem1 ) && HB_IS_NUMINT( pItem2 ) )
{
@@ -2194,38 +2307,45 @@ static void hb_vmMult( void )
}
else */ if( HB_IS_NUMERIC( pItem1 ) && HB_IS_NUMERIC( pItem2 ) )
{
int iDec2, iDec1, iType2 = pItem2->type, iType1 = pItem1->type;
double d2 = hb_vmPopDouble( &iDec2 );
double d1 = hb_vmPopDouble( &iDec1 );
int iDec2, iDec1, iType2 = pItem2->type, iType1 = pItem2->type;
double dNumber1 = hb_itemGetNDDec( pItem1, &iDec1 );
double dNumber2 = hb_itemGetNDDec( pItem2, &iDec2 );
hb_vmPushNumType( d1 * d2, iDec1 + iDec2, iType1, iType2 );
hb_itemPutNumType( pResult, dNumber1 * dNumber2, iDec1 + iDec2, iType1, iType2 );
while( iPopCnt-- > 0 )
{
hb_stackDec();
}
}
else if( HB_IS_OBJECT( pItem1 ) && hb_objHasMsg( pItem1, "__OpMult" ) )
hb_vmOperatorCall( pItem1, pItem2, "__OPMULT" );
else
{
PHB_ITEM pResult = hb_errRT_BASE_Subst( EG_ARG, 1083, NULL, "*", 2, pItem1, pItem2 );
if( pResult )
hb_vmOperatorCall( pResult, pItem1, pItem2, "__OPMULT" );
--iPopCnt; /* hb_vmOperatorCall pops pItem2 */
while( iPopCnt-- > 0 )
{
hb_stackPop();
}
}
else
{
PHB_ITEM pSubst = hb_errRT_BASE_Subst( EG_ARG, 1083, NULL, "*", 2, pItem1, pItem2 );
if( pSubst )
{
hb_itemForwardValue( pResult, pSubst );
hb_itemRelease( pSubst );
}
while( iPopCnt-- > 0 )
{
hb_stackPop();
hb_vmPush( pResult );
hb_itemRelease( pResult );
}
}
}
static void hb_vmDivide( void )
static void hb_vmDivide( HB_ITEM_PTR pResult, HB_ITEM_PTR pItem1, HB_ITEM_PTR pItem2, int iPopCnt )
{
PHB_ITEM pItem1;
PHB_ITEM pItem2;
HB_TRACE(HB_TR_DEBUG, ("hb_vmDivide()"));
pItem1 = hb_stackItemFromTop( -2 );
pItem2 = hb_stackItemFromTop( -1 );
HB_TRACE(HB_TR_DEBUG, ("hb_vmDivide(%p,%p,%p,%i)", pResult, pItem1, pItem2, iPopCnt));
/*
* This code is commented out for Clipper compatibility.
@@ -2237,29 +2357,26 @@ static void hb_vmDivide( void )
if ( lDivisor == 0 )
{
PHB_ITEM pResult = hb_errRT_BASE_Subst( EG_ZERODIV, 1340, NULL, "/", 2, pItem1, pItem2 );
PHB_ITEM pSubst = hb_errRT_BASE_Subst( EG_ZERODIV, 1340, NULL, "/", 2, pItem1, pItem2 );
if( pResult )
if( pSubst )
{
hb_itemForwardValue( pResult, pSubst );
hb_itemRelease( pSubst );
}
while( iPopCnt-- > 0 )
{
hb_stackPop();
hb_stackPop();
hb_vmPush( pResult );
hb_itemRelease( pResult );
}
}
else
{
hb_stackPop(); /* pop divisor from the stack */
/* commented out see note below
HB_LONG lNumber1 = HB_ITEM_GET_NUMINTRAW( pItem1 );
hb_itemPutNDDec( pResult, ( double ) lNumber1 / ( double ) lDivisor, hb_set.HB_SET_DECIMALS );
while( iPopCnt-- > 0 )
{
HB_LONG lDivided = hb_vmPopHBLong();
if ( hb_set.HB_SET_DECIMALS == 0 && lDivided % lDivisor == 0 )
hb_vmPushNumInt( lDivided / lDivisor );
else
hb_vmPushDouble( ( double ) lDivided / ( double ) lDivisor, hb_set.HB_SET_DECIMALS );
hb_stackDec();
}
*/
hb_vmPushDouble( hb_vmPopNumber() / ( double ) lDivisor, hb_set.HB_SET_DECIMALS );
}
}
else if( HB_IS_NUMERIC( pItem1 ) && HB_IS_NUMERIC( pItem2 ) )
@@ -2268,45 +2385,57 @@ static void hb_vmDivide( void )
if( dDivisor == 0.0 )
{
PHB_ITEM pResult = hb_errRT_BASE_Subst( EG_ZERODIV, 1340, NULL, "/", 2, pItem1, pItem2 );
PHB_ITEM pSubst = hb_errRT_BASE_Subst( EG_ZERODIV, 1340, NULL, "/", 2, pItem1, pItem2 );
if( pResult )
if( pSubst )
{
hb_itemForwardValue( pResult, pSubst );
hb_itemRelease( pSubst );
}
while( iPopCnt-- > 0 )
{
hb_stackPop();
hb_stackPop();
hb_vmPush( pResult );
hb_itemRelease( pResult );
}
}
else
{
hb_stackPop(); /* pop divisor from the stack */
/* If all both operand was integer and the result is an integer, too,
push the number without decimals. Clipper compatible. Actually,
this is not Clipper compatible. The only time Clipper returns 0
decimal places is for compiler optimized integer division with an
integer result. Therefore this code is not needed and has been
removed - David G. Holm <dholm@jsd-llc.com>
if( bIntegerOperands && fmod( hb_vmTopNumber() / dDivisor ) == 0.0 )
hb_vmPushNumber( hb_vmPopNumber() / dDivisor, 0 );
else
*/
hb_vmPushDouble( hb_vmPopNumber() / dDivisor, hb_set.HB_SET_DECIMALS );
double dNumber1 = hb_itemGetND( pItem1 );
hb_itemPutNDDec( pResult, dNumber1 / dDivisor, hb_set.HB_SET_DECIMALS );
while( iPopCnt-- > 0 )
{
hb_stackDec();
}
}
}
else if( HB_IS_OBJECT( pItem1 ) && hb_objHasMsg( pItem1, "__OpDivide" ) )
hb_vmOperatorCall( pItem1, pItem2, "__OPDIVIDE" );
else
{
PHB_ITEM pResult = hb_errRT_BASE_Subst( EG_ARG, 1084, NULL, "/", 2, pItem1, pItem2 );
if( pResult )
hb_vmOperatorCall( pResult, pItem1, pItem2, "__OPDIVIDE" );
--iPopCnt; /* hb_vmOperatorCall pops pItem2 */
while( iPopCnt-- > 0 )
{
hb_stackPop();
}
}
else
{
PHB_ITEM pSubst = hb_errRT_BASE_Subst( EG_ARG, 1084, NULL, "/", 2, pItem1, pItem2 );
if( pSubst )
{
hb_itemForwardValue( pResult, pSubst );
hb_itemRelease( pSubst );
}
while( iPopCnt-- > 0 )
{
hb_stackPop();
hb_vmPush( pResult );
hb_itemRelease( pResult );
}
}
}
@@ -2376,7 +2505,7 @@ static void hb_vmModulus( void )
}
}
else if( HB_IS_OBJECT( pItem1 ) && hb_objHasMsg( pItem1, "__OpMod" ) )
hb_vmOperatorCall( pItem1, pItem2, "__OPMOD" );
hb_vmOperatorCall( pItem1, pItem1, pItem2, "__OPMOD" );
else
{
PHB_ITEM pResult = hb_errRT_BASE_Subst( EG_ARG, 1085, NULL, "%", 2, pItem1, pItem2 );
@@ -2411,7 +2540,7 @@ static void hb_vmPower( void )
hb_vmPushDouble( pow( d1, d2 ), hb_set.HB_SET_DECIMALS );
}
else if( HB_IS_OBJECT( pItem1 ) && hb_objHasMsg( pItem1, "__OpPower" ) )
hb_vmOperatorCall( pItem1, pItem2, "__OPPOWER" );
hb_vmOperatorCall( pItem1, pItem1, pItem2, "__OPPOWER" );
else
{
PHB_ITEM pResult = hb_errRT_BASE_Subst( EG_ARG, 1088, NULL, "^", 2, pItem1, pItem2 );
@@ -2584,7 +2713,7 @@ static void hb_vmEqual( BOOL bExact )
else if( HB_IS_LOGICAL( pItem1 ) && HB_IS_LOGICAL( pItem2 ) )
hb_vmPushLogical( hb_vmPopLogical() == hb_vmPopLogical() );
else if( HB_IS_OBJECT( pItem1 ) && hb_objHasMsg( pItem1, "__OpEqual" ) )
hb_vmOperatorCall( pItem1, pItem2, "__OPEQUAL" );
hb_vmOperatorCall( pItem1, pItem1, pItem2, "__OPEQUAL" );
else if( bExact && HB_IS_ARRAY( pItem1 ) && HB_IS_ARRAY( pItem2 ) )
{
BOOL bResult = ( pItem1->item.asArray.value == pItem2->item.asArray.value );
@@ -2659,7 +2788,7 @@ static void hb_vmNotEqual( void )
else if( HB_IS_LOGICAL( pItem1 ) && HB_IS_LOGICAL( pItem2 ) )
hb_vmPushLogical( hb_vmPopLogical() != hb_vmPopLogical() );
else if( HB_IS_OBJECT( pItem1 ) && hb_objHasMsg( pItem1, "__OpNotEqual" ) )
hb_vmOperatorCall( pItem1, pItem2, "__OPNOTEQUAL" );
hb_vmOperatorCall( pItem1, pItem1, pItem2, "__OPNOTEQUAL" );
else if( pItem1->type != pItem2->type ||
( HB_IS_BLOCK( pItem1 ) && HB_IS_BLOCK( pItem2 ) ) ||
( HB_IS_ARRAY( pItem1 ) && HB_IS_ARRAY( pItem2 ) ) )
@@ -2724,7 +2853,7 @@ static void hb_vmLess( void )
hb_vmPushLogical( bLogical1 < bLogical2 );
}
else if( HB_IS_OBJECT( pItem1 ) && hb_objHasMsg( pItem1, "__OpLess" ) )
hb_vmOperatorCall( pItem1, pItem2, "__OPLESS" );
hb_vmOperatorCall( pItem1, pItem1, pItem2, "__OPLESS" );
else
{
PHB_ITEM pResult = hb_errRT_BASE_Subst( EG_ARG, 1073, NULL, "<", 2, pItem1, pItem2 );
@@ -2781,7 +2910,7 @@ static void hb_vmLessEqual( void )
hb_vmPushLogical( bLogical1 <= bLogical2 );
}
else if( HB_IS_OBJECT( pItem1 ) && hb_objHasMsg( pItem1, "__OpLessEqual" ) )
hb_vmOperatorCall( pItem1, pItem2, "__OPLESSEQUAL" );
hb_vmOperatorCall( pItem1, pItem1, pItem2, "__OPLESSEQUAL" );
else
{
PHB_ITEM pResult = hb_errRT_BASE_Subst( EG_ARG, 1074, NULL, "<=", 2, pItem1, pItem2 );
@@ -2838,7 +2967,7 @@ static void hb_vmGreater( void )
hb_vmPushLogical( bLogical1 > bLogical2 );
}
else if( HB_IS_OBJECT( pItem1 ) && hb_objHasMsg( pItem1, "__OpGreater" ) )
hb_vmOperatorCall( pItem1, pItem2, "__OPGREATER" );
hb_vmOperatorCall( pItem1, pItem1, pItem2, "__OPGREATER" );
else
{
PHB_ITEM pResult = hb_errRT_BASE_Subst( EG_ARG, 1075, NULL, ">", 2, pItem1, pItem2 );
@@ -2895,7 +3024,7 @@ static void hb_vmGreaterEqual( void )
hb_vmPushLogical( bLogical1 >= bLogical2 );
}
else if( HB_IS_OBJECT( pItem1 ) && hb_objHasMsg( pItem1, "__OpGreaterEqual" ) )
hb_vmOperatorCall( pItem1, pItem2, "__OPGREATEREQUAL" );
hb_vmOperatorCall( pItem1, pItem1, pItem2, "__OPGREATEREQUAL" );
else
{
PHB_ITEM pResult = hb_errRT_BASE_Subst( EG_ARG, 1076, NULL, ">=", 2, pItem1, pItem2 );
@@ -2929,7 +3058,7 @@ static void hb_vmInstring( void )
hb_vmPushLogical( bResult );
}
else if( HB_IS_OBJECT( pItem1 ) && hb_objHasMsg( pItem1, "__OpInstring" ) )
hb_vmOperatorCall( pItem1, pItem2, "__OPINSTRING" );
hb_vmOperatorCall( pItem1, pItem1, pItem2, "__OPINSTRING" );
else
{
PHB_ITEM pResult = hb_errRT_BASE_Subst( EG_ARG, 1109, NULL, "$", 2, pItem1, pItem2 );
@@ -3399,7 +3528,7 @@ static void hb_vmAnd( void )
hb_stackDec();
}
else if( HB_IS_OBJECT( pItem1 ) && hb_objHasMsg( pItem1, "__OpAnd" ) )
hb_vmOperatorCall( pItem1, pItem2, "__OPAND" );
hb_vmOperatorCall( pItem1, pItem1, pItem2, "__OPAND" );
else
{
PHB_ITEM pResult = hb_errRT_BASE_Subst( EG_ARG, 1078, NULL, ".AND.", 2, pItem1, pItem2 );
@@ -3431,7 +3560,7 @@ static void hb_vmOr( void )
hb_stackDec();
}
else if( HB_IS_OBJECT( pItem1 ) && hb_objHasMsg( pItem1, "__OpOr" ) )
hb_vmOperatorCall( pItem1, pItem2, "__OPOR" );
hb_vmOperatorCall( pItem1, pItem1, pItem2, "__OPOR" );
else
{
PHB_ITEM pResult = hb_errRT_BASE_Subst( EG_ARG, 1079, NULL, ".OR.", 2, pItem1, pItem2 );
@@ -3505,7 +3634,7 @@ static void hb_vmArrayPush( void )
if( HB_IS_OBJECT( pArray ) && hb_objHasMsg( pArray, "__OpArrayIndex" ) )
{
hb_vmOperatorCall( pArray, pIndex, "__OPARRAYINDEX" );
hb_vmOperatorCall( pArray, pArray, pIndex, "__OPARRAYINDEX" );
return;
}
@@ -3699,14 +3828,14 @@ static void hb_vmArrayNew( HB_ITEM_PTR pArray, USHORT uiDimension )
/* Object */
/* ------------------------------- */
static void hb_vmOperatorCall( PHB_ITEM pObjItem, PHB_ITEM pMsgItem, char * szSymbol )
static void hb_vmOperatorCall( HB_ITEM_PTR pResult, PHB_ITEM pObjItem, PHB_ITEM pMsgItem, char * szSymbol )
{
/* NOTE: There is no need to test if specified symbol exists. It is checked
* by the caller (if HB_IS_OBJECT() && HAS_METHOD() )
*/
HB_ITEM ItemMsg;
HB_TRACE(HB_TR_DEBUG, ("hb_vmOperatorCall(%p, %p, %s)", pObjItem, pMsgItem, szSymbol));
HB_TRACE(HB_TR_DEBUG, ("hb_vmOperatorCall(%p, %p, %p, %s)", pResult, pObjItem, pMsgItem, szSymbol));
ItemMsg.type = HB_IT_SYMBOL;
ItemMsg.item.asSymbol.value = hb_dynsymFind( szSymbol )->pSymbol;
@@ -3726,7 +3855,7 @@ static void hb_vmOperatorCall( PHB_ITEM pObjItem, PHB_ITEM pMsgItem, char * szSy
* NOTE: for performance reason we don't pop the second argument.
* We can replace the second argument with the return value.
*/
hb_itemCopy( pObjItem, &hb_stack.Return );
hb_itemCopy( pResult, &hb_stack.Return );
}
static void hb_vmOperatorCallUnary( PHB_ITEM pObjItem, char * szSymbol )
@@ -5500,7 +5629,7 @@ static void hb_vmPopLocal( SHORT iLocal )
hb_itemInit( &item );
hb_itemCopy( &item, hb_stackTopItem() );
hb_vmOperatorCall( pLocal, &item, "__OPASSIGN" );
hb_vmOperatorCall( pLocal, pLocal, &item, "__OPASSIGN" );
hb_itemClear( &item );
hb_stackPush();
return;
@@ -5535,7 +5664,7 @@ static void hb_vmPopStatic( USHORT uiStatic )
hb_itemInit( &item );
hb_itemCopy( &item, hb_stackTopItem() );
hb_vmOperatorCall( pStatic, &item, "__OPASSIGN" );
hb_vmOperatorCall( pStatic, pStatic, &item, "__OPASSIGN" );
hb_itemClear( &item );
hb_stackPush();
return;

View File

@@ -893,6 +893,76 @@ HB_EXPORT PHB_ITEM hb_itemPutNDLen( PHB_ITEM pItem, double dNumber, int iWidth,
return pItem;
}
HB_EXPORT PHB_ITEM hb_itemPutNDDec( PHB_ITEM pItem, double dNumber, int iDec )
{
HB_TRACE_STEALTH(HB_TR_DEBUG, ("hb_itemPutNDDec(%p, %lf, %i)", pItem, dNumber, iDec));
if( pItem )
{
if( HB_IS_COMPLEX( pItem ) )
{
hb_itemClear( pItem );
}
}
else
{
pItem = hb_itemNew( NULL );
}
pItem->type = HB_IT_DOUBLE;
pItem->item.asDouble.length = HB_DBL_LENGTH( dNumber );
if( iDec == HB_DEFAULT_DECIMALS )
{
pItem->item.asDouble.decimal = hb_set.HB_SET_DECIMALS;
}
else
{
pItem->item.asDouble.decimal = iDec;
}
pItem->item.asDouble.value = dNumber;
return pItem;
}
HB_EXPORT double hb_itemGetNDDec( PHB_ITEM pItem, int * piDec )
{
double dNumber;
HB_TRACE(HB_TR_DEBUG, ("hb_itemGetNDDec(%p,p%)", pItem, piDec));
switch( pItem->type )
{
case HB_IT_INTEGER:
dNumber = ( double ) pItem->item.asInteger.value;
*piDec = 0;
break;
case HB_IT_LONG:
dNumber = ( double ) pItem->item.asLong.value;
*piDec = 0;
break;
case HB_IT_DOUBLE:
dNumber = pItem->item.asDouble.value;
*piDec = pItem->item.asDouble.decimal;
break;
case HB_IT_DATE:
dNumber = (double) pItem->item.asDate.value;
*piDec = 0;
break;
default:
dNumber = 0; /* To avoid GCC -O2 warning */
break;
}
return dNumber;
}
HB_EXPORT PHB_ITEM hb_itemPutNILen( PHB_ITEM pItem, int iNumber, int iWidth )
{
HB_TRACE(HB_TR_DEBUG, ("hb_itemPutNILen(%p, %d, %d)", pItem, iNumber, iWidth));
@@ -979,6 +1049,51 @@ HB_EXPORT PHB_ITEM hb_itemPutNLLLen( PHB_ITEM pItem, LONGLONG llNumber, int iWid
}
#endif
HB_EXPORT PHB_ITEM hb_itemPutHBLong( PHB_ITEM pItem, HB_LONG lNumber )
{
HB_TRACE(HB_TR_DEBUG, ("hb_itemPutHBLong( %p, %" PFHL "d)", pItem, lNumber));
if( pItem )
{
if( HB_IS_COMPLEX( pItem ) )
{
hb_itemClear( pItem );
}
}
else
{
pItem = hb_itemNew( NULL );
}
pItem->type = HB_IT_LONG;
pItem->item.asLong.value = lNumber;
pItem->item.asLong.length = HB_LONG_LENGTH( lNumber );
return pItem;
}
HB_EXPORT PHB_ITEM hb_itemPutNumType( PHB_ITEM pItem, double dNumber, int iDec, int iType1, int iType2 )
{
HB_TRACE(HB_TR_DEBUG, ("hb_itemPutNumType( %p, %lf, %d, %i, %i)", pItem, dNumber, iDec, iType1, iType2));
if( iDec || iType1 & HB_IT_DOUBLE || iType2 & HB_IT_DOUBLE )
{
return hb_itemPutNDDec( pItem, dNumber, iDec );
}
else if ( HB_DBL_LIM_INT( dNumber ) )
{
return hb_itemPutNI( pItem, ( int ) dNumber );
}
else if ( HB_DBL_LIM_LONG( dNumber ) )
{
return hb_itemPutHBLong( pItem, ( HB_LONG ) dNumber );
}
else
{
return hb_itemPutND( pItem, dNumber );
}
}
HB_EXPORT PHB_ITEM hb_itemPutPtr( PHB_ITEM pItem, void * pValue )
{
HB_TRACE(HB_TR_DEBUG, ("hb_itemPutPtr(%p, %p)", pItem, pValue));