+ 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:
Ryszard Glab
2006-09-29 08:59:17 +00:00
parent e0e9dc2808
commit 64509ea871
17 changed files with 313 additions and 105 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -5,6 +5,6 @@
/* hbexpra.c is also included from ../macro/macro.c
* However it produces a slighty different code if used in
* macro compiler (there is an additional parameter passed to some functions)
* 1.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"

View File

@@ -5,6 +5,6 @@
/* hbexprb.c is also included from ../macro/macro.c
* However it produces a slighty different code if used in
* macro compiler (there is an additional parameter passed to some functions)
* 1.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"

View File

@@ -5,6 +5,6 @@
/* hbexprc.c is also included from ../macro/macro.c
* However it produces a slighty different code if used in
* macro compiler (there is an additional parameter passed to some functions)
* 1.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"

View File

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

View File

@@ -212,6 +212,15 @@ static void hb_compDebugStart( void ) { };
BOOL lateEval; /* Flag for early {|| &macro} (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 ) );

View File

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

View File

@@ -5,7 +5,7 @@
/* hbexpra.c is also included from ../compiler/expropta.c
* However it produces a slighty different code if used in
* macro compiler (there is an additional parameter passed to some functions)
* 1.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

View File

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

View File

@@ -5,7 +5,7 @@
/* 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

View File

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