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:
@@ -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
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -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 ) */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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_ */
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -60,6 +60,8 @@ C_SOURCES=\
|
||||
C_MAIN=harbour.c
|
||||
|
||||
LIBS=\
|
||||
ccmalloc \
|
||||
dl \
|
||||
pp \
|
||||
common \
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -376,7 +376,6 @@ void hb_pp_Free( void )
|
||||
hb_xfree( (void *)hb_pp_aCondCompile );
|
||||
hb_pp_aCondCompile = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void hb_pp_Init( void )
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user