diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 595ef4afd0..6a6f8135ad 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -1,3 +1,34 @@ +19990725-01:00 GMT+2 Ryszard Glab + + *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 diff --git a/harbour/source/compiler/harbour.l b/harbour/source/compiler/harbour.l index cf6a1880cd..cac01e1357 100644 --- a/harbour/source/compiler/harbour.l +++ b/harbour/source/compiler/harbour.l @@ -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 ) ); + } +{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; + } + } +{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; diff --git a/harbour/source/compiler/harbour.y b/harbour/source/compiler/harbour.y index def87f0421..3d36095f35 100644 --- a/harbour/source/compiler/harbour.y +++ b/harbour/source/compiler/harbour.y @@ -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 ); diff --git a/harbour/source/rtl/memvars.c b/harbour/source/rtl/memvars.c index 76b6fc3e3d..c102f379ef 100644 --- a/harbour/source/rtl/memvars.c +++ b/harbour/source/rtl/memvars.c @@ -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( ) + * $ARGUMENTS$ + * = 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( ) + * $ARGUMENTS$ + * = 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( ) + * $ARGUMENTS$ + * = 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( , ) + * $ARGUMENTS$ + * = string that contains the wildcard mask for variables' names + * that will be released. Supported wildcards: '*' and '?' + * = 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 ) +{ +} diff --git a/harbour/source/vm/hvm.c b/harbour/source/vm/hvm.c index 833d0da4da..88e31d5780 100644 --- a/harbour/source/vm/hvm.c +++ b/harbour/source/vm/hvm.c @@ -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" ); } diff --git a/harbour/tests/working/memvar.prg b/harbour/tests/working/memvar.prg index 4421e0ffb2..647fc6bc77 100644 --- a/harbour/tests/working/memvar.prg +++ b/harbour/tests/working/memvar.prg @@ -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