ChangeLog 19990725-01:00 GMT+2

This commit is contained in:
Ryszard Glab
1999-07-24 23:17:36 +00:00
parent 201317f141
commit 54f7f0a724
6 changed files with 566 additions and 248 deletions

View File

@@ -1,3 +1,34 @@
19990725-01:00 GMT+2 Ryszard Glab <rglab@imid.med.pl>
*source/rtl/memvars.c
* corrected code that handle values' cache
+ added code to test variables with the names that are the same
as functions names
* variables passed by reference are correctly handled now in
PARAMETERS statement
* renamed __PUBLIC to __MVPUBLIC and __PRIVATE to __MVPRIVATE
all other functions related to memory variables will start
with '__MV' prefix
+ added __MVXRELEASE function to release value stored in memvar
variable (it can be used in RELEASE command)
*source/vm/hvm.c
* variables passed by reference are correctly handled now in
PARAMETERS statement
*source/compiler/harbour.y
* the symbol table is generated correctly now if a memvar variable
have the same name as one of used functions or is the same as the
name of compiled module
* simplified and cleared handling of symbol positions
*source/compiler/harbour.l
* MEMVAR keyword is handled correctly now
*tests/working/memvar.prg
+ added code to test variables with the names that are the same
as functions names
19990725-00:20 CET Felipe Coury
* tests/working/bld32exe.bat
changed for RDD

View File

@@ -116,7 +116,7 @@ Separator {SpaceTab}
%x STRING1 STRING2 STRING3
%x NEXT_ BREAK_ CASE_ DO_ WHILE_ WITH_ END_ EXIT_ EXTERNAL_ FIELD_
%x FOR_ FUNCTION_ IIF_ IF_ IN_ INIT_ LOCAL_ LOOP_
%x PARAM_ PRIVATE_ PUBLIC_
%x MEMVAR_ PARAM_ PRIVATE_ PUBLIC_
%s INDEX
%%
@@ -767,7 +767,30 @@ Separator {SpaceTab}
%{
/* ************************************************************************ */
%}
"memvar" _iState =MEMVAR; return MEMVAR;
"memv"|"memva"|"memvar" { BEGIN MEMVAR_;
yylval.string = yy_strupr( yy_strdup( yytext ) );
}
<MEMVAR_>{Separator}+[_a-zA-Z] { /* an identifier after MEMVAR */
unput( yytext[ yyleng-1 ] );
if( i_INDEX_STATE ) BEGIN INDEX; else BEGIN 0;
if( _iState == LOOKUP )
{ /* it is the first item in the line */
OurFree( (void *) yylval.string );
_iState =MEMVAR;
return MEMVAR;
}
else
{ /* there is another item in line already */
_iState =IDENTIFIER;
return IDENTIFIER;
}
}
<MEMVAR_>{Separator}*[^a-zA-Z] { /* any character (not identifier) after MEMVAR */
unput( yytext[ yyleng-1 ] );
if( i_INDEX_STATE ) BEGIN INDEX; else BEGIN 0;
_iState =IDENTIFIER;
return IDENTIFIER;
}
%{
/* ************************************************************************ */
%}
@@ -851,7 +874,7 @@ Separator {SpaceTab}
unput( yytext[ yyleng-1 ] );
if( i_INDEX_STATE ) BEGIN INDEX; else BEGIN 0;
if( _iState == LOOKUP )
{ /* it is first item in the line */
{ /* it is the first item in the line */
OurFree( (void *) yylval.string );
_iState =PARAMETERS;
return PARAMETERS;

View File

@@ -179,7 +179,7 @@ PFUNCTION AddFunCall( char * szFuntionName );
void AddExtern( char * szExternName ); /* defines a new extern name */
void AddSearchPath( char *, PATHNAMES * * ); /* add pathname to a search list */
void AddVar( char * szVarName ); /* add a new param, local, static variable to a function definition or a public or private */
PCOMSYMBOL AddSymbol( char * szSymbolName );
PCOMSYMBOL AddSymbol( char *, WORD * );
void CheckDuplVars( PVAR pVars, char * szVarName, int iVarScope ); /*checks for duplicate variables definitions */
void Dec( void ); /* generates the pcode to decrement the latest value on the virtual machine stack */
void DimArray( WORD wDimensions ); /* instructs the virtual machine to build an array with wDimensions */
@@ -188,6 +188,7 @@ void Duplicate( void ); /* duplicates the virtual machine latest stack latest va
void DupPCode( WORD wStart ); /* duplicates the current generated pcode from an offset */
void FixElseIfs( void * pIfElseIfs ); /* implements the ElseIfs pcode fixups */
void FixReturns( void ); /* fixes all last defined function returns jumps offsets */
WORD FixSymbolPos( WORD ); /* converts symbol's compile-time position into generation-time position */
void Function( BYTE bParams ); /* generates the pcode to execute a Clipper function pushing its result */
PFUNCTION FunctionNew( char *, char ); /* creates and initialises the _FUNC structure */
void FunDef( char * szFunName, SYMBOLSCOPE cScope, int iType ); /* starts a new Clipper language function definition */
@@ -199,9 +200,8 @@ PFUNCTION GetFuncall( char * szFunName ); /* locates a previously defined called
PVAR GetVar( PVAR pVars, WORD wOrder ); /* returns a variable if defined or zero */
WORD GetVarPos( PVAR pVars, char * szVarName ); /* returns the order + 1 of a variable if defined or zero */
int GetLocalVarPos( char * szVarName ); /* returns the order + 1 of a local variable */
PCOMSYMBOL GetSymbol( char * szSymbolName ); /* returns a symbol pointer from the symbol table */
PCOMSYMBOL GetSymbolOrd( WORD wSymbol ); /* returns a symbol based on its index on the symbol table */
WORD GetSymbolPos( char * szSymbolName ); /* returns the index + 1 of a symbol on the symbol table */
PCOMSYMBOL GetSymbol( char *, WORD * ); /* returns a symbol pointer from the symbol table */
PCOMSYMBOL GetSymbolOrd( WORD ); /* returns a symbol based on its index on the symbol table */
void Inc( void ); /* generates the pcode to increment the latest value on the virtual machine stack */
WORD Jump( int iOffset ); /* generates the pcode to jump to a specific offset */
WORD JumpFalse( int iOffset ); /* generates the pcode to jump if false */
@@ -440,6 +440,7 @@ PRETURN pReturns = 0; /* list of multiple returns from a function */
PEXTERN pExterns = 0;
PTR_LOOPEXIT pLoops = 0;
PATHNAMES *_pIncludePath = NULL;
FILENAME *_pFileName =NULL;
PSTACK_VAL_TYPE pStackValType = 0; /* compile time stack values linked list */
char cVarType = ' '; /* current declared variable type */
@@ -533,14 +534,14 @@ Line : LINE INTEGER LITERAL Crlf
Function : FunScope FUNCTION IDENTIFIER { cVarType = ' '; FunDef( $3, $1, 0 ); } Params Crlf { SetFrame(); }
| FunScope PROCEDURE IDENTIFIER { cVarType = ' '; FunDef( $3, $1, FUN_PROCEDURE ); } Params Crlf { SetFrame(); }
| FunScope DECLARE_FUN IDENTIFIER Params Crlf { cVarType = ' '; AddSymbol( $3 ); }
| FunScope DECLARE_FUN IDENTIFIER Params AS_NUMERIC Crlf { cVarType = 'N'; AddSymbol( $3 ); }
| FunScope DECLARE_FUN IDENTIFIER Params AS_CHARACTER Crlf { cVarType = 'C'; AddSymbol( $3 ); }
| FunScope DECLARE_FUN IDENTIFIER Params AS_DATE Crlf { cVarType = 'D'; AddSymbol( $3 ); }
| FunScope DECLARE_FUN IDENTIFIER Params AS_LOGICAL Crlf { cVarType = 'L'; AddSymbol( $3 ); }
| FunScope DECLARE_FUN IDENTIFIER Params AS_ARRAY Crlf { cVarType = 'A'; AddSymbol( $3 ); }
| FunScope DECLARE_FUN IDENTIFIER Params AS_OBJECT Crlf { cVarType = 'O'; AddSymbol( $3 ); }
| FunScope DECLARE_FUN IDENTIFIER Params AS_BLOCK Crlf { cVarType = 'B'; AddSymbol( $3 ); }
| FunScope DECLARE_FUN IDENTIFIER Params Crlf { cVarType = ' '; AddSymbol( $3, NULL ); }
| FunScope DECLARE_FUN IDENTIFIER Params AS_NUMERIC Crlf { cVarType = 'N'; AddSymbol( $3, NULL ); }
| FunScope DECLARE_FUN IDENTIFIER Params AS_CHARACTER Crlf { cVarType = 'C'; AddSymbol( $3, NULL ); }
| FunScope DECLARE_FUN IDENTIFIER Params AS_DATE Crlf { cVarType = 'D'; AddSymbol( $3, NULL ); }
| FunScope DECLARE_FUN IDENTIFIER Params AS_LOGICAL Crlf { cVarType = 'L'; AddSymbol( $3, NULL ); }
| FunScope DECLARE_FUN IDENTIFIER Params AS_ARRAY Crlf { cVarType = 'A'; AddSymbol( $3, NULL ); }
| FunScope DECLARE_FUN IDENTIFIER Params AS_OBJECT Crlf { cVarType = 'O'; AddSymbol( $3, NULL ); }
| FunScope DECLARE_FUN IDENTIFIER Params AS_BLOCK Crlf { cVarType = 'B'; AddSymbol( $3, NULL ); }
;
FunScope : { $$ = FS_PUBLIC; }
@@ -1168,7 +1169,6 @@ int harbour_main( int argc, char * argv[] )
char szFileName[ _POSIX_PATH_MAX ]; /* filename to parse */
char szPpoName[ _POSIX_PATH_MAX ];
char *szOutPath ="";
FILENAME *pFileName =NULL;
if( argc > 1 )
{
@@ -1314,19 +1314,19 @@ int harbour_main( int argc, char * argv[] )
}
}
else
pFileName =SplitFilename( argv[ iArg ] );
_pFileName =SplitFilename( argv[ iArg ] );
iArg++;
}
if( pFileName )
if( _pFileName )
{
if( !pFileName->extension )
pFileName->extension =".prg";
MakeFilename( szFileName, pFileName );
if( !_pFileName->extension )
_pFileName->extension =".prg";
MakeFilename( szFileName, _pFileName );
if ( lPpo )
{
pFileName->extension =".ppo";
MakeFilename( szPpoName, pFileName );
_pFileName->extension =".ppo";
MakeFilename( szPpoName, _pFileName );
yyppo = fopen ( szPpoName, "w" );
}
}
@@ -1370,8 +1370,20 @@ int harbour_main( int argc, char * argv[] )
}
AddSearchPath( pPath, &_pIncludePath );
}
FunDef( yy_strupr( yy_strdup( pFileName->name ) ), FS_PUBLIC, FUN_PROCEDURE );
/* Generate the starting procedure frame
*/
if( _iStartProc )
FunDef( yy_strupr( yy_strdup( _pFileName->name ) ), FS_PUBLIC, FUN_PROCEDURE );
else
/* Don't pass the name of module if the code for starting procedure
* will be not generated. The name cannot be placed as first symbol
* because this symbol can be used as function call or memvar's name.
*/
FunDef( yy_strupr( yy_strdup( "" ) ), FS_PUBLIC, FUN_PROCEDURE );
yyparse();
GenExterns(); /* generates EXTERN symbols names */
fclose( yyin );
files.pLast = NULL;
@@ -1391,53 +1403,53 @@ int harbour_main( int argc, char * argv[] )
_pInitFunc->pCode[ 2 ] =HIBYTE( _wStatics );
_pInitFunc->wStaticsBase =_wStatics;
pSym = AddSymbol( _pInitFunc->szName );
pSym = AddSymbol( _pInitFunc->szName, NULL );
pSym->cScope |= _pInitFunc->cScope;
functions.pLast->pNext = _pInitFunc;
++functions.iCount;
}
/* we create a the output file */
pFileName->path = szOutPath;
_pFileName->path = szOutPath;
switch( _iLanguage )
{
case LANG_C:
pFileName->extension =".c";
MakeFilename( szFileName, pFileName );
GenCCode( szFileName, pFileName->name );
_pFileName->extension =".c";
MakeFilename( szFileName, _pFileName );
GenCCode( szFileName, _pFileName->name );
break;
case LANG_JAVA:
pFileName->extension =".java";
MakeFilename( szFileName, pFileName );
GenJava( szFileName, pFileName->name );
_pFileName->extension =".java";
MakeFilename( szFileName, _pFileName );
GenJava( szFileName, _pFileName->name );
break;
case LANG_PASCAL:
pFileName->extension =".pas";
MakeFilename( szFileName, pFileName );
GenPascal( szFileName, pFileName->name );
_pFileName->extension =".pas";
MakeFilename( szFileName, _pFileName );
GenPascal( szFileName, _pFileName->name );
break;
case LANG_RESOURCES:
pFileName->extension =".rc";
MakeFilename( szFileName, pFileName );
GenRC( szFileName, pFileName->name );
_pFileName->extension =".rc";
MakeFilename( szFileName, _pFileName );
GenRC( szFileName, _pFileName->name );
break;
case LANG_PORT_OBJ:
pFileName->extension =".hrb";
MakeFilename( szFileName, pFileName );
GenPortObj( szFileName, pFileName->name );
_pFileName->extension =".hrb";
MakeFilename( szFileName, _pFileName );
GenPortObj( szFileName, _pFileName->name );
break;
}
}
#ifdef HARBOUR_OBJ_GENERATION
if( _iObj32 )
{
pFileName->extension = ".obj";
MakeFilename( szFileName, pFileName );
GenObj32( szFileName, pFileName->name );
_pFileName->extension = ".obj";
MakeFilename( szFileName, _pFileName );
GenObj32( szFileName, _pFileName->name );
}
#endif
if ( lPpo ) fclose ( yyppo );
@@ -1447,7 +1459,7 @@ int harbour_main( int argc, char * argv[] )
printf( "Can't open input file: %s\n", szFileName );
iStatus = 1;
}
OurFree( (void *) pFileName );
OurFree( (void *) _pFileName );
}
else
PrintUsage( argv[ 0 ] );
@@ -1735,6 +1747,7 @@ void AddVar( char * szVarName )
if( iVarScope & VS_MEMVAR )
{
PCOMSYMBOL pSym;
WORD wPos;
if( ! pFunc->pMemvars )
pFunc->pMemvars = pVar;
@@ -1749,41 +1762,38 @@ void AddVar( char * szVarName )
switch( iVarScope )
{
case VS_MEMVAR:
AddSymbol( yy_strdup(szVarName) );
/* variable declared in MEMVAR statement */
AddSymbol( yy_strdup(szVarName) );
pSym =AddSymbol( yy_strdup(szVarName), &wPos );
pSym->cScope |= VS_MEMVAR;
break;
case (VS_PARAMETER | VS_PRIVATE):
{
WORD wPos;
++functions.pLast->wParamCount;
pSym =GetSymbol( szVarName ); /* check if symbol exists already */
pSym =GetSymbol( szVarName, &wPos ); /* check if symbol exists already */
if( ! pSym )
pSym =AddSymbol( yy_strdup(szVarName) );
pSym =AddSymbol( yy_strdup(szVarName), &wPos );
pSym->cScope |= VS_MEMVAR;
wPos =GetSymbolPos( szVarName ) - ( _iStartProc ? 1: 2 );
GenPCode3( HB_P_PARAMETER, LOBYTE(wPos), HIBYTE(wPos) );
GenPCode1( LOBYTE(functions.pLast->wParamCount) );
}
break;
case VS_PRIVATE:
{
PushSymbol(yy_strdup("__PRIVATE"), 1);
PushSymbol(yy_strdup("__MVPRIVATE"), 1);
PushNil();
PushSymbol( yy_strdup(szVarName), 0 );
Do( 1 );
pSym =GetSymbol( szVarName );
pSym =GetSymbol( szVarName, &wPos );
pSym->cScope |= VS_MEMVAR;
}
break;
case VS_PUBLIC:
{
PushSymbol(yy_strdup("__PUBLIC"), 1);
PushSymbol(yy_strdup("__MVPUBLIC"), 1);
PushNil();
PushSymbol( yy_strdup(szVarName), 0 );
Do( 1 );
pSym =GetSymbol( szVarName );
pSym =GetSymbol( szVarName, &wPos );
pSym->cScope |= VS_MEMVAR;
}
break;
@@ -1836,7 +1846,7 @@ void AddVar( char * szVarName )
}
}
PCOMSYMBOL AddSymbol( char * szSymbolName )
PCOMSYMBOL AddSymbol( char * szSymbolName, WORD *pwPos )
{
PCOMSYMBOL pSym = ( PCOMSYMBOL ) OurMalloc( sizeof( COMSYMBOL ) );
@@ -1857,6 +1867,9 @@ PCOMSYMBOL AddSymbol( char * szSymbolName )
}
symbols.iCount++;
if( pwPos )
*pwPos =symbols.iCount;
/*if( cVarType != ' ') printf("\nDeclared %s as type %c at symbol %i\n", szSymbolName, cVarType, symbols.iCount );*/
return pSym;
}
@@ -2037,10 +2050,10 @@ void FunDef( char * szFunName, SYMBOLSCOPE cScope, int iType )
FixReturns(); /* fix all previous function returns offsets */
pSym = GetSymbol( szFunName );
pSym = GetSymbol( szFunName, NULL );
if( ! pSym )
/* there is not a symbol on the symbol table for this function name */
pSym = AddSymbol( szFunName );
pSym = AddSymbol( szFunName, NULL );
if( cScope != FS_PUBLIC )
// pSym->cScope = FS_PUBLIC;
@@ -2136,15 +2149,15 @@ void GenCCode( char *szFileName, char *szName ) /* generates the C languag
}
/* writes the symbol table */
/* fprintf( yyc, "\nstatic SYMBOL symbols[] = { " ); */
/* Generate the wrapper that will initialize local symbol table
*/
fprintf( yyc, "\n\nHB_INIT_SYMBOLS_BEGIN( %s__InitSymbols )\n", symbols.pFirst->szName );
yy_strupr( _pFileName->name );
fprintf( yyc, "\n\nHB_INIT_SYMBOLS_BEGIN( %s__InitSymbols )\n", _pFileName->name );
if( ! _iStartProc )
pSym = pSym->pNext; /* starting procedure is always the first symbol */
wSym = 0; /* syymbols counter */
wSym = 0; /* symbols counter */
while( pSym )
{
fprintf( yyc, "{ \"%s\", ", pSym->szName );
@@ -2168,25 +2181,22 @@ void GenCCode( char *szFileName, char *szName ) /* generates the C languag
if( pSym->cScope & VS_MEMVAR )
fprintf( yyc, " | VS_MEMVAR" );
/* specify the function address if it is a defined function or a
/* specify the function address if it is a defined function or an
external called function */
pFTemp = GetFunction( pSym->szName );
if( ! pFTemp ) /* if it is not a defined function */
pFTemp = GetFuncall( pSym->szName ); /* check if it is a function call */
if( pFTemp )
fprintf( yyc, ", HB_%s, 0 }", pFTemp->szName );
if( GetFunction( pSym->szName ) ) /* is it a function defined in this module */
fprintf( yyc, ", HB_%s, 0 }", pSym->szName );
else if( GetFuncall( pSym->szName ) ) /* is it a function called from this module */
fprintf( yyc, ", HB_%s, 0 }", pSym->szName );
else
fprintf( yyc, ", 0, 0 }" );
fprintf( yyc, ", 0, 0 }" ); /* memvar */
if( pSym != symbols.pLast )
fprintf( yyc, ",\n" );
pSym = pSym->pNext;
}
/* fprintf( yyc, " };\n\n" ); */
fprintf( yyc, "\nHB_INIT_SYMBOLS_END( %s__InitSymbols );\n", symbols.pFirst->szName );
fprintf( yyc, "#if ! defined(__GNUC__)\n#pragma startup %s__InitSymbols\n#endif\n\n\n", symbols.pFirst->szName );
fprintf( yyc, "\nHB_INIT_SYMBOLS_END( %s__InitSymbols );\n", _pFileName->name );
fprintf( yyc, "#if ! defined(__GNUC__)\n#pragma startup %s__InitSymbols\n#endif\n\n\n", _pFileName->name );
/* Generate functions data
*/
@@ -2377,12 +2387,17 @@ void GenCCode( char *szFileName, char *szName ) /* generates the C languag
break;
case HB_P_MESSAGE:
wSym = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256;
fprintf( yyc, " HB_P_MESSAGE, %i, %i, /* %s */\n",
pFunc->pCode[ lPCodePos + 1 ],
pFunc->pCode[ lPCodePos + 2 ],
GetSymbolOrd( wSym + ! _iStartProc )->szName );
lPCodePos += 3;
{
WORD wFixPos;
wSym = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256;
wFixPos =FixSymbolPos( wSym );
fprintf( yyc, " HB_P_MESSAGE, %i, %i, /* %s */\n",
LOBYTE( wFixPos ),
HIBYTE( wFixPos ),
GetSymbolOrd( wSym )->szName );
lPCodePos += 3;
}
break;
case HB_P_MINUS:
@@ -2421,13 +2436,18 @@ void GenCCode( char *szFileName, char *szName ) /* generates the C languag
break;
case HB_P_PARAMETER:
wVar = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256;
fprintf( yyc, " HB_P_PARAMETER, %i, %i, %i,\t/* %s */\n",
pFunc->pCode[ lPCodePos + 1 ],
pFunc->pCode[ lPCodePos + 2 ],
pFunc->pCode[ lPCodePos + 3 ],
GetSymbolOrd( wVar + ! _iStartProc )->szName );
lPCodePos += 4;
{
WORD wFixPos;
wVar = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256;
wFixPos =FixSymbolPos( wVar );
fprintf( yyc, " HB_P_PARAMETER, %i, %i, %i,\t/* %s */\n",
LOBYTE( wFixPos ),
HIBYTE( wFixPos ),
pFunc->pCode[ lPCodePos + 3 ],
GetSymbolOrd( wVar )->szName );
lPCodePos += 4;
}
break;
case HB_P_PLUS:
@@ -2471,12 +2491,17 @@ void GenCCode( char *szFileName, char *szName ) /* generates the C languag
break;
case HB_P_POPMEMVAR:
wVar = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256;
fprintf( yyc, " HB_P_POPMEMVAR, %i, %i,\t/* %s */\n",
pFunc->pCode[ lPCodePos + 1 ],
pFunc->pCode[ lPCodePos + 2 ],
GetSymbolOrd( wVar + ! _iStartProc )->szName );
lPCodePos += 3;
{
WORD wFixPos;
wVar = pFunc->pCode[ lPCodePos + 1 ] + pFunc->pCode[ lPCodePos + 2 ] * 256;
wFixPos =FixSymbolPos( wVar );
fprintf( yyc, " HB_P_POPMEMVAR, %i, %i,\t/* %s */\n",
LOBYTE( wFixPos ),
HIBYTE( wFixPos ),
GetSymbolOrd( wVar )->szName );
lPCodePos += 3;
}
break;
case HB_P_POPSTATIC:
@@ -2624,23 +2649,33 @@ void GenCCode( char *szFileName, char *szName ) /* generates the C languag
break;
case HB_P_PUSHMEMVAR:
wVar = pFunc->pCode[ lPCodePos + 1 ] +
pFunc->pCode[ lPCodePos + 2 ] * 256;
fprintf( yyc, " HB_P_PUSHMEMVAR, %i, %i,\t/* %s */\n",
pFunc->pCode[ lPCodePos + 1 ],
pFunc->pCode[ lPCodePos + 2 ],
GetSymbolOrd( wVar + ! _iStartProc )->szName );
lPCodePos += 3;
{
WORD wFixPos;
wVar = pFunc->pCode[ lPCodePos + 1 ] +
pFunc->pCode[ lPCodePos + 2 ] * 256;
wFixPos =FixSymbolPos( wVar );
fprintf( yyc, " HB_P_PUSHMEMVAR, %i, %i,\t/* %s */\n",
LOBYTE( wFixPos ),
HIBYTE( wFixPos ),
GetSymbolOrd( wVar )->szName );
lPCodePos += 3;
}
break;
case HB_P_PUSHMEMVARREF:
wVar = pFunc->pCode[ lPCodePos + 1 ] +
pFunc->pCode[ lPCodePos + 2 ] * 256;
fprintf( yyc, " HB_P_PUSHMEMVARREF, %i, %i,\t/* %s */\n",
pFunc->pCode[ lPCodePos + 1 ],
pFunc->pCode[ lPCodePos + 2 ],
GetSymbolOrd( wVar + ! _iStartProc )->szName );
lPCodePos += 3;
{
WORD wFixPos;
wVar = pFunc->pCode[ lPCodePos + 1 ] +
pFunc->pCode[ lPCodePos + 2 ] * 256;
wFixPos =FixSymbolPos( wVar );
fprintf( yyc, " HB_P_PUSHMEMVARREF, %i, %i,\t/* %s */\n",
LOBYTE( wFixPos ),
HIBYTE( wFixPos ),
GetSymbolOrd( wVar )->szName );
lPCodePos += 3;
}
break;
case HB_P_PUSHNIL:
@@ -2706,13 +2741,18 @@ void GenCCode( char *szFileName, char *szName ) /* generates the C languag
break;
case HB_P_PUSHSYM:
wSym = pFunc->pCode[ lPCodePos + 1 ] +
pFunc->pCode[ lPCodePos + 2 ] * 256;
fprintf( yyc, " HB_P_PUSHSYM, %i, %i, /* %s */\n",
pFunc->pCode[ lPCodePos + 1 ],
pFunc->pCode[ lPCodePos + 2 ],
GetSymbolOrd( wSym + ! _iStartProc )->szName );
lPCodePos += 3;
{
WORD wFixPos;
wSym = pFunc->pCode[ lPCodePos + 1 ] +
pFunc->pCode[ lPCodePos + 2 ] * 256;
wFixPos =FixSymbolPos( wSym );
fprintf( yyc, " HB_P_PUSHSYM, %i, %i, /* %s */\n",
LOBYTE( wFixPos ),
HIBYTE( wFixPos ),
GetSymbolOrd( wSym )->szName );
lPCodePos += 3;
}
break;
case HB_P_RETVALUE:
@@ -2724,7 +2764,8 @@ void GenCCode( char *szFileName, char *szName ) /* generates the C languag
/* we only generate it if there are statics used in this function */
if( pFunc->bFlags & FUN_USES_STATICS )
{
w = GetSymbolPos( _pInitFunc->szName ) - ( _iStartProc ? 1: 2 );
GetSymbol( _pInitFunc->szName, &w );
w = FixSymbolPos( w );
fprintf( yyc, " HB_P_SFRAME, %i, %i,\t\t/* symbol _INITSTATICS */\n",
LOBYTE( w ), HIBYTE( w ) );
}
@@ -2733,7 +2774,8 @@ void GenCCode( char *szFileName, char *szName ) /* generates the C languag
case HB_P_STATICS:
{
w = GetSymbolPos( _pInitFunc->szName ) - ( _iStartProc ? 1: 2 );
GetSymbol( _pInitFunc->szName, &w );
w = FixSymbolPos( w );
fprintf( yyc, " HB_P_STATICS, %i, %i,\t\t/* symbol _INITSTATICS */\n",
LOBYTE( w ), HIBYTE( w ) );
lPCodePos += 3;
@@ -2859,14 +2901,14 @@ void GenExterns( void ) /* generates the symbols for the EXTERN names */
while( pExterns )
{
if( GetSymbolPos( pExterns->szName ) )
if( GetSymbol( pExterns->szName, NULL ) )
{
if( ! GetFuncall( pExterns->szName ) )
AddFunCall( pExterns->szName );
}
else
{
AddSymbol( pExterns->szName );
AddSymbol( pExterns->szName, NULL );
AddFunCall( pExterns->szName );
}
pDelete = pExterns;
@@ -3094,19 +3136,37 @@ int GetStaticVarPos( char *szVarName )
return 0;
}
WORD FixSymbolPos( WORD wCompilePos )
{
return (_iStartProc ? wCompilePos-1 : wCompilePos-2);
}
PCOMSYMBOL GetSymbol( char * szSymbolName ) /* returns a symbol pointer from the symbol table */
/* returns a symbol pointer from the symbol table
* and sets its position in the symbol table
*/
PCOMSYMBOL GetSymbol( char * szSymbolName, WORD * pwPos )
{
PCOMSYMBOL pSym = symbols.pFirst;
WORD wCnt = 1;
if( pwPos )
*pwPos = 0;
while( pSym )
{
if( ! strcmp( pSym->szName, szSymbolName ) && pSym != symbols.pFirst )
if( ! strcmp( pSym->szName, szSymbolName ) )
{
if( pwPos )
*pwPos =wCnt;
return pSym;
}
else
{
if( pSym->pNext )
{
pSym = pSym->pNext;
++wCnt;
}
else
return 0;
}
@@ -3117,7 +3177,7 @@ PCOMSYMBOL GetSymbol( char * szSymbolName ) /* returns a symbol pointer from the
PCOMSYMBOL GetSymbolOrd( WORD wSymbol ) /* returns a symbol based on its index on the symbol table */
{
PCOMSYMBOL pSym = symbols.pFirst;
WORD w = 0;
WORD w = 1;
while( w++ < wSymbol && pSym->pNext )
pSym = pSym->pNext;
@@ -3125,29 +3185,6 @@ PCOMSYMBOL GetSymbolOrd( WORD wSymbol ) /* returns a symbol based on its index
return pSym;
}
WORD GetSymbolPos( char * szSymbolName ) /* return 0 if not found or order + 1 */
{
PCOMSYMBOL pSym = symbols.pFirst;
WORD wSymbol = 1;
while( pSym )
{
if( ! strcmp( pSym->szName, szSymbolName ) && pSym != symbols.pFirst )
return wSymbol;
else
{
if( pSym->pNext )
{
pSym = pSym->pNext;
wSymbol++;
}
else
return 0;
}
}
return 0;
}
WORD GetFunctionPos( char * szFunctionName ) /* return 0 if not found or order + 1 */
{
PFUNCTION pFunc = functions.pFirst;
@@ -3325,35 +3362,26 @@ void LineBody( void ) /* generates the pcode with the currently compiled source
*/
void MemvarPCode( BYTE bPCode, char * szVarName )
{
WORD wVar;
WORD wVar;
PCOMSYMBOL pVar;
GenWarning( WARN_AMBIGUOUS_VAR, szVarName, NULL );
GenWarning( WARN_AMBIGUOUS_VAR, szVarName, NULL );
if( ( wVar = GetSymbolPos( szVarName ) ) )
{
wVar -=(_iStartProc ? 1: 2);
GenPCode3( bPCode, LOBYTE( wVar ), HIBYTE( wVar ) );
}
else
{
AddSymbol( szVarName );
symbols.pLast->cScope =VS_MEMVAR;
wVar = GetSymbolPos( szVarName ) - (_iStartProc ? 1: 2);
GenPCode3( bPCode, LOBYTE( wVar ), HIBYTE( wVar ) );
}
pVar = GetSymbol( szVarName, &wVar );
if( ! pVar )
pVar =AddSymbol( szVarName, &wVar );
pVar->cScope |=VS_MEMVAR;
GenPCode3( bPCode, LOBYTE( wVar ), HIBYTE( wVar ) );
}
void Message( char * szMsgName ) /* sends a message to an object */
{
WORD wSym = GetSymbolPos( szMsgName );
WORD wSym;
PCOMSYMBOL pSym =GetSymbol( szMsgName, &wSym );
if( ! wSym ) /* the symbol was not found on the symbol table */
{
AddSymbol( szMsgName );
wSym = symbols.iCount;
}
GetSymbolOrd( wSym - 1 )->cScope |= FS_MESSAGE;
wSym -= _iStartProc ? 1: 2;
if( ! pSym ) /* the symbol was not found on the symbol table */
pSym =AddSymbol( szMsgName, &wSym );
pSym->cScope |= FS_MESSAGE;
GenPCode3( HB_P_MESSAGE, LOBYTE( wSym ), HIBYTE( wSym ) );
if( _iWarnings )
@@ -3361,7 +3389,7 @@ void Message( char * szMsgName ) /* sends a message to an object */
PSTACK_VAL_TYPE pNewStackType;
char cType;
cType = GetSymbolOrd( wSym - 1 )->cType;
cType = pSym->cType;
pNewStackType = ( STACK_VAL_TYPE * )OurMalloc( sizeof( STACK_VAL_TYPE ) );
pNewStackType->cType = cType;
@@ -3375,17 +3403,15 @@ void Message( char * szMsgName ) /* sends a message to an object */
void MessageDupl( char * szMsgName ) /* fix a generated message and duplicate to an object */
{
WORD wSetSym = GetSymbolPos( szMsgName );
WORD wSetSym;
PCOMSYMBOL pSym;
BYTE bLoGetSym, bHiGetSym; /* get symbol */
PFUNCTION pFunc = functions.pLast; /* get the currently defined Clipper function */
if( ! wSetSym ) /* the symbol was not found on the symbol table */
{
AddSymbol( szMsgName );
wSetSym = symbols.iCount;
}
GetSymbolOrd( wSetSym - 1 )->cScope |= FS_MESSAGE;
wSetSym -= _iStartProc ? 1: 2;
pSym =GetSymbol( szMsgName, &wSetSym );
if( ! pSym ) /* the symbol was not found on the symbol table */
pSym =AddSymbol( szMsgName, &wSetSym );
pSym->cScope |= FS_MESSAGE;
/* Get previously generated message */
bLoGetSym = pFunc->pCode[ _lMessageFix + 1];
bHiGetSym = pFunc->pCode[ _lMessageFix + 2];
@@ -3401,16 +3427,15 @@ void MessageDupl( char * szMsgName ) /* fix a generated message and duplicate t
void MessageFix( char * szMsgName ) /* fix a generated message to an object */
{
WORD wSym = GetSymbolPos( szMsgName );
WORD wSym;
PCOMSYMBOL pSym;
PFUNCTION pFunc = functions.pLast; /* get the currently defined Clipper function */
if( ! wSym ) /* the symbol was not found on the symbol table */
{
AddSymbol( szMsgName );
wSym = symbols.iCount;
}
GetSymbolOrd( wSym - 1 )->cScope |= FS_MESSAGE;
wSym -= _iStartProc ? 1: 2;
pSym =GetSymbol( szMsgName, &wSym );
if( ! pSym ) /* the symbol was not found on the symbol table */
pSym =AddSymbol( szMsgName, &wSym );
pSym->cScope |= FS_MESSAGE;
pFunc->pCode[ _lMessageFix + 1 ] = LOBYTE( wSym );
pFunc->pCode[ _lMessageFix + 2 ] = HIBYTE( wSym );
pFunc->lPCodePos -= 3; /* Remove unnecessary function call */
@@ -3706,7 +3731,8 @@ void PushString( char * szText )
/* generates the pcode to push a symbol on the virtual machine stack */
void PushSymbol( char * szSymbolName, int iIsFunction )
{
WORD wSym, wFunId;
WORD wSym;
PCOMSYMBOL pSym;
if( iIsFunction )
{
@@ -3720,15 +3746,10 @@ void PushSymbol( char * szSymbolName, int iIsFunction )
szSymbolName[ strlen( *pName ) ] ='\0';
}
wSym = wFunId = GetSymbolPos( szSymbolName ); /* returns 1, 2, ... */
if( wSym == 1 ) /* default module name procedure */
wSym = 0;
if( ! wSym ) /* the symbol was not found on the symbol table */
pSym = GetSymbol( szSymbolName, &wSym );
if( ! pSym ) /* the symbol was not found on the symbol table */
{
AddSymbol( szSymbolName );
wSym = symbols.iCount;
pSym =AddSymbol( szSymbolName, &wSym );
if( iIsFunction )
AddFunCall( szSymbolName );
}
@@ -3737,11 +3758,6 @@ void PushSymbol( char * szSymbolName, int iIsFunction )
if( iIsFunction && ! GetFuncall( szSymbolName ) )
AddFunCall( szSymbolName );
}
wSym -= _iStartProc ? 1: 2;
/*
if( ! iIsFunction )
GetSymbolOrd( wSym )->cScope |= FS_MESSAGE;
*/
GenPCode3( HB_P_PUSHSYM, LOBYTE( wSym ), HIBYTE( wSym ) );
if( _iWarnings )
@@ -3750,7 +3766,7 @@ void PushSymbol( char * szSymbolName, int iIsFunction )
char cType;
if( iIsFunction )
cType = GetSymbolOrd( wFunId - 1 )->cType;
cType = pSym->cType;
else
cType = cVarType;
@@ -4889,18 +4905,13 @@ void GenPortObj( char *szFileName, char *szName )
case HB_P_JUMPFALSE:
case HB_P_JUMPTRUE:
case HB_P_LINE:
case HB_P_MESSAGE:
case HB_P_POPLOCAL:
case HB_P_POPMEMVAR:
case HB_P_POPSTATIC:
case HB_P_PUSHINT:
case HB_P_PUSHLOCAL:
case HB_P_PUSHLOCALREF:
case HB_P_PUSHMEMVAR:
case HB_P_PUSHMEMVARREF:
case HB_P_PUSHSTATIC:
case HB_P_PUSHSTATICREF:
case HB_P_PUSHSYM:
fputc( pFunc->pCode[ lPCodePos++ ], yyc );
fputc( pFunc->pCode[ lPCodePos++ ], yyc );
fputc( pFunc->pCode[ lPCodePos++ ], yyc );
@@ -4920,11 +4931,25 @@ void GenPortObj( char *szFileName, char *szName )
}
break;
case HB_P_PUSHSYM:
case HB_P_MESSAGE:
case HB_P_POPMEMVAR:
case HB_P_PUSHMEMVAR:
case HB_P_PUSHMEMVARREF:
fputc( pFunc->pCode[ lPCodePos ], yyc );
wVar =FixSymbolPos( pFunc->pCode[ lPCodePos+1 ] + 256 *pFunc->pCode[ lPCodePos+2 ] );
fputc( LOBYTE( wVar ), yyc );
fputc( HIBYTE( wVar ), yyc );
lPCodePos +=3;
break;
case HB_P_PARAMETER:
fputc( pFunc->pCode[ lPCodePos++ ], yyc );
fputc( pFunc->pCode[ lPCodePos++ ], yyc );
fputc( pFunc->pCode[ lPCodePos++ ], yyc );
fputc( pFunc->pCode[ lPCodePos++ ], yyc );
fputc( pFunc->pCode[ lPCodePos ], yyc );
wVar =FixSymbolPos( pFunc->pCode[ lPCodePos+1 ] + 256 * pFunc->pCode[ lPCodePos+2 ] );
fputc( LOBYTE( wVar ), yyc );
fputc( HIBYTE( wVar ), yyc );
fputc( pFunc->pCode[ lPCodePos+3 ], yyc );
lPCodePos +=4;
break;
case HB_P_PUSHBLOCK:
@@ -4979,7 +5004,8 @@ void GenPortObj( char *szFileName, char *szName )
/* we only generate it if there are statics used in this function */
if( pFunc->bFlags & FUN_USES_STATICS )
{
w = GetSymbolPos( _pInitFunc->szName ) - ( _iStartProc ? 1: 2 );
GetSymbol( _pInitFunc->szName, &w );
w = FixSymbolPos( w );
fputc( pFunc->pCode[ lPCodePos ], yyc );
fputc( LOBYTE( w ), yyc );
fputc( HIBYTE( w ), yyc );
@@ -4990,7 +5016,8 @@ void GenPortObj( char *szFileName, char *szName )
break;
case HB_P_STATICS:
w = GetSymbolPos( _pInitFunc->szName ) - ( _iStartProc ? 1: 2 );
GetSymbol( _pInitFunc->szName, &w );
w = FixSymbolPos( w );
fputc( pFunc->pCode[ lPCodePos ], yyc );
fputc( LOBYTE( w ), yyc );
fputc( HIBYTE( w ), yyc );

View File

@@ -306,8 +306,11 @@ void hb_MemvarValueDecRef( HB_HANDLE hValue )
}
}
else if( (_globalLastFree - hValue) == 1 )
{
_globalLastFree =hValue; /* last item */
if( _globalLastFree == _globalFirstFree )
_globalFreeCnt =0;
}
else
++_globalFreeCnt;
@@ -317,7 +320,7 @@ void hb_MemvarValueDecRef( HB_HANDLE hValue )
}
}
/* This can happen if for example PUBLIC variable holds a codeblock with
* detached variable. When hb_MemvarsRelease(0 is called then detached
* detached variable. When hb_MemvarsRelease() is called then detached
* variable can be released before the codeblock. So if the codeblock
* will be released later then it will try to release again this detached
* variable.
@@ -348,7 +351,11 @@ void hb_MemvarSetValue( PSYMBOL pMemvarSymb, HB_ITEM_PTR pItem )
if( pDyn->hMemvar )
{
/* value is already created */
ItemCopy( &_globalTable[ pDyn->hMemvar ].item, pItem );
HB_ITEM_PTR pSetItem = &_globalTable[ pDyn->hMemvar ].item;
if( IS_BYREF(pSetItem) )
ItemCopy( ItemUnRef(pSetItem), pItem );
else
ItemCopy( pSetItem, pItem );
}
else
{
@@ -358,7 +365,7 @@ void hb_MemvarSetValue( PSYMBOL pMemvarSymb, HB_ITEM_PTR pItem )
}
}
else
hb_errorRT_BASE( EG_NOVAR, 1003, "Variable does not exist: ", pMemvarSymb->szName );
hb_errorRT_BASE( EG_NOVAR, 1003, "Unknown variable: ", pMemvarSymb->szName );
}
void hb_MemvarGetValue( HB_ITEM_PTR pItem, PSYMBOL pMemvarSymb )
@@ -374,14 +381,19 @@ void hb_MemvarGetValue( HB_ITEM_PTR pItem, PSYMBOL pMemvarSymb )
#endif
if( pDyn->hMemvar )
{
/* value is already created */
ItemCopy( pItem, &_globalTable[ pDyn->hMemvar ].item );
/* value is already created
*/
HB_ITEM_PTR pGetItem = &_globalTable[ pDyn->hMemvar ].item;
if( IS_BYREF(pGetItem) )
ItemCopy( pItem, ItemUnRef(pGetItem) );
else
ItemCopy( pItem, pGetItem );
}
else /* variable is not initialized */
hb_errorRT_BASE( EG_NOVAR, 1003, "Variable does not exist: ", pMemvarSymb->szName );
}
else
hb_errorRT_BASE( EG_NOVAR, 1003, "Variable does not exist: ", pMemvarSymb->szName );
hb_errorRT_BASE( EG_NOVAR, 1003, "Unknown variable: ", pMemvarSymb->szName );
}
void hb_MemvarGetRefer( HB_ITEM_PTR pItem, PSYMBOL pMemvarSymb )
@@ -397,10 +409,10 @@ void hb_MemvarGetRefer( HB_ITEM_PTR pItem, PSYMBOL pMemvarSymb )
#endif
if( pDyn->hMemvar )
{
/* value is already created */
pItem->type = IT_BYREF | IT_MEMVAR;
pItem->item.asMemvar.offset = 0;
pItem->item.asMemvar.value = pDyn->hMemvar;
/* value is already created */
pItem->item.asMemvar.itemsbase = &_globalTable;
++_globalTable[ pDyn->hMemvar ].counter;
}
@@ -408,7 +420,7 @@ void hb_MemvarGetRefer( HB_ITEM_PTR pItem, PSYMBOL pMemvarSymb )
hb_errorRT_BASE( EG_NOVAR, 1003, "Variable does not exist: ", pMemvarSymb->szName );
}
else
hb_errorRT_BASE( EG_NOVAR, 1003, "Variable does not exist: ", pMemvarSymb->szName );
hb_errorRT_BASE( EG_NOVAR, 1003, "Unknown variable: ", pMemvarSymb->szName );
}
/*
@@ -420,7 +432,7 @@ void hb_MemvarGetRefer( HB_ITEM_PTR pItem, PSYMBOL pMemvarSymb )
* bScope - the scope of created variable - if a variable with the same name
* exists already then it's value is hidden by new variable with
* passed scope
* pValue - optinal item used to initialize the value of created variable
* pValue - optional item used to initialize the value of created variable
* or NULL
*
*/
@@ -445,13 +457,15 @@ static void hb_MemvarCreateFromDynSymbol( PDYNSYM pDynVar, BYTE bScope, PHB_ITEM
if( bScope & VS_PUBLIC )
{
/* If the variable with the same name exists already
* then the current value have to be unchanged
*/
* then the current value have to be unchanged
*/
if( ! pDynVar->hMemvar )
{
pDynVar->hMemvar = hb_MemvarValueNew( pValue, TRUE );
if( !pValue )
{
/* new PUBLIC variable - initialize it to .F.
*/
_globalTable[ pDynVar->hMemvar ].item.type =IT_LOGICAL;
_globalTable[ pDynVar->hMemvar ].item.item.asLogical.value =0;
}
@@ -460,28 +474,89 @@ static void hb_MemvarCreateFromDynSymbol( PDYNSYM pDynVar, BYTE bScope, PHB_ITEM
else
{
/* We need to store the handle to the value of variable that is
* visible at this moment so later we can restore this value when
* the new variable will be released
*/
* visible at this moment so later we can restore this value when
* the new variable will be released
*/
HB_HANDLE hCurrentValue =pDynVar->hMemvar;
pDynVar->hMemvar = hb_MemvarValueNew( pValue, TRUE );
_globalTable[ pDynVar->hMemvar ].hPrevMemvar =hCurrentValue;
/* Add this variable to the PRIVATE variables stack
*/
hb_MemvarAddPrivate( pDynVar );
}
}
/*
* This function creates PUBLIC variable
*
* This function can be called either by the harbour compiler or by user.
* The compiler always passes the item of IT_SYMBOL type that stores the
* name of variable.
* If user calls this function then the passed argument/arguments can be:
* -a string with the name of variable to be created
* -an one-dimensional array with strings
/* This function releases
*/
HARBOUR HB___PUBLIC( void )
void hb_MemvarRelease( HB_ITEM_PTR pMemvar )
{
HB_HANDLE hVar, hOldValue;
PDYNSYM pDynVar;
if( IS_STRING(pMemvar) )
{
pDynVar =hb_GetDynSym( pMemvar->item.asString.value );
if( pDynVar )
{
hVar =pDynVar->hMemvar;
if( hVar )
{
hOldValue =_globalTable[ hVar ].hPrevMemvar;
hb_MemvarValueDecRef( hVar );
/*
* Restore previous value for variables that were overridden
*/
pDynVar->hMemvar =hOldValue;
}
}
}
else
hb_errorRT_BASE( EG_ARG, 3000, "Argument error: ", "RELEASE" );
}
/****************************************************************************
*/
/* $DOC$
* $FUNCNAME$
* __MVXPUBLIC()
* $CATEGORY$
* Variable management
* $ONELINER$
* This function creates a PUBLIC variable
* $SYNTAX$
* __MVPUBLIC( <variable_name> )
* $ARGUMENTS$
* <variable_name> = either a string that contains the variable's name or
* an one-dimensional array of strings with variable names
* No skeleton are allowed here.
* $RETURNS$
* Nothing
* $DESCRIPTION$
* This function can be called either by the harbour compiler or by user.
* The compiler always passes the item of IT_SYMBOL type that stores the
* name of variable.
* If a variable with the same name exists already then the new
* variable is not created - the previous value remains unchanged.
* If it is first variable with this name then the variable is
* initialized with .T. value.
*
* $EXAMPLES$
*
* $TESTS$
*
* $STATUS$
*
* $COMPLIANCE$
*
* $SEEALSO$
*
* $END$
*/
HARBOUR HB___MVPUBLIC( void )
{
int i, iCount = hb_pcount();
PHB_ITEM pMemvar;
@@ -514,17 +589,42 @@ HARBOUR HB___PUBLIC( void )
}
}
/*
* This function creates PRIVATE variable
/* $DOC$
* $FUNCNAME$
* __MVXPRIVATE()
* $CATEGORY$
* Variable management
* $ONELINER$
* This function creates a PRIVATE variable
* $SYNTAX$
* __MVPRIVATE( <variable_name> )
* $ARGUMENTS$
* <variable_name> = either a string that contains the variable's name or
* an one-dimensional array of strings with variable names
* No skeleton are allowed here.
* $RETURNS$
* Nothing
* $DESCRIPTION$
* This function can be called either by the harbour compiler or by user.
* The compiler always passes the item of IT_SYMBOL type that stores the
* name of variable.
* If a variable with the same name exists already then the value of old
* variable is hidden until the new variable is released. The new variable
* is always initialized to NIL value.
*
* $EXAMPLES$
*
* This function can be called either by the harbour compiler or by user.
* The compiler always passes the item of IT_SYMBOL type that stores the
* name of variable.
* If user calls this function then the passed argument/arguments can be:
* -a string with the name of variable to be created
* -an one-dimensional array with strings
* $TESTS$
*
* $STATUS$
*
* $COMPLIANCE$
*
* $SEEALSO$
*
* $END$
*/
HARBOUR HB___PRIVATE( void )
HARBOUR HB___MVPRIVATE( void )
{
int i, iCount = hb_pcount();
PHB_ITEM pMemvar;
@@ -561,3 +661,103 @@ HARBOUR HB___PRIVATE( void )
}
}
}
/* $DOC$
* $FUNCNAME$
* __MVXRELEASE()
* $CATEGORY$
* Variable management
* $ONELINER$
* This function releases value stored in PRIVATE or PUBLIC variable
* $SYNTAX$
* __MVXRELEASE( <variable_name> )
* $ARGUMENTS$
* <variable_name> = either a string that contains the variable's name or
* an one-dimensional array of strings with variable names
* No skeleton are allowed here.
* $RETURNS$
* Nothing
* $DESCRIPTION$
* This function releases values stored in memory variable. It shouldn't
* be called directly, rather it should be placed into RELEASE command.
* $EXAMPLES$
*
* $TESTS$
*
* $STATUS$
*
* $COMPLIANCE$
*
* $SEEALSO$
*
* $END$
*/
HARBOUR HB___MVXRELEASE( void )
{
int i, iCount = hb_pcount();
PHB_ITEM pMemvar;
if( iCount )
{
for( i=1; i<=iCount; i++ )
{
pMemvar =hb_param( i, IT_ANY );
if( pMemvar )
{
if( IS_ARRAY( pMemvar ) )
{
/* we are accepting an one-dimensional array of strings only
*/
ULONG j, ulLen = hb_arrayLen( pMemvar );
HB_ITEM VarItem;
for( j=1; j<=ulLen; j++ )
{
hb_arrayGet( pMemvar, j, &VarItem );
hb_MemvarRelease( &VarItem );
ItemRelease( &VarItem );
}
}
else
hb_MemvarRelease( pMemvar );
}
}
}
}
/* $DOC$
* $FUNCNAME$
* __MVRELEASE()
* $CATEGORY$
* Variable management
* $ONELINER$
* This function releases value stored in PRIVATE or PUBLIC variable
* $SYNTAX$
* __MVRELEASE( <skeleton>, <include_exclude_flag> )
* $ARGUMENTS$
* <skeleton> = string that contains the wildcard mask for variables' names
* that will be released. Supported wildcards: '*' and '?'
* <include_exclude_flag> = logical value that specifies if variables
* mathing passed skeleton should be either included in deletion (if .T.)
* or excluded from deletion (if .F.)
* $RETURNS$
* Nothing
* $DESCRIPTION$
* This function releases values stored in memory variables. It shouldn't
* be called directly, it should be placed into RELEASE ALL command.
* $EXAMPLES$
*
* $TESTS$
*
* $STATUS$
*
* $COMPLIANCE$
*
* $SEEALSO$
*
* $END$
*/
HARBOUR HB___MVRELEASE( void )
{
}

View File

@@ -1712,7 +1712,7 @@ double PopNumber( void )
void PopParameter( PSYMBOL pSym, BYTE bParam )
{
hb_MemvarSetValue( pSym, hb_param( bParam, IT_ANY ) );
hb_MemvarSetValue( pSym, stack.pBase +1 +bParam );
HB_DEBUG( "PopParameter\n" );
}

View File

@@ -3,6 +3,7 @@
// $Id$
//
PROCEDURE MAIN()
LOCAL main:=0
Test1()
__accept( "press Enter..." )
@@ -19,6 +20,8 @@ PROCEDURE MAIN()
Test7( 'value1', 2, .T. )
__accept( "press Enter..." )
Test8()
__accept( "press Enter..." )
Test9()
RETURN
@@ -168,7 +171,9 @@ PARAMETERS memparam
Qout( "PARAMETER after passing by reference= ", UseVar( @memparam ) )
// Qout( Use( @memnone ) )
#ifdef __HARBOUR__
Qout( "PUBLIC created by __PUBLIC function=", public1 )
#endif
Qout( "" )
RETURN
@@ -178,16 +183,17 @@ FUNCTION UseVar( value )
UseRef( @value )
__PUBLIC( "public1" ) //, "public21" )
// __PRIVATE( "private1", "private2", "private3" )
__PRIVATE( {"private1", "private2", "private3"} )
#ifdef __HARBOUR__
__mvPUBLIC( "public1" ) //, "public21" )
// __mvPRIVATE( "private1", "private2", "private3" )
__mvPRIVATE( {"private1", "private2", "private3"} )
Qout( "undeclared PUBLIC created by __PUBLIC function=", public1 )
Qout( "undeclared PRIVATE created by __PRIVATE function=", private1 )
Qout( "undeclared PRIVATE created by __PRIVATE function=", private2 )
Qout( "undeclared PRIVATE created by __PRIVATE function=", private3 )
public1 :='public created by __PUBLIC'
#endif
Qout( "" )
RETURN( value )
@@ -227,7 +233,7 @@ PARAM parameter1again
Qout( "Parameter 1 =", para1 )
Qout( "Parameter 2 =", para2 )
Qout( "Parameter 3 =", para3 )
Qout( "Parameter 4 =", parameter1again )
Qout( "Parameter 4 =", parameter1again )
RETURN
@@ -281,3 +287,34 @@ PARAMETER param2
Qout( "Param2 = ", param2 )
RETURN
//////////////////////////////////////////////////////////////////////
PROCEDURE TEST9()
PUBLIC memvar
PUBLIC memfunc
memvar :=19
Qout( "Variable with the name of module (memvar)=", memvar )
memfunc := 33
Qout( "Variable with the name of function =", memfunc )
Qout( "Return value from a function=", memfunc( 9 ) )
// mem()
RETURN
STATIC FUNCTION memfunc( memfunc )
RETURN memfunc * memfunc
INIT PROCEDURE initmem()
PARA memvar
PARA initmem
Qout( "Tests for PARAMETERS, PRIVATE nad PUBLIC variables" )
Qout( "" )
Qout( 'in INIT function - Passed parameter = ', memvar )
Qout( 'in INIT function - Passed parameter with different name = ', initmem )
Qout( "" )
RETURN