+ added support for passing methods as macro
eg:
o:&send()
o:&send.end()
o:&(expr)()
o:&var++
o:&var := 0
o:&(expr)++
WITH OBJECT obj
++:&var
:&var += :&(var2+"oo")
END
NOTICE:
For simple assigments (=,:=), compound assignments (+=,-=,*=,/=)
and for pre/post increment operators( ++,--) the macro should
evaluate to a symbol that starts with underscore '_'.
To access a variable the macro should evaluate to a symbol
with no '_' char.
This commit is contained in:
@@ -8,6 +8,45 @@
|
||||
2002-12-01 13:30 UTC+0100 Foo Bar <foo.bar@foobar.org>
|
||||
*/
|
||||
|
||||
2006-09-28 11:10 UTC+0100 Ryszard Glab <rglab//imid.med.pl>
|
||||
|
||||
* harbour/source/rdd/workarea.c
|
||||
* minor modification
|
||||
|
||||
* harbour/source/rdd/dbfcdx/dbfcdx1.c
|
||||
* minor Clipper compatibility update
|
||||
|
||||
2006-09-29 11:20 UTC+0100 Ryszard Glab <rglab//imid.med.pl>
|
||||
* tests/Makefile
|
||||
+ added omacro.prg and varparam.prg
|
||||
* ChangeLog
|
||||
* fixed date in previous commit
|
||||
|
||||
2006-09-29 11:10 UTC+0100 Ryszard Glab <rglab//imid.med.pl>
|
||||
* include/hbexpra.c
|
||||
* include/hbexprb.c
|
||||
* include/hbexprc.c
|
||||
* include/hbexprop.h
|
||||
* source/common/expropt1.c
|
||||
* source/compiler/expropta.c
|
||||
* source/compiler/exproptb.c
|
||||
* source/compiler/exproptc.c
|
||||
* source/compiler/harbour.c
|
||||
* source/compiler/harbour.y
|
||||
* source/macro/macro.y
|
||||
* source/macro/macroa.c
|
||||
* source/macro/macrob.c
|
||||
|
||||
* source/vm/hvm.c
|
||||
+ added support for passing methods as macro
|
||||
|
||||
o:&send()
|
||||
o:&send.end()
|
||||
and for pre/post increment operators( ++,--) the macro should
|
||||
o:&var++
|
||||
o:&var := 0
|
||||
o:&(expr)++
|
||||
WITH OBJECT obj
|
||||
++:&var
|
||||
:&var += :&(var2+"oo")
|
||||
END
|
||||
|
||||
@@ -392,9 +392,9 @@ HB_EXPR_PTR hb_compExprNewFunCall( HB_EXPR_PTR pName, HB_EXPR_PTR pParms )
|
||||
/* Optimize Eval( bBlock, [ArgList] ) to: bBlock:Eval( [ArgList] ) */
|
||||
pEval = hb_compExprNewMethodCall(
|
||||
#ifndef HB_MACRO_SUPPORT
|
||||
hb_compExprNewSend( pParms->value.asList.pExprList, hb_compIdentifierNew( "EVAL", TRUE ) ),
|
||||
hb_compExprNewSend( pParms->value.asList.pExprList, hb_compIdentifierNew( "EVAL", TRUE ), NULL ),
|
||||
#else
|
||||
hb_compExprNewSend( pParms->value.asList.pExprList, hb_strdup("EVAL") ),
|
||||
hb_compExprNewSend( pParms->value.asList.pExprList, hb_strdup("EVAL"), NULL ),
|
||||
#endif
|
||||
hb_compExprNewArgList( pParms->value.asList.pExprList->pNext ) );
|
||||
|
||||
@@ -651,34 +651,51 @@ HB_EXPR_PTR hb_compExprNewFunCall( HB_EXPR_PTR pName, HB_EXPR_PTR pParms )
|
||||
/* Creates new send expression
|
||||
* pObject : szMessage
|
||||
*/
|
||||
HB_EXPR_PTR hb_compExprNewSend( HB_EXPR_PTR pObject, char * szMessage )
|
||||
HB_EXPR_PTR hb_compExprNewSend( HB_EXPR_PTR pObject, char * szMessage, HB_EXPR_PTR pMessage )
|
||||
{
|
||||
HB_EXPR_PTR pExpr;
|
||||
|
||||
HB_TRACE(HB_TR_DEBUG, ("hb_compExprNewSend(%p, %s)", pObject, szMessage));
|
||||
|
||||
pExpr = hb_compExprNew( HB_ET_SEND );
|
||||
pExpr->value.asMessage.szMessage = szMessage;
|
||||
pExpr->value.asMessage.pObject = pObject;
|
||||
pExpr->value.asMessage.pParms = NULL;
|
||||
|
||||
#ifndef HB_MACRO_SUPPORT
|
||||
if( (strcmp( "__ENUMINDEX", szMessage ) == 0) ||
|
||||
(strcmp( "__ENUMBASE", szMessage ) == 0 ) ||
|
||||
(strcmp( "__ENUMVALUE", szMessage ) == 0 ) )
|
||||
if( szMessage != NULL )
|
||||
{
|
||||
if( pObject->ExprType == HB_ET_VARIABLE )
|
||||
pExpr->value.asMessage.szMessage = szMessage;
|
||||
pExpr->value.asMessage.pMessage = NULL;
|
||||
#ifndef HB_MACRO_SUPPORT
|
||||
if( (strcmp( "__ENUMINDEX", szMessage ) == 0) ||
|
||||
(strcmp( "__ENUMBASE", szMessage ) == 0 ) ||
|
||||
(strcmp( "__ENUMVALUE", szMessage ) == 0 ) )
|
||||
{
|
||||
if( ! hb_compForEachVarError( pObject->value.asSymbol ) )
|
||||
if( pObject->ExprType == HB_ET_VARIABLE )
|
||||
{
|
||||
if( ! hb_compForEachVarError( pObject->value.asSymbol ) )
|
||||
{
|
||||
/* pExpr->value.asMessage.pObject = hb_compExprNewVarRef( pObject->value.asSymbol );*/
|
||||
/* NOTE: direct type change */
|
||||
pObject->ExprType = HB_ET_VARREF;
|
||||
pExpr->value.asMessage.pObject = pObject;
|
||||
/* NOTE: direct type change */
|
||||
pObject->ExprType = HB_ET_VARREF;
|
||||
pExpr->value.asMessage.pObject = pObject;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
pExpr->value.asMessage.pMessage = pMessage;
|
||||
pExpr->value.asMessage.szMessage = NULL;
|
||||
if( pMessage->ExprType == HB_ET_MACRO )
|
||||
{
|
||||
/* Signal that macro compiler have to generate a pcode that will
|
||||
* return function name as symbol instead of usual value
|
||||
*/
|
||||
pMessage->value.asMacro.SubType = HB_ET_MACRO_SYMBOL;
|
||||
}
|
||||
}
|
||||
|
||||
return pExpr;
|
||||
}
|
||||
|
||||
|
||||
@@ -2217,7 +2217,18 @@ static HB_EXPR_FUNC( hb_compExprUseSend )
|
||||
{
|
||||
BOOL fMacroList = FALSE;
|
||||
int iParms = hb_compExprListLen( pSelf->value.asMessage.pParms );
|
||||
HB_EXPR_PCODE2( hb_compGenMessage, pSelf->value.asMessage.szMessage, bIsObject );
|
||||
if( pSelf->value.asMessage.szMessage )
|
||||
{
|
||||
HB_EXPR_PCODE2( hb_compGenMessage, pSelf->value.asMessage.szMessage, bIsObject );
|
||||
}
|
||||
else
|
||||
{
|
||||
HB_EXPR_USE( pSelf->value.asMessage.pMessage, HB_EA_PUSH_PCODE );
|
||||
if( ! bIsObject )
|
||||
{
|
||||
HB_EXPR_PCODE2( hb_compGenMessage, NULL, bIsObject );
|
||||
}
|
||||
}
|
||||
if( bIsObject )
|
||||
{
|
||||
HB_EXPR_USE( pSelf->value.asMessage.pObject, HB_EA_PUSH_PCODE );
|
||||
@@ -2267,7 +2278,18 @@ static HB_EXPR_FUNC( hb_compExprUseSend )
|
||||
else
|
||||
{
|
||||
/* acces to instance variable */
|
||||
HB_EXPR_PCODE2( hb_compGenMessage, pSelf->value.asMessage.szMessage, bIsObject );
|
||||
if( pSelf->value.asMessage.szMessage )
|
||||
{
|
||||
HB_EXPR_PCODE2( hb_compGenMessage, pSelf->value.asMessage.szMessage, bIsObject );
|
||||
}
|
||||
else
|
||||
{
|
||||
HB_EXPR_USE( pSelf->value.asMessage.pMessage, HB_EA_PUSH_PCODE );
|
||||
if( ! bIsObject )
|
||||
{
|
||||
HB_EXPR_PCODE2( hb_compGenMessage, NULL, bIsObject );
|
||||
}
|
||||
}
|
||||
if( bIsObject )
|
||||
{
|
||||
HB_EXPR_USE( pSelf->value.asMessage.pObject, HB_EA_PUSH_PCODE );
|
||||
@@ -2285,7 +2307,18 @@ static HB_EXPR_FUNC( hb_compExprUseSend )
|
||||
/* NOTE: This is an exception from the rule - this leaves
|
||||
* the return value on the stack
|
||||
*/
|
||||
HB_EXPR_PCODE2( hb_compGenMessageData, pSelf->value.asMessage.szMessage, bIsObject );
|
||||
if( pSelf->value.asMessage.szMessage )
|
||||
{
|
||||
HB_EXPR_PCODE2( hb_compGenMessageData, pSelf->value.asMessage.szMessage, bIsObject );
|
||||
}
|
||||
else
|
||||
{
|
||||
HB_EXPR_USE( pSelf->value.asMessage.pMessage, HB_EA_PUSH_PCODE );
|
||||
if( ! bIsObject )
|
||||
{
|
||||
HB_EXPR_PCODE2( hb_compGenMessage, NULL, bIsObject );
|
||||
}
|
||||
}
|
||||
if( bIsObject )
|
||||
{
|
||||
HB_EXPR_USE( pSelf->value.asMessage.pObject, HB_EA_PUSH_PCODE );
|
||||
@@ -2319,6 +2352,10 @@ static HB_EXPR_FUNC( hb_compExprUseSend )
|
||||
{
|
||||
HB_EXPR_PCODE1( hb_compExprDelete, pSelf->value.asMessage.pParms );
|
||||
}
|
||||
if( pSelf->value.asMessage.pMessage )
|
||||
{
|
||||
HB_EXPR_PCODE1( hb_compExprDelete, pSelf->value.asMessage.pMessage );
|
||||
}
|
||||
#if defined( HB_MACRO_SUPPORT )
|
||||
HB_XFREE( pSelf->value.asMessage.szMessage );
|
||||
#endif
|
||||
|
||||
@@ -80,21 +80,30 @@ static void hb_compExprSendPopPush( HB_EXPR_PTR pObj )
|
||||
if( pObj->value.asMessage.pObject )
|
||||
{
|
||||
/* Push _message for later use */
|
||||
HB_EXPR_PCODE2( hb_compGenMessageData, pObj->value.asMessage.szMessage, TRUE );
|
||||
/* Push object */
|
||||
HB_EXPR_USE( pObj->value.asMessage.pObject, HB_EA_PUSH_PCODE );
|
||||
|
||||
/* Now push current value of variable */
|
||||
HB_EXPR_PCODE2( hb_compGenMessage, pObj->value.asMessage.szMessage, TRUE );
|
||||
if( pObj->value.asMessage.szMessage )
|
||||
{
|
||||
HB_EXPR_PCODE2( hb_compGenMessageData, pObj->value.asMessage.szMessage, TRUE );
|
||||
}
|
||||
else
|
||||
{
|
||||
HB_EXPR_USE( pObj->value.asMessage.pMessage, HB_EA_PUSH_PCODE );
|
||||
}
|
||||
/* Push object */
|
||||
HB_EXPR_USE( pObj->value.asMessage.pObject, HB_EA_PUSH_PCODE );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Push _message for later use */
|
||||
HB_EXPR_PCODE2( hb_compGenMessageData, pObj->value.asMessage.szMessage, FALSE );
|
||||
/* Now push current value of variable */
|
||||
HB_EXPR_PCODE2( hb_compGenMessage, pObj->value.asMessage.szMessage, FALSE );
|
||||
if( pObj->value.asMessage.szMessage )
|
||||
{
|
||||
HB_EXPR_PCODE2( hb_compGenMessageData, pObj->value.asMessage.szMessage, FALSE );
|
||||
}
|
||||
else
|
||||
{
|
||||
HB_EXPR_USE( pObj->value.asMessage.pMessage, HB_EA_PUSH_PCODE );
|
||||
/* Push WITHOBJECTMESSAGE pcode */
|
||||
HB_EXPR_PCODE2( hb_compGenMessage, NULL, FALSE );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,7 +136,7 @@ void hb_compExprPushOperEq( HB_EXPR_PTR pSelf, BYTE bOpEq )
|
||||
{
|
||||
HB_EXPR_PCODE1( hb_compExprSendPopPush, pSelf->value.asOperator.pLeft );
|
||||
/* Do it. */
|
||||
HB_EXPR_GENPCODE2( hb_compGenPCode2, HB_P_SENDSHORT, 0, ( BOOL ) 1 );
|
||||
HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_PUSHOVARREF );
|
||||
|
||||
/* NOTE: COMPATIBILITY ISSUE:
|
||||
* The above HB_C52_STRICT setting determines
|
||||
@@ -157,10 +166,22 @@ void hb_compExprPushOperEq( HB_EXPR_PTR pSelf, BYTE bOpEq )
|
||||
/* push increment value */
|
||||
HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE );
|
||||
/* increase operation */
|
||||
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 );
|
||||
|
||||
/* call pop message with one argument */
|
||||
HB_EXPR_GENPCODE2( hb_compGenPCode2, HB_P_SENDSHORT, 1, ( BOOL ) 1 );
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -287,18 +308,27 @@ void hb_compExprUseOperEq( HB_EXPR_PTR pSelf, BYTE bOpEq )
|
||||
{
|
||||
HB_EXPR_PCODE1( hb_compExprSendPopPush, pSelf->value.asOperator.pLeft );
|
||||
/* Do it.*/
|
||||
HB_EXPR_GENPCODE2( hb_compGenPCode2, HB_P_SENDSHORT, 0, ( BOOL ) 1 );
|
||||
HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_PUSHOVARREF );
|
||||
|
||||
/* push increment value */
|
||||
HB_EXPR_USE( pSelf->value.asOperator.pRight, HB_EA_PUSH_PCODE );
|
||||
/* increase operation */
|
||||
/* increase operation and pop the unneeded value from the stack */
|
||||
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 );
|
||||
|
||||
/* Now do the assignment - call pop message with one argument */
|
||||
HB_EXPR_GENPCODE2( hb_compGenPCode2, HB_P_SENDSHORT, 1, ( BOOL ) 1 );
|
||||
|
||||
/* pop the unneeded value from the stack */
|
||||
HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_POP );
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -425,13 +455,10 @@ void hb_compExprPushPreOp( HB_EXPR_PTR pSelf, BYTE bOper )
|
||||
{
|
||||
HB_EXPR_PCODE1( hb_compExprSendPopPush, pSelf->value.asOperator.pLeft );
|
||||
/* Do it. */
|
||||
HB_EXPR_GENPCODE2( hb_compGenPCode2, HB_P_SENDSHORT, 0, ( BOOL ) 1 );
|
||||
HB_EXPR_GENPCODE1( hb_compGenPCode1, HB_P_PUSHOVARREF );
|
||||
|
||||
/* increase/decrease operation */
|
||||
HB_EXPR_GENPCODE1( hb_compGenPCode1, bOper );
|
||||
|
||||
/* Now, do the assignment - call pop message with one argument - it leaves the value on the stack */
|
||||
HB_EXPR_GENPCODE2( hb_compGenPCode2, HB_P_SENDSHORT, 1, ( BOOL ) 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -231,8 +231,9 @@ typedef struct HB_EXPR_
|
||||
struct
|
||||
{
|
||||
struct HB_EXPR_ *pObject; /* object */
|
||||
char * szMessage; /* message */
|
||||
struct HB_EXPR_ *pParms; /* method parameters */
|
||||
char * szMessage; /* message as string */
|
||||
struct HB_EXPR_ *pMessage; /* message as macro */
|
||||
} asMessage;
|
||||
struct
|
||||
{
|
||||
@@ -359,7 +360,7 @@ HB_EXPR_PTR hb_compExprNewFunRef( char * );
|
||||
HB_EXPR_PTR hb_compExprNewRef( HB_EXPR_PTR );
|
||||
HB_EXPR_PTR hb_compExprNewCodeblockExpr( HB_EXPR_PTR, HB_EXPR_PTR );
|
||||
HB_EXPR_PTR hb_compExprNewFunCallArg( HB_EXPR_PTR, HB_EXPR_PTR );
|
||||
HB_EXPR_PTR hb_compExprNewSend( HB_EXPR_PTR, char * );
|
||||
HB_EXPR_PTR hb_compExprNewSend( HB_EXPR_PTR, char *szMessage, HB_EXPR_PTR pMessage );
|
||||
HB_EXPR_PTR hb_compExprNewMethodCall( HB_EXPR_PTR, HB_EXPR_PTR );
|
||||
HB_EXPR_PTR hb_compExprNewList( HB_EXPR_PTR );
|
||||
HB_EXPR_PTR hb_compExprNewArgList( HB_EXPR_PTR );
|
||||
|
||||
@@ -499,7 +499,7 @@ HB_EXPR_PTR hb_compExprNewAliasExpr( HB_EXPR_PTR pAlias, HB_EXPR_PTR pExpList )
|
||||
/* Creates new method call
|
||||
* pObject : identifier ( pArgList )
|
||||
*
|
||||
* pObject = is an expression returned by hb_compExprNewSend
|
||||
* pObject = is an expression returned by hb_compExprNewSend
|
||||
* pArgList = list of passed arguments - it will be HB_ET_NONE if no arguments
|
||||
* are passed
|
||||
*/
|
||||
|
||||
@@ -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.22 - ignore this magic number - this is used to force compilation
|
||||
* 1.23 - 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.19 - ignore this magic number - this is used to force compilation
|
||||
* 1.20 - 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.10 - ignore this magic number - this is used to force compilation
|
||||
* 1.11 - ignore this magic number - this is used to force compilation
|
||||
*/
|
||||
#include "hbexprc.c"
|
||||
|
||||
@@ -2903,15 +2903,25 @@ void hb_compGenVarPCode( BYTE bPCode, char * szVarName )
|
||||
void hb_compGenMessage( char * szMsgName, BOOL bIsObject )
|
||||
{
|
||||
USHORT wSym;
|
||||
PCOMSYMBOL pSym = hb_compSymbolFind( szMsgName, &wSym, HB_SYM_MSGNAME );
|
||||
PCOMSYMBOL pSym;
|
||||
|
||||
if( szMsgName )
|
||||
{
|
||||
pSym = hb_compSymbolFind( szMsgName, &wSym, HB_SYM_MSGNAME );
|
||||
|
||||
if( ! pSym ) /* the symbol was not found on the symbol table */
|
||||
pSym = hb_compSymbolAdd( szMsgName, &wSym, HB_SYM_MSGNAME );
|
||||
pSym->cScope |= HB_FS_MESSAGE;
|
||||
if( bIsObject )
|
||||
hb_compGenPCode3( HB_P_MESSAGE, HB_LOBYTE( wSym ), HB_HIBYTE( wSym ), ( BOOL ) 1 );
|
||||
if( ! pSym ) /* the symbol was not found on the symbol table */
|
||||
pSym = hb_compSymbolAdd( szMsgName, &wSym, HB_SYM_MSGNAME );
|
||||
pSym->cScope |= HB_FS_MESSAGE;
|
||||
if( bIsObject )
|
||||
hb_compGenPCode3( HB_P_MESSAGE, HB_LOBYTE( wSym ), HB_HIBYTE( wSym ), ( BOOL ) 1 );
|
||||
else
|
||||
hb_compGenPCode3( HB_P_WITHOBJECTMESSAGE, HB_LOBYTE( wSym ), HB_HIBYTE( wSym ), ( BOOL ) 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
wSym = 0xFFFF;
|
||||
hb_compGenPCode3( HB_P_WITHOBJECTMESSAGE, HB_LOBYTE( wSym ), HB_HIBYTE( wSym ), ( BOOL ) 1 );
|
||||
}
|
||||
}
|
||||
|
||||
void hb_compGenMessageData( char * szMsg, BOOL bIsObject ) /* generates an underscore-symbol name for a data assignment */
|
||||
|
||||
@@ -212,6 +212,15 @@ static void hb_compDebugStart( void ) { };
|
||||
BOOL lateEval; /* Flag for early {|| ¯o} (0) or late {|| &(macro)} (1) binding */
|
||||
BOOL isMacro;
|
||||
} asCodeblock;
|
||||
struct
|
||||
{
|
||||
BOOL bMacro;
|
||||
union
|
||||
{
|
||||
char *string;
|
||||
HB_EXPR_PTR macro;
|
||||
} value;
|
||||
} asMessage;
|
||||
void * pVoid; /* to hold any memory structure we may need */
|
||||
};
|
||||
|
||||
@@ -258,7 +267,7 @@ static void hb_compDebugStart( void ) { };
|
||||
%right '\n' ';' ','
|
||||
/*the highest precedence*/
|
||||
|
||||
%type <string> IdentName IDENTIFIER LITERAL SendId MACROVAR MACROTEXT CompTimeStr
|
||||
%type <string> IdentName IDENTIFIER LITERAL MACROVAR MACROTEXT CompTimeStr
|
||||
%type <string> DOIDENT WHILE
|
||||
%type <valDouble> NUM_DOUBLE
|
||||
%type <valInteger> NUM_INTEGER
|
||||
@@ -305,6 +314,7 @@ static void hb_compDebugStart( void ) { };
|
||||
%type <asExpr> ForVar ForList ForExpr
|
||||
%type <asCodeblock> CBSTART
|
||||
%type <asExpr> DateValue
|
||||
%type <asMessage> SendId
|
||||
|
||||
%%
|
||||
|
||||
@@ -743,33 +753,34 @@ FunCallAlias : FunCall ALIASOP { $$ = $1; }
|
||||
|
||||
/* Object's instance variable
|
||||
*/
|
||||
SendId : IdentName { $$ = $1; }
|
||||
| MacroVar { $$ = "&"; hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_INVALID_SEND, "&", NULL); }
|
||||
SendId : IdentName { $$.value.string = $1; $$.bMacro=FALSE; }
|
||||
| MacroVar { $$.value.macro = $1; $$.bMacro=TRUE; }
|
||||
| MacroExpr { $$.value.macro = $1; $$.bMacro=TRUE; }
|
||||
;
|
||||
|
||||
ObjectData : NumValue ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| NilValue ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| DateValue ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| LiteralValue ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| Variable ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| CodeBlock ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| Logical ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| SelfValue ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| Array ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| ArrayAt ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| AliasVar ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| AliasExpr ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| MacroVar ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| MacroExpr ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| FunCall ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| IfInline ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| PareExpList ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| VariableAt ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| ObjectMethod ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| ObjectData ':' SendId { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
ObjectData : NumValue ':' SendId { $$ = ($3.bMacro ? hb_compExprNewSend( $1, NULL, $3.value.macro ) : hb_compExprNewSend( $1, $3.value.string, NULL )); }
|
||||
| NilValue ':' SendId { $$ = ($3.bMacro ? hb_compExprNewSend( $1, NULL, $3.value.macro ) : hb_compExprNewSend( $1, $3.value.string, NULL )); }
|
||||
| DateValue ':' SendId { $$ = ($3.bMacro ? hb_compExprNewSend( $1, NULL, $3.value.macro ) : hb_compExprNewSend( $1, $3.value.string, NULL )); }
|
||||
| LiteralValue ':' SendId { $$ = ($3.bMacro ? hb_compExprNewSend( $1, NULL, $3.value.macro ) : hb_compExprNewSend( $1, $3.value.string, NULL )); }
|
||||
| Variable ':' SendId { $$ = ($3.bMacro ? hb_compExprNewSend( $1, NULL, $3.value.macro ) : hb_compExprNewSend( $1, $3.value.string, NULL )); }
|
||||
| CodeBlock ':' SendId { $$ = ($3.bMacro ? hb_compExprNewSend( $1, NULL, $3.value.macro ) : hb_compExprNewSend( $1, $3.value.string, NULL )); }
|
||||
| Logical ':' SendId { $$ = ($3.bMacro ? hb_compExprNewSend( $1, NULL, $3.value.macro ) : hb_compExprNewSend( $1, $3.value.string, NULL )); }
|
||||
| SelfValue ':' SendId { $$ = ($3.bMacro ? hb_compExprNewSend( $1, NULL, $3.value.macro ) : hb_compExprNewSend( $1, $3.value.string, NULL )); }
|
||||
| Array ':' SendId { $$ = ($3.bMacro ? hb_compExprNewSend( $1, NULL, $3.value.macro ) : hb_compExprNewSend( $1, $3.value.string, NULL )); }
|
||||
| ArrayAt ':' SendId { $$ = ($3.bMacro ? hb_compExprNewSend( $1, NULL, $3.value.macro ) : hb_compExprNewSend( $1, $3.value.string, NULL )); }
|
||||
| AliasVar ':' SendId { $$ = ($3.bMacro ? hb_compExprNewSend( $1, NULL, $3.value.macro ) : hb_compExprNewSend( $1, $3.value.string, NULL )); }
|
||||
| AliasExpr ':' SendId { $$ = ($3.bMacro ? hb_compExprNewSend( $1, NULL, $3.value.macro ) : hb_compExprNewSend( $1, $3.value.string, NULL )); }
|
||||
| MacroVar ':' SendId { $$ = ($3.bMacro ? hb_compExprNewSend( $1, NULL, $3.value.macro ) : hb_compExprNewSend( $1, $3.value.string, NULL )); }
|
||||
| MacroExpr ':' SendId { $$ = ($3.bMacro ? hb_compExprNewSend( $1, NULL, $3.value.macro ) : hb_compExprNewSend( $1, $3.value.string, NULL )); }
|
||||
| FunCall ':' SendId { $$ = ($3.bMacro ? hb_compExprNewSend( $1, NULL, $3.value.macro ) : hb_compExprNewSend( $1, $3.value.string, NULL )); }
|
||||
| IfInline ':' SendId { $$ = ($3.bMacro ? hb_compExprNewSend( $1, NULL, $3.value.macro ) : hb_compExprNewSend( $1, $3.value.string, NULL )); }
|
||||
| PareExpList ':' SendId { $$ = ($3.bMacro ? hb_compExprNewSend( $1, NULL, $3.value.macro ) : hb_compExprNewSend( $1, $3.value.string, NULL )); }
|
||||
| VariableAt ':' SendId { $$ = ($3.bMacro ? hb_compExprNewSend( $1, NULL, $3.value.macro ) : hb_compExprNewSend( $1, $3.value.string, NULL )); }
|
||||
| ObjectMethod ':' SendId { $$ = ($3.bMacro ? hb_compExprNewSend( $1, NULL, $3.value.macro ) : hb_compExprNewSend( $1, $3.value.string, NULL )); }
|
||||
| ObjectData ':' SendId { $$ = ($3.bMacro ? hb_compExprNewSend( $1, NULL, $3.value.macro ) : hb_compExprNewSend( $1, $3.value.string, NULL )); }
|
||||
| ':' SendId { if( hb_comp_wWithObjectCnt == 0 )
|
||||
hb_compGenError( hb_comp_szErrors, 'E', HB_COMP_ERR_WITHOBJECT, NULL, NULL );
|
||||
$$ = hb_compExprNewSend( NULL, $2 );
|
||||
$$ = ($2.bMacro ? hb_compExprNewSend( NULL, NULL, $2.value.macro ) : hb_compExprNewSend( NULL, $2.value.string, NULL ));
|
||||
}
|
||||
;
|
||||
|
||||
@@ -1906,9 +1917,7 @@ DoArgument : IdentName { $$ = hb_compExprNewVarRef( $1 ); }
|
||||
| '@' MacroVar { $$ = hb_compExprNewRef( $2 ); }
|
||||
| '@' AliasVar { $$ = hb_compExprNewRef( $2 ); }
|
||||
;
|
||||
/*
|
||||
| '@' IdentName { $$ = hb_compExprNewVarRef( $2 ); }
|
||||
*/
|
||||
|
||||
WithObject : WITHOBJECT Expression Crlf
|
||||
{
|
||||
hb_compExprDelete( hb_compExprGenPush( $2 ) );
|
||||
|
||||
@@ -443,26 +443,26 @@ Argument : EmptyExpression { $$ = $1; }
|
||||
|
||||
/* Object's instance variable
|
||||
*/
|
||||
ObjectData : NumValue ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| NilValue ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| DateValue ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| LiteralValue ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| CodeBlock ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| Logical ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| SelfValue ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| Array ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| ArrayAt ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| Variable ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| AliasVar ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| AliasExpr ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| MacroVar ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| MacroExpr ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| FunCall ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| IfInline ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| PareExpList ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| VariableAt ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| ObjectMethod ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
| ObjectData ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3 ); }
|
||||
ObjectData : NumValue ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3, NULL ); }
|
||||
| NilValue ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3, NULL ); }
|
||||
| DateValue ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3, NULL ); }
|
||||
| LiteralValue ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3, NULL ); }
|
||||
| CodeBlock ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3, NULL ); }
|
||||
| Logical ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3, NULL ); }
|
||||
| SelfValue ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3, NULL ); }
|
||||
| Array ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3, NULL ); }
|
||||
| ArrayAt ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3, NULL ); }
|
||||
| Variable ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3, NULL ); }
|
||||
| AliasVar ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3, NULL ); }
|
||||
| AliasExpr ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3, NULL ); }
|
||||
| MacroVar ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3, NULL ); }
|
||||
| MacroExpr ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3, NULL ); }
|
||||
| FunCall ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3, NULL ); }
|
||||
| IfInline ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3, NULL ); }
|
||||
| PareExpList ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3, NULL ); }
|
||||
| VariableAt ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3, NULL ); }
|
||||
| ObjectMethod ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3, NULL ); }
|
||||
| ObjectData ':' IDENTIFIER { $$ = hb_compExprNewSend( $1, $3, NULL ); }
|
||||
;
|
||||
|
||||
/* Object's method
|
||||
|
||||
@@ -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.20 - ignore this magic number - this is used to force compilation
|
||||
* 1.21 - 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.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 @@
|
||||
/* 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.9 - ignore this magic number - this is used to force compilation
|
||||
* 1.10 - ignore this magic number - this is used to force compilation
|
||||
*/
|
||||
|
||||
#define HB_MACRO_SUPPORT
|
||||
|
||||
@@ -1801,10 +1801,20 @@ HB_EXPORT void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols )
|
||||
/* WITH OBJECT */
|
||||
|
||||
case HB_P_WITHOBJECTMESSAGE:
|
||||
hb_vmPushSymbol( pSymbols + HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) ) );
|
||||
{
|
||||
USHORT wSymPos = HB_PCODE_MKUSHORT( &( pCode[ w + 1 ] ) );
|
||||
if( wSymPos != 0xFFFF )
|
||||
{
|
||||
/* NOTE: 0xFFFF is passed when ':&varmacro' syntax is used.
|
||||
* In this case symbol is already pushed on the stack
|
||||
* using HB_P_MACROSYMBOL.
|
||||
*/
|
||||
hb_vmPushSymbol( pSymbols + wSymPos );
|
||||
}
|
||||
hb_vmPush( hb_stackWithObjectItem() );
|
||||
w += 3;
|
||||
break;
|
||||
}
|
||||
|
||||
case HB_P_WITHOBJECTSTART:
|
||||
hb_vmWithObjectStart();
|
||||
@@ -2450,6 +2460,11 @@ static void hb_vmInc( void )
|
||||
|
||||
pItem = hb_stackItemFromTop( -1 );
|
||||
|
||||
if( HB_IS_BYREF( pItem ) )
|
||||
{
|
||||
pItem = hb_itemUnRef( pItem );
|
||||
}
|
||||
|
||||
if( HB_IS_DATE( pItem ) )
|
||||
pItem->item.asDate.value++;
|
||||
else if( HB_IS_NUMINT( pItem ) )
|
||||
@@ -2497,6 +2512,11 @@ static void hb_vmDec( void )
|
||||
|
||||
pItem = hb_stackItemFromTop( -1 );
|
||||
|
||||
if( HB_IS_BYREF( pItem ) )
|
||||
{
|
||||
pItem = hb_itemUnRef( pItem );
|
||||
}
|
||||
|
||||
if( HB_IS_DATE( pItem ) )
|
||||
pItem->item.asDate.value--;
|
||||
else if( HB_IS_NUMINT( pItem ) )
|
||||
|
||||
48
harbour/tests/omacro.prg
Normal file
48
harbour/tests/omacro.prg
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* This file tests support for passing object methods and vars
|
||||
* using macro syntax
|
||||
*/
|
||||
PROCEDURE MAIN()
|
||||
LOCAL obj:=ErrorNew()
|
||||
MEMVAR send1, send2
|
||||
|
||||
PRIVATE send1:="_description"
|
||||
PRIVATE send2:="_tries"
|
||||
|
||||
obj:tries := 1
|
||||
obj:&send1 := 'test'
|
||||
|
||||
obj:tries += 1
|
||||
obj:tries++
|
||||
++obj:tries
|
||||
|
||||
WITH OBJECT obj
|
||||
:tries += 1
|
||||
:tries++
|
||||
++:tries
|
||||
|
||||
/*
|
||||
Notice that for post/pre increment decrement operators and
|
||||
for assigments (:=,+=,-=,*=,/=) the macro have to
|
||||
start from the underscore symbol '_'
|
||||
|
||||
To access the object variable using macro the '_' should be omitted
|
||||
*/
|
||||
:&send2 +=1
|
||||
:&send2++
|
||||
++:&send2
|
||||
++:&(send2)
|
||||
|
||||
:&( send2 ) := :&( SUBSTR(send2,2) ) +1
|
||||
|
||||
:&send1 +=' description'
|
||||
:&(send1) += ' of '
|
||||
END
|
||||
|
||||
obj:&( "_"+ SUBSTR(send1,2) ) += "Error object"
|
||||
? send1, "=", obj:&( SUBSTR(send1,2) )
|
||||
? send2, "=", obj:tries
|
||||
|
||||
RETURN
|
||||
Reference in New Issue
Block a user