2006-09-20 14:15 UTC+0100 Ryszard Glab <rglab//imid.med.pl>
* include/hbpcode.h
+ added new pcode HB_P_VFRAME
* include/hbapi.h
+ added USHORT paramdeclcnt to asSymbol structure
* include/hbstack.h
* source/vm/estack.c
+ added hb_stackLocalVariable() to acces local variables
* source/compiler/genc.c
* source/compiler/gencc.c
* source/compiler/harbour.c
* source/compiler/harbour.l
* source/compiler/harbour.y
* source/compiler/hbdead.c
* source/compiler/hbfix.c
* source/compiler/hblbl.c
* source/compiler/hbpcode.c
* source/compiler/hbstripl.c
* source/vm/hvm.c
+ added support for variable number of parameters in
functions/procedures
+ tests/varparam.prg
* example usage of new syntax for variable number of
parameters
* source/vm/arrayshb.c
* changed HB_APARAMS() to use current stack frame if no
arguments are passed ( HB_APARAMS() == HB_APARAMS(0) )
SYNTAX for variable number of parameters
1) [FUNCTION|PROCEDURE] name( ... )
or
2) [FUNCTION|PROCEDURE] name( var1, var2, varN, ... )
To access passed parameters use the following:
PCOUNT() - returns number of passed parameters
HB_PVALUE( iParamNum ) - returns <iParamNum> parameter
HB_APARAMS() - returns array with all passed parameters
or usual name of parameter variable in case of syntax 2)
This commit is contained in:
@@ -8,6 +8,51 @@
|
||||
2002-12-01 13:30 UTC+0100 Foo Bar <foo.bar@foobar.org>
|
||||
*/
|
||||
|
||||
PHB_FUNC - and added translation for PHB_SYMB to not force using
|
||||
[P]HB_SYMB in 3-rd party code
|
||||
|
||||
|
||||
* added protection against possible GPF after executing
|
||||
hb_stackBaseProcOffset() when first item on the stack
|
||||
|
||||
cases. Probably some more general solution like leaving
|
||||
first dummy item on HVM stack for breaking stack scan
|
||||
loops will be better. I'll think about it.
|
||||
|
||||
* harbour/source/vm/itemapi.c
|
||||
! fixed clearing enumerators
|
||||
|
||||
2006-09-20 14:15 UTC+0100 Ryszard Glab <rglab//imid.med.pl>
|
||||
* include/hbpcode.h
|
||||
+ added new pcode HB_P_VFRAME
|
||||
|
||||
* include/hbapi.h
|
||||
+ added USHORT paramdeclcnt to asSymbol structure
|
||||
|
||||
* include/hbstack.h
|
||||
+ added support for variable number of parameters in
|
||||
+ added hb_stackLocalVariable() to acces local variables
|
||||
|
||||
* source/compiler/genc.c
|
||||
* source/compiler/gencc.c
|
||||
* source/compiler/harbour.c
|
||||
|
||||
* source/compiler/harbour.y
|
||||
* source/compiler/hbdead.c
|
||||
* source/compiler/hbfix.c
|
||||
* source/compiler/hblbl.c
|
||||
* source/compiler/hbpcode.c
|
||||
* source/compiler/hbstripl.c
|
||||
* source/vm/hvm.c
|
||||
+ added support for variable number of parameters in
|
||||
functions/procedures
|
||||
|
||||
+ tests/varparam.prg
|
||||
HB_PVALUE( iParamNum ) - returns <iParamNum> parameter
|
||||
parameters
|
||||
|
||||
* source/vm/arrayshb.c
|
||||
|
||||
arguments are passed ( HB_APARAMS() == HB_APARAMS(0) )
|
||||
|
||||
SYNTAX for variable number of parameters
|
||||
|
||||
@@ -322,7 +322,8 @@ struct hb_struSymbol
|
||||
PHB_SYMB value;
|
||||
PHB_STACK_STATE stackstate; /* function stack state */
|
||||
USHORT lineno;
|
||||
USHORT paramcnt;
|
||||
USHORT paramcnt; /* number of passed parameters in function call */
|
||||
USHORT paramdeclcnt; /* number of declared parameters in function definition */
|
||||
};
|
||||
|
||||
/* items hold at the virtual machine stack */
|
||||
|
||||
@@ -220,8 +220,8 @@ typedef enum
|
||||
HB_P_MACROSEND, /* 146 send operator with macrlist params */
|
||||
HB_P_PUSHOVARREF, /* 147 pushes reference to object variable */
|
||||
HB_P_ARRAYPUSHREF, /* 148 pushes reference to array element */
|
||||
/* NOTE: This have to be the last definition */
|
||||
HB_P_LAST_PCODE /* 149 this defines the number of defined pcodes */
|
||||
HB_P_VFRAME, /* 149 frame with variable number of parameters */
|
||||
HB_P_LAST_PCODE /* 150 this defines the number of defined pcodes */
|
||||
} HB_PCODE;
|
||||
|
||||
#endif /* HB_PCODE_H_ */
|
||||
|
||||
@@ -85,6 +85,7 @@ extern HB_STACK hb_stack;
|
||||
|
||||
extern HB_ITEM_PTR hb_stackItemFromTop( int nFromTop );
|
||||
extern HB_ITEM_PTR hb_stackItemFromBase( int nFromBase );
|
||||
extern HB_ITEM_PTR hb_stacklocalVariable( int *piFromBase );
|
||||
extern LONG hb_stackTopOffset( void );
|
||||
extern LONG hb_stackBaseOffset( void );
|
||||
extern LONG hb_stackTotalItems( void );
|
||||
@@ -183,6 +184,10 @@ extern void hb_stackClearMevarsBase( void );
|
||||
if( ++hb_stack.pPos == hb_stack.pEnd ) \
|
||||
hb_stackIncrease(); \
|
||||
} while ( 0 )
|
||||
#define hb_stackLocalVariable( p ) ((((*hb_stack.pBase)->item.asSymbol.paramcnt > (*hb_stack.pBase)->item.asSymbol.paramdeclcnt) && \
|
||||
(*(p)) > (*hb_stack.pBase)->item.asSymbol.paramdeclcnt ) ? \
|
||||
(* ( hb_stack.pBase + ( int ) ((*(p))+=((*hb_stack.pBase)->item.asSymbol.paramcnt - (*hb_stack.pBase)->item.asSymbol.paramdeclcnt)) + 1 ) ) : \
|
||||
(* ( hb_stack.pBase + ( int ) (*(p)) + 1 ) ) )
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -2009,6 +2009,16 @@ static HB_GENC_FUNC( hb_p_withobjectend )
|
||||
return 1;
|
||||
}
|
||||
|
||||
static HB_GENC_FUNC( hb_p_vframe )
|
||||
{
|
||||
fprintf( cargo->yyc, "\tHB_P_VFRAME, %i, %i,",
|
||||
pFunc->pCode[ lPCodePos + 1 ],
|
||||
pFunc->pCode[ lPCodePos + 2 ] );
|
||||
if( cargo->bVerbose ) fprintf( cargo->yyc, "\t/* locals, params */" );
|
||||
fprintf( cargo->yyc, "\n" );
|
||||
return 3;
|
||||
}
|
||||
|
||||
/* NOTE: The order of functions have to match the order of opcodes
|
||||
* mnemonics
|
||||
*/
|
||||
@@ -2166,7 +2176,8 @@ static HB_GENC_FUNC_PTR s_verbose_table[] = {
|
||||
hb_p_withobjectend,
|
||||
hb_p_macrosend,
|
||||
hb_p_pushovarref,
|
||||
hb_p_arraypushref
|
||||
hb_p_arraypushref,
|
||||
hb_p_vframe
|
||||
};
|
||||
|
||||
static void hb_compGenCReadable( PFUNCTION pFunc, FILE * yyc )
|
||||
|
||||
@@ -1589,6 +1589,15 @@ static HB_GENC_FUNC( hb_p_withobjectmessage )
|
||||
return 3;
|
||||
}
|
||||
|
||||
static HB_GENC_FUNC( hb_p_vframe )
|
||||
{
|
||||
HB_GENC_LABEL();
|
||||
|
||||
fprintf( cargo->yyc, "\thb_xvmVFrame( %hu, %hu );\n",
|
||||
pFunc->pCode[ lPCodePos + 1 ], pFunc->pCode[ lPCodePos + 2 ] );
|
||||
return 3;
|
||||
}
|
||||
|
||||
|
||||
/* NOTE: The order of functions have to match the order of opcodes
|
||||
* mnemonics
|
||||
@@ -1747,7 +1756,8 @@ static HB_GENC_FUNC_PTR s_verbose_table[] = {
|
||||
hb_p_withobjectend,
|
||||
hb_p_macrosend,
|
||||
hb_p_pushovarref,
|
||||
hb_p_arraypushref
|
||||
hb_p_arraypushref,
|
||||
hb_p_vframe
|
||||
};
|
||||
|
||||
void hb_compGenCRealCode( PFUNCTION pFunc, FILE * yyc )
|
||||
|
||||
@@ -3682,7 +3682,7 @@ static void hb_compOptimizeFrames( PFUNCTION pFunc )
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( pFunc->pCode[ 0 ] == HB_P_FRAME &&
|
||||
else if( (pFunc->pCode[ 0 ] == HB_P_FRAME || pFunc->pCode[ 0 ] == HB_P_VFRAME) &&
|
||||
pFunc->pCode[ 3 ] == HB_P_SFRAME )
|
||||
{
|
||||
PVAR pLocal;
|
||||
@@ -3713,7 +3713,7 @@ static void hb_compOptimizeFrames( PFUNCTION pFunc )
|
||||
pFunc->pCode[ 2 ] = ( BYTE )( pFunc->wParamCount );
|
||||
bSkipFRAME = FALSE;
|
||||
}
|
||||
else
|
||||
else if( pFunc->pCode[ 0 ] == HB_P_FRAME )
|
||||
bSkipFRAME = TRUE;
|
||||
|
||||
if( pFunc->bFlags & FUN_USES_STATICS )
|
||||
|
||||
@@ -1691,6 +1691,7 @@ Separator {SpaceTab}
|
||||
".or." hb_comp_iState =OPERATOR; return OR;
|
||||
"!"|".not." hb_comp_iState =OPERATOR; return NOT;
|
||||
"::" unput( ':' ); unput( 'f' ); unput( 'l' ); unput( 'e' ); unput( 'S' );
|
||||
"..." hb_comp_iState = OPERATOR; return EPSILON;
|
||||
[,\|\#\&\.\:\<\>\@] hb_comp_iState =OPERATOR; return yytext[ 0 ];
|
||||
[\{] hb_comp_iState =LARRAY; return yytext[ 0 ];
|
||||
[\}] hb_comp_iState =RARRAY; return yytext[ 0 ];
|
||||
|
||||
@@ -231,6 +231,7 @@ static void hb_compDebugStart( void ) { };
|
||||
%token FOREACH DESCEND
|
||||
%token DOSWITCH WITHOBJECT
|
||||
%token NUM_DATE
|
||||
%token EPSILON
|
||||
|
||||
/*the lowest precedence*/
|
||||
/*postincrement and postdecrement*/
|
||||
@@ -345,8 +346,10 @@ CompTimeStr: LITERAL { hb_compAutoOpenAdd( $1 ); }
|
||||
| LITERAL '+' LITERAL { char szFileName[ _POSIX_PATH_MAX ]; sprintf( szFileName, "%s%s", $1, $3 ); hb_compAutoOpenAdd( szFileName ); }
|
||||
;
|
||||
|
||||
Function : FunScope FUNCTION IdentName { hb_comp_cVarType = ' '; hb_compFunctionAdd( $3, ( HB_SYMBOLSCOPE ) $1, 0 ); } Params Crlf {}
|
||||
| FunScope PROCEDURE IdentName { hb_comp_cVarType = ' '; hb_compFunctionAdd( $3, ( HB_SYMBOLSCOPE ) $1, FUN_PROCEDURE ); } Params Crlf {}
|
||||
Function : FunScope FUNCTION IdentName { hb_comp_cVarType = ' '; hb_compFunctionAdd( $3, ( HB_SYMBOLSCOPE ) $1, 0 ); } Crlf {}
|
||||
| FunScope PROCEDURE IdentName { hb_comp_cVarType = ' '; hb_compFunctionAdd( $3, ( HB_SYMBOLSCOPE ) $1, FUN_PROCEDURE ); } Crlf {}
|
||||
| FunScope FUNCTION IdentName { hb_comp_cVarType = ' '; hb_compFunctionAdd( $3, ( HB_SYMBOLSCOPE ) $1, 0 ); hb_comp_iVarScope = VS_PARAMETER; } '(' Params ')' Crlf {}
|
||||
| FunScope PROCEDURE IdentName { hb_comp_cVarType = ' '; hb_compFunctionAdd( $3, ( HB_SYMBOLSCOPE ) $1, FUN_PROCEDURE ); hb_comp_iVarScope = VS_PARAMETER;} '(' Params ')' Crlf {}
|
||||
;
|
||||
|
||||
FunScope : { $$ = HB_FS_PUBLIC; }
|
||||
@@ -355,9 +358,10 @@ FunScope : { $$ = HB_FS_PUBLIC; }
|
||||
| EXIT { $$ = HB_FS_EXIT; }
|
||||
;
|
||||
|
||||
Params : { $$ = 0; }
|
||||
| '(' ')' { $$ = 0; }
|
||||
| '(' { hb_comp_iVarScope = VS_PARAMETER; } ParamList ')' { $$ = $3; }
|
||||
Params : /*no parameters */ { $$ = 0; }
|
||||
| EPSILON { hb_comp_functions.pLast->pCode[0] = HB_P_VFRAME; $$ = 0; }
|
||||
| ParamList { $$ = $1; }
|
||||
| ParamList ',' EPSILON { hb_comp_functions.pLast->pCode[0] = HB_P_VFRAME; $$ = $1; }
|
||||
;
|
||||
|
||||
AsType : /* not specified */ { hb_comp_cVarType = ' '; }
|
||||
|
||||
@@ -458,7 +458,8 @@ static PHB_CODETRACE_FUNC s_codeTraceFuncTable[ HB_P_LAST_PCODE ] =
|
||||
hb_p_default, /* HB_P_WITHOBJECTEND */
|
||||
hb_p_default, /* HB_P_MACROSEND */
|
||||
hb_p_default, /* HB_P_PUSHOVARREF */
|
||||
hb_p_default /* HB_P_ARRAYPUSHREF */
|
||||
hb_p_default, /* HB_P_ARRAYPUSHREF */
|
||||
hb_p_default /* HB_P_VFRAME */
|
||||
};
|
||||
|
||||
void hb_compCodeTraceMarkDead( PFUNCTION pFunc )
|
||||
|
||||
@@ -638,7 +638,8 @@ static HB_FIX_FUNC_PTR s_fixlocals_table[] =
|
||||
NULL, /* HB_P_WITHOBJECTEND */
|
||||
NULL, /* HB_P_MACROSEND */
|
||||
NULL, /* HB_P_PUSHOVARREF */
|
||||
NULL /* HB_P_ARRAYPUSHREF */
|
||||
NULL, /* HB_P_ARRAYPUSHREF */
|
||||
NULL /* HB_P_VFRAME */
|
||||
};
|
||||
|
||||
void hb_compFixFuncPCode( PFUNCTION pFunc )
|
||||
|
||||
@@ -322,7 +322,8 @@ static PHB_LABEL_FUNC s_GenLabelFuncTable[ HB_P_LAST_PCODE ] =
|
||||
NULL, /* HB_P_WITHOBJECTEND */
|
||||
NULL, /* HB_P_MACROSEND */
|
||||
NULL, /* HB_P_PUSHOVARREF */
|
||||
NULL /* HB_P_ARRAYPUSHREF */
|
||||
NULL, /* HB_P_ARRAYPUSHREF */
|
||||
NULL /* HB_P_VFRAME */
|
||||
};
|
||||
|
||||
void hb_compGenLabelTable( PFUNCTION pFunc, PHB_LABEL_INFO label_info )
|
||||
|
||||
@@ -255,7 +255,8 @@ const BYTE hb_comp_pcode_len[] = {
|
||||
1, /* HB_P_WITHOBJECTEND, */
|
||||
3, /* HB_P_MACROSEND, */
|
||||
1, /* HB_P_PUSHOVARREF, */
|
||||
1 /* HB_P_ARRAYPUSHREF */
|
||||
1, /* HB_P_ARRAYPUSHREF */
|
||||
3 /* HB_P_VFRAME */
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -415,7 +416,8 @@ static HB_PCODE_FUNC_PTR s_psize_table[] =
|
||||
NULL, /* HB_P_WITHOBJECTEND */
|
||||
NULL, /* HB_P_MACROSEND */
|
||||
NULL, /* HB_P_PUSHOVARREF */
|
||||
NULL /* HB_P_ARRAYPUSHREF */
|
||||
NULL, /* HB_P_ARRAYPUSHREF */
|
||||
NULL /* HB_P_VFRAME */
|
||||
};
|
||||
|
||||
LONG hb_compPCodeSize( PFUNCTION pFunc, ULONG ulOffset )
|
||||
|
||||
@@ -227,7 +227,8 @@ static PHB_STRIP_FUNC s_stripLines_table[] =
|
||||
NULL, /* HB_P_WITHOBJECTEND */
|
||||
NULL, /* HB_P_MACROSEND */
|
||||
NULL, /* HB_P_PUSHOVARREF */
|
||||
NULL /* HB_P_ARRAYPUSHREF */
|
||||
NULL, /* HB_P_ARRAYPUSHREF */
|
||||
NULL /* HB_P_VFRAME */
|
||||
};
|
||||
|
||||
void hb_compStripFuncLines( PFUNCTION pFunc )
|
||||
|
||||
@@ -330,5 +330,8 @@ HB_FUNC( ACLONE )
|
||||
|
||||
HB_FUNC( HB_APARAMS )
|
||||
{
|
||||
hb_itemRelease( hb_itemReturn( hb_arrayFromParams( hb_parni( 1 ) + 1 ) ) );
|
||||
if( hb_pcount() == 0 )
|
||||
hb_itemRelease( hb_itemReturn( hb_arrayFromParams( 1 ) ) );
|
||||
else
|
||||
hb_itemRelease( hb_itemReturn( hb_arrayFromParams( hb_parni( 1 ) + 1 ) ) );
|
||||
}
|
||||
|
||||
@@ -249,6 +249,10 @@ HB_ITEM_PTR hb_stackNewFrame( HB_STACK_STATE * pStack, USHORT uiParams )
|
||||
pItem->item.asSymbol.stackstate = pStack;
|
||||
pItem->item.asSymbol.lineno = 0;
|
||||
pItem->item.asSymbol.paramcnt = uiParams;
|
||||
/* set default value of 'paramdeclcnt' - it will be updated
|
||||
* in hb_vmVFrame only
|
||||
*/
|
||||
pItem->item.asSymbol.paramdeclcnt = uiParams;
|
||||
hb_stack.pBase = pBase;
|
||||
|
||||
return pItem;
|
||||
@@ -295,6 +299,28 @@ HB_ITEM_PTR hb_stackItemFromBase( int nFromBase )
|
||||
return * ( hb_stack.pBase + nFromBase + 1 );
|
||||
}
|
||||
|
||||
#undef hb_stackLocalVariable
|
||||
HB_ITEM_PTR hb_stackLocalVariable( int *piFromBase )
|
||||
{
|
||||
HB_ITEM_PTR pBase = *hb_stack.pBase;
|
||||
|
||||
if( *piFromBase <= 0 )
|
||||
hb_errInternal( HB_EI_STACKUFLOW, NULL, NULL, NULL );
|
||||
|
||||
if( pBase->item.asSymbol.paramcnt > pBase->item.asSymbol.paramdeclcnt )
|
||||
{
|
||||
/* function with variable number of parameters:
|
||||
* FUNCTION foo( a,b,c,...)
|
||||
* LOCAL x,y,z
|
||||
* number of passed parameters is bigger then number of declared
|
||||
* parameters - skip additional parameters only for local variables
|
||||
*/
|
||||
if( *piFromBase > pBase->item.asSymbol.paramdeclcnt )
|
||||
*piFromBase += pBase->item.asSymbol.paramcnt - pBase->item.asSymbol.paramdeclcnt;
|
||||
}
|
||||
return * ( hb_stack.pBase + *piFromBase + 1 );
|
||||
}
|
||||
|
||||
#undef hb_stackBaseItem
|
||||
HB_ITEM_PTR hb_stackBaseItem( void )
|
||||
{
|
||||
|
||||
@@ -158,6 +158,7 @@ static void hb_vmLocalName( USHORT uiLocal, char * szLocalName ); /* locals a
|
||||
static void hb_vmStaticName( BYTE bIsGlobal, USHORT uiStatic, char * szStaticName ); /* statics vars information for the debugger */
|
||||
static void hb_vmModuleName( char * szModuleName ); /* PRG and function name information for the debugger */
|
||||
static void hb_vmFrame( BYTE bLocals, BYTE bParams ); /* increases the stack pointer for the amount of locals and params suplied */
|
||||
static void hb_vmVFrame( BYTE bLocals, BYTE bParams ); /* increases the stack pointer for the amount of locals and variable number of params suplied */
|
||||
static void hb_vmSFrame( PHB_SYMB pSym ); /* sets the statics frame for a function */
|
||||
static void hb_vmStatics( PHB_SYMB pSym, USHORT uiStatics ); /* increases the global statics array to hold a PRG statics */
|
||||
static void hb_vmEndBlock( void ); /* copies the last codeblock pushed value into the return value */
|
||||
@@ -1783,13 +1784,16 @@ HB_EXPORT void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols )
|
||||
}
|
||||
|
||||
case HB_P_LOCALNEARADDINT:
|
||||
{
|
||||
SHORT iLocal = pCode[ w + 1 ];
|
||||
HB_TRACE( HB_TR_DEBUG, ("HB_P_LOCALNEARADDINT") );
|
||||
|
||||
hb_vmAddInt( hb_stackItemFromBase( pCode[ w + 1 ] ),
|
||||
hb_vmAddInt( hb_stackLocalVariable( &iLocal ),
|
||||
HB_PCODE_MKSHORT( &( pCode[ w + 2 ] ) ) );
|
||||
w += 4;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
/* WITH OBJECT */
|
||||
|
||||
case HB_P_WITHOBJECTMESSAGE:
|
||||
@@ -1809,6 +1813,11 @@ HB_EXPORT void hb_vmExecute( const BYTE * pCode, PHB_SYMB pSymbols )
|
||||
w += 1;
|
||||
break;
|
||||
|
||||
case HB_P_VFRAME:
|
||||
hb_vmVFrame( pCode[ w + 1 ], pCode[ w + 2 ] );
|
||||
w += 3;
|
||||
break;
|
||||
|
||||
/* misc */
|
||||
|
||||
case HB_P_NOOP:
|
||||
@@ -4432,21 +4441,45 @@ static void hb_vmModuleName( char * szModuleName ) /* PRG and function name info
|
||||
static void hb_vmFrame( BYTE bLocals, BYTE bParams )
|
||||
{
|
||||
int iTotal, iExtra;
|
||||
int ipcount = hb_pcount();
|
||||
|
||||
HB_TRACE(HB_TR_DEBUG, ("hb_vmFrame(%d, %d)", (int) bLocals, (int) bParams));
|
||||
|
||||
iExtra = hb_pcount() - bParams;
|
||||
iExtra = ipcount - bParams;
|
||||
|
||||
while( iExtra > 0 )
|
||||
if( iExtra > 0 )
|
||||
{
|
||||
hb_itemClear( hb_stackItemFromTop( -iExtra ) );
|
||||
iExtra--;
|
||||
hb_stackBaseItem()->item.asSymbol.paramcnt = bParams;
|
||||
while( iExtra > 0 )
|
||||
{
|
||||
hb_itemClear( hb_stackItemFromTop( -iExtra ) );
|
||||
iExtra--;
|
||||
}
|
||||
}
|
||||
|
||||
iTotal = bLocals + bParams;
|
||||
if( iTotal )
|
||||
{
|
||||
iTotal -= hb_pcount();
|
||||
iTotal -= ipcount;
|
||||
while( --iTotal >= 0 )
|
||||
hb_vmPushNil();
|
||||
}
|
||||
}
|
||||
|
||||
static void hb_vmVFrame( BYTE bLocals, BYTE bParams )
|
||||
{
|
||||
int iTotal;
|
||||
|
||||
HB_TRACE(HB_TR_DEBUG, ("hb_vmVFrame(%d, %d)", (int) bLocals, (int) bParams));
|
||||
|
||||
hb_stackBaseItem()->item.asSymbol.paramdeclcnt = bParams;
|
||||
|
||||
if( hb_pcount() < bParams )
|
||||
iTotal = bLocals + bParams - hb_pcount();
|
||||
else
|
||||
iTotal = bLocals;
|
||||
if( iTotal )
|
||||
{
|
||||
while( --iTotal >= 0 )
|
||||
hb_vmPushNil();
|
||||
}
|
||||
@@ -4970,7 +5003,7 @@ static void hb_vmPushLocal( SHORT iLocal )
|
||||
if( iLocal >= 0 )
|
||||
{
|
||||
/* local variable or local parameter */
|
||||
pLocal = hb_stackItemFromBase( iLocal );
|
||||
pLocal = hb_stackLocalVariable( &iLocal );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -4997,6 +5030,7 @@ static void hb_vmPushLocalByRef( SHORT iLocal )
|
||||
|
||||
pTop->type = HB_IT_BYREF;
|
||||
/* we store its stack offset instead of a pointer to support a dynamic stack */
|
||||
hb_stackLocalVariable( &iLocal );
|
||||
pTop->item.asRefer.value = iLocal;
|
||||
pTop->item.asRefer.offset = hb_stackBaseOffset();
|
||||
if( iLocal >= 0 )
|
||||
@@ -5332,7 +5366,7 @@ static void hb_vmPopLocal( SHORT iLocal )
|
||||
if( iLocal >= 0 )
|
||||
{
|
||||
/* local variable or local parameter */
|
||||
pLocal = hb_stackItemFromBase( iLocal );
|
||||
pLocal = hb_stackLocalVariable( &iLocal );
|
||||
if( HB_IS_BYREF( pLocal ) )
|
||||
pLocal = hb_itemUnRef( pLocal );
|
||||
}
|
||||
@@ -6318,6 +6352,13 @@ HB_EXPORT void hb_xvmFrame( int iLocals, int iParams )
|
||||
hb_vmFrame( ( BYTE ) iLocals, ( BYTE ) iParams );
|
||||
}
|
||||
|
||||
HB_EXPORT void hb_xvmVFrame( int iLocals, int iParams )
|
||||
{
|
||||
HB_TRACE(HB_TR_DEBUG, ("hb_xvmVFrame(%d, %d)", iLocals, iParams));
|
||||
|
||||
hb_vmVFrame( ( BYTE ) iLocals, ( BYTE ) iParams );
|
||||
}
|
||||
|
||||
HB_EXPORT void hb_xvmSFrame( PHB_SYMB pSymbol )
|
||||
{
|
||||
HB_TRACE(HB_TR_DEBUG, ("hb_xvmSFrame(%p)", pSymbol));
|
||||
@@ -6615,7 +6656,7 @@ HB_EXPORT void hb_xvmLocalSetInt( int iLocal, LONG lValue )
|
||||
if( iLocal >= 0 )
|
||||
{
|
||||
/* local variable or local parameter */
|
||||
pLocal = hb_stackItemFromBase( iLocal );
|
||||
pLocal = hb_stackLocalVariable( &iLocal );
|
||||
if( HB_IS_BYREF( pLocal ) )
|
||||
pLocal = hb_itemUnRef( pLocal );
|
||||
}
|
||||
@@ -6644,7 +6685,7 @@ HB_EXPORT BOOL hb_xvmLocalAddInt( int iLocal, LONG lAdd )
|
||||
{
|
||||
HB_TRACE(HB_TR_DEBUG, ("hb_xvmLocalAddInt(%d,%ld)", iLocal, lAdd));
|
||||
|
||||
hb_vmAddInt( hb_stackItemFromBase( iLocal ), lAdd );
|
||||
hb_vmAddInt( hb_stackLocalVariable( &iLocal ), lAdd );
|
||||
|
||||
HB_XVM_RETURN
|
||||
}
|
||||
@@ -6655,7 +6696,7 @@ HB_EXPORT BOOL hb_xvmLocalAdd( int iLocal )
|
||||
|
||||
HB_TRACE(HB_TR_DEBUG, ("hb_xvmLocalAdd(%d)", iLocal));
|
||||
|
||||
pLocal = hb_stackItemFromBase( iLocal );
|
||||
pLocal = hb_stackLocalVariable( &iLocal );
|
||||
if( HB_IS_BYREF( pLocal ) )
|
||||
pLocal = hb_itemUnRef( pLocal );
|
||||
hb_vmPlus( pLocal, hb_stackItemFromTop( -2 ), hb_stackItemFromTop( -1 ), 2 );
|
||||
|
||||
325
harbour/tests/varparam.prg
Normal file
325
harbour/tests/varparam.prg
Normal file
@@ -0,0 +1,325 @@
|
||||
//
|
||||
// $Id$
|
||||
//
|
||||
/* TEST FOR USING VARIABLE NUMBER OF PARAMETERS */
|
||||
|
||||
MEMVAR iLoop
|
||||
PROCEDURE MAIN(p1, p2)
|
||||
LOCAL l1:=11,l2:=22,l3:=33,l4:=44,l5:=55,l6:=66
|
||||
PRIVATE iLoop
|
||||
|
||||
? 'passed 0: '; TEST_0_0( )
|
||||
? 'passed 1: '; TEST_0_0( 1 )
|
||||
? 'passed 2: '; TEST_0_0( 1, 2 )
|
||||
? 'passed 3: '; TEST_0_0( 1, 2, 3 )
|
||||
|
||||
? '---------------------------------------'
|
||||
? 'passed 0: '; TEST_0_0v( )
|
||||
? 'passed 1: '; TEST_0_0v( 1 )
|
||||
? 'passed 2: '; TEST_0_0v( 1, 2 )
|
||||
? 'passed 3: '; TEST_0_0v( 1, 2, 3 )
|
||||
|
||||
? '---------------------------------------'
|
||||
? 'passed 0: '; TEST_1_0( )
|
||||
? 'passed 1: '; TEST_1_0( 1 )
|
||||
? 'passed 2: '; TEST_1_0( 1, 2 )
|
||||
? 'passed 3: '; TEST_1_0( 1, 2, 3 )
|
||||
|
||||
? '---------------------------------------'
|
||||
? 'passed 0: '; TEST_1_0v( )
|
||||
? 'passed 1: '; TEST_1_0v( 1 )
|
||||
? 'passed 2: '; TEST_1_0v( 1, 2 )
|
||||
? 'passed 3: '; TEST_1_0v( 1, 2, 3 )
|
||||
|
||||
? '---------------------------------------'
|
||||
? 'passed 0: '; TEST_1_1( )
|
||||
? 'passed 1: '; TEST_1_1( 1 )
|
||||
? 'passed 2: '; TEST_1_1( 1, 2 )
|
||||
? 'passed 3: '; TEST_1_1( 1, 2, 3 )
|
||||
|
||||
? '---------------------------------------'
|
||||
? 'passed 0: '; TEST_1_1v( )
|
||||
? 'passed 1: '; TEST_1_1v( 1 )
|
||||
? 'passed 2: '; TEST_1_1v( 1, 2 )
|
||||
? 'passed 3: '; TEST_1_1v( 1, 2, 3 )
|
||||
|
||||
? '---------------------------------------'
|
||||
? 'passed 0: '; TEST_1_3( )
|
||||
? 'passed 1: '; TEST_1_3( 1 )
|
||||
? 'passed 2: '; TEST_1_3( 1, 2 )
|
||||
? 'passed 3: '; TEST_1_3( 1, 2, 3 )
|
||||
? 'passed 4: '; TEST_1_3( 1, 2, 3, 4 )
|
||||
? 'passed 5: '; TEST_1_3( 1, 2, 3, 4, 5 )
|
||||
? 'passed 6: '; TEST_1_3( 1, 2, 3, 4, 5, 6 )
|
||||
|
||||
? '---------------------------------------'
|
||||
? 'passed 0: '; TEST_1_3v( )
|
||||
? 'passed 1: '; TEST_1_3v( 1 )
|
||||
? 'passed 2: '; TEST_1_3v( 1, 2 )
|
||||
? 'passed 3: '; TEST_1_3v( 1, 2, 3 )
|
||||
? 'passed 4: '; TEST_1_3v( 1, 2, 3, 4 )
|
||||
? 'passed 5: '; TEST_1_3v( 1, 2, 3, 4, 5 )
|
||||
? 'passed 6: '; TEST_1_3v( 1, 2, 3, 4, 5, 6 )
|
||||
|
||||
? '---------------------------------------'
|
||||
? 'passed 0: '; TEST_3_0( )
|
||||
? 'passed 1: '; TEST_3_0( 1 )
|
||||
? 'passed 2: '; TEST_3_0( 1, 2 )
|
||||
? 'passed 3: '; TEST_3_0( 1, 2, 3 )
|
||||
? 'passed 4: '; TEST_3_0( 1, 2, 3, 4 )
|
||||
? 'passed 5: '; TEST_3_0( 1, 2, 3, 4, 5 )
|
||||
? 'passed 6: '; TEST_3_0( 1, 2, 3, 4, 5, 6 )
|
||||
|
||||
? '---------------------------------------'
|
||||
? 'passed 0: '; TEST_3_0v( )
|
||||
? 'passed 1: '; TEST_3_0v( 1 )
|
||||
? 'passed 2: '; TEST_3_0v( 1, 2 )
|
||||
? 'passed 3: '; TEST_3_0v( 1, 2, 3 )
|
||||
? 'passed 4: '; TEST_3_0v( 1, 2, 3, 4 )
|
||||
? 'passed 5: '; TEST_3_0v( 1, 2, 3, 4, 5 )
|
||||
? 'passed 6: '; TEST_3_0v( 1, 2, 3, 4, 5, 6 )
|
||||
|
||||
? '---------------------------------------'
|
||||
? 'passed 0: '; TEST_3_3( )
|
||||
? 'passed 1: '; TEST_3_3( 1 )
|
||||
? 'passed 2: '; TEST_3_3( 1, 2 )
|
||||
? 'passed 3: '; TEST_3_3( 1, 2, 3 )
|
||||
? 'passed 4: '; TEST_3_3( 1, 2, 3, 4 )
|
||||
? 'passed 5: '; TEST_3_3( 1, 2, 3, 4, 5 )
|
||||
? 'passed 6: '; TEST_3_3( 1, 2, 3, 4, 5, 6 )
|
||||
|
||||
? '---------------------------------------'
|
||||
? 'passed 0: '; TEST_3_3v( )
|
||||
? 'passed 1: '; TEST_3_3v( 1 )
|
||||
? 'passed 2: '; TEST_3_3v( 1, 2 )
|
||||
? 'passed 3: '; TEST_3_3v( 1, 2, 3 )
|
||||
? 'passed 4: '; TEST_3_3v( 1, 2, 3, 4 )
|
||||
? 'passed 5: '; TEST_3_3v( 1, 2, 3, 4, 5 )
|
||||
? 'passed 6: '; TEST_3_3v( 1, 2, 3, 4, 5, 6 )
|
||||
|
||||
? '---------------------------------------'
|
||||
? 'Passed 6 by ref: '; TEST_0_0( @l1, @l2, @l3, @l4, @l5, @l6 )
|
||||
? 'Passed 6 by ref: '; TEST_0_0v( @l1, @l2, @l3, @l4, @l5, @l6 )
|
||||
|
||||
? '---------------------------------------'
|
||||
? 'Passed 6 by ref: '; TEST_1_0( @l1, @l2, @l3, @l4, @l5, @l6 )
|
||||
? 'Passed 6 by ref: '; TEST_1_0v( @l1, @l2, @l3, @l4, @l5, @l6 )
|
||||
|
||||
? '---------------------------------------'
|
||||
? 'Passed 6 by ref: '; TEST_1_1( @l1, @l2, @l3, @l4, @l5, @l6 )
|
||||
? 'Passed 6 by ref: '; TEST_1_1v( @l1, @l2, @l3, @l4, @l5, @l6 )
|
||||
|
||||
? '---------------------------------------'
|
||||
? 'Passed 6 by ref: '; TEST_1_3( @l1, @l2, @l3, @l4, @l5, @l6 )
|
||||
? 'Passed 6 by ref: '; TEST_1_3v( @l1, @l2, @l3, @l4, @l5, @l6 )
|
||||
|
||||
? '---------------------------------------'
|
||||
? 'Passed 6 by ref: '; TEST_3_0( @l1, @l2, @l3, @l4, @l5, @l6 )
|
||||
? 'Passed 6 by ref: '; TEST_3_0v( @l1, @l2, @l3, @l4, @l5, @l6 )
|
||||
|
||||
? '---------------------------------------'
|
||||
? 'Passed 6 by ref: '; TEST_3_3( @l1, @l2, @l3, @l4, @l5, @l6 )
|
||||
? 'Passed 6 by ref: '; TEST_3_3v( @l1, @l2, @l3, @l4, @l5, @l6 )
|
||||
|
||||
RETURN
|
||||
|
||||
PROCEDURE TEST_0_0v( ... )
|
||||
|
||||
?? PROCNAME(0), ' received: ', PCOUNT()
|
||||
FOR m->iLoop:=1 TO PCOUNT()
|
||||
? m->iLoop, "=", HB_PVALUE( m->iLoop )
|
||||
NEXT
|
||||
|
||||
inkey(0)
|
||||
|
||||
RETURN
|
||||
|
||||
PROCEDURE TEST_0_0( )
|
||||
|
||||
?? PROCNAME(0), ' received: ', PCOUNT()
|
||||
FOR m->iLoop:=1 TO PCOUNT()
|
||||
? m->iLoop, "=", HB_PVALUE( m->iLoop )
|
||||
NEXT
|
||||
|
||||
inkey(0)
|
||||
|
||||
RETURN
|
||||
|
||||
PROCEDURE TEST_1_0v( ... )
|
||||
LOCAL i:='i'
|
||||
|
||||
?? PROCNAME(0), ' received: ', PCOUNT()
|
||||
? 'i=',i
|
||||
FOR i:=1 TO PCOUNT()
|
||||
? i, "=", HB_PVALUE( i )
|
||||
NEXT
|
||||
|
||||
inkey(0)
|
||||
|
||||
RETURN
|
||||
|
||||
PROCEDURE TEST_1_0( )
|
||||
LOCAL i:='i'
|
||||
|
||||
?? PROCNAME(0), ' received: ', PCOUNT()
|
||||
? 'i=',i
|
||||
FOR i:=1 TO PCOUNT()
|
||||
? i, "=", HB_PVALUE( i )
|
||||
NEXT
|
||||
|
||||
inkey(0)
|
||||
|
||||
RETURN
|
||||
|
||||
PROCEDURE TEST_1_3v( a,b,c, ... )
|
||||
LOCAL i:='i'
|
||||
|
||||
?? PROCNAME(0), ' received: ', PCOUNT()
|
||||
? 'i=',i
|
||||
? 'a=',a
|
||||
? 'b=',b
|
||||
? 'c=',c
|
||||
FOR i:=1 TO PCOUNT()
|
||||
? i, "=", HB_PVALUE( i )
|
||||
NEXT
|
||||
|
||||
FOR EACH i IN HB_APARAMS()
|
||||
? i:__enumindex, "-", i
|
||||
NEXT
|
||||
|
||||
inkey(0)
|
||||
|
||||
RETURN
|
||||
|
||||
|
||||
PROCEDURE TEST_1_3( a,b,c )
|
||||
LOCAL i:='i'
|
||||
|
||||
?? PROCNAME(0), ' received: ', PCOUNT()
|
||||
? 'i=',i
|
||||
? 'a=',a
|
||||
? 'b=',b
|
||||
? 'c=',c
|
||||
FOR i:=1 TO PCOUNT()
|
||||
? i, "=", HB_PVALUE( i )
|
||||
NEXT
|
||||
|
||||
FOR EACH i IN HB_APARAMS()
|
||||
? i:__enumindex, "-", i
|
||||
NEXT
|
||||
|
||||
inkey(0)
|
||||
|
||||
RETURN
|
||||
|
||||
|
||||
PROCEDURE TEST_1_1( a )
|
||||
LOCAL i:='i'
|
||||
|
||||
?? PROCNAME(0), ' received: ', PCOUNT()
|
||||
? 'i=',i
|
||||
? 'a=',a
|
||||
FOR i:=1 TO PCOUNT()
|
||||
? i, "=", HB_PVALUE( i )
|
||||
NEXT
|
||||
|
||||
inkey(0)
|
||||
|
||||
RETURN
|
||||
|
||||
PROCEDURE TEST_1_1v( a, ... )
|
||||
LOCAL i:='i'
|
||||
|
||||
?? PROCNAME(0), ' received: ', PCOUNT()
|
||||
? 'i=',i
|
||||
? 'a=',a
|
||||
FOR i:=1 TO PCOUNT()
|
||||
? i, "=", HB_PVALUE( i )
|
||||
NEXT
|
||||
|
||||
inkey(0)
|
||||
|
||||
RETURN
|
||||
|
||||
PROCEDURE TEST_3_3v( a,b,c, ... )
|
||||
LOCAL x:='x', y:='y', z:='z'
|
||||
|
||||
?? PROCNAME(0), ' received: ', PCOUNT()
|
||||
? 'x=',x
|
||||
? 'y=',y
|
||||
? 'z=',z
|
||||
? 'a=',a
|
||||
? 'b=',b
|
||||
? 'c=',c
|
||||
FOR m->iLoop:=1 TO PCOUNT()
|
||||
? m->iLoop, "=", HB_PVALUE( m->iLoop )
|
||||
NEXT
|
||||
|
||||
test_ref( @a, @b, @c, @x, @y, @z )
|
||||
|
||||
inkey(0)
|
||||
|
||||
RETURN
|
||||
|
||||
PROCEDURE TEST_3_3( a,b,c )
|
||||
LOCAL x:='x', y:='y', z:='z'
|
||||
|
||||
?? PROCNAME(0), ' received: ', PCOUNT()
|
||||
? 'x=',x
|
||||
? 'y=',y
|
||||
? 'z=',z
|
||||
? 'a=',a
|
||||
? 'b=',b
|
||||
? 'c=',c
|
||||
FOR m->iLoop:=1 TO PCOUNT()
|
||||
? m->iLoop, "=", HB_PVALUE( m->iLoop )
|
||||
NEXT
|
||||
|
||||
test_ref( @a, @b, @c, @x, @y, @z )
|
||||
|
||||
inkey(0)
|
||||
|
||||
RETURN
|
||||
|
||||
PROCEDURE TEST_3_0( )
|
||||
LOCAL x:='x', y:='y', z:='z'
|
||||
|
||||
?? PROCNAME(0), ' received: ', PCOUNT()
|
||||
? 'x=',x
|
||||
? 'y=',y
|
||||
? 'z=',z
|
||||
FOR m->iLoop:=1 TO PCOUNT()
|
||||
? m->iLoop, "=", HB_PVALUE( m->iLoop )
|
||||
NEXT
|
||||
|
||||
inkey(0)
|
||||
|
||||
RETURN
|
||||
|
||||
PROCEDURE TEST_3_0v( ... )
|
||||
LOCAL x:='x', y:='y', z:='z'
|
||||
|
||||
?? PROCNAME(0), ' received: ', PCOUNT()
|
||||
? 'x=',x
|
||||
? 'y=',y
|
||||
? 'z=',z
|
||||
FOR m->iLoop:=1 TO PCOUNT()
|
||||
? m->iLoop, "=", HB_PVALUE( m->iLoop )
|
||||
NEXT
|
||||
|
||||
inkey(0)
|
||||
|
||||
RETURN
|
||||
|
||||
PROCEDURE TEST_REF( a, ... )
|
||||
LOCAL b
|
||||
|
||||
? '@@@'
|
||||
? PROCNAME(0), ' received: ', PCOUNT()
|
||||
? 'a= ', a
|
||||
? 'b= ', b
|
||||
FOR EACH b IN HB_APARAMS(0)
|
||||
? b:__enumindex, "-", b
|
||||
NEXT
|
||||
|
||||
RETURN
|
||||
Reference in New Issue
Block a user