MEMVARs, PUBLICs etc.

This forum is meant for questions and discussions about the X# language and tools
Karl-Heinz
Posts: 774
Joined: Wed May 17, 2017 8:50 am
Location: Germany

MEMVARs, PUBLICs etc.

Post by Karl-Heinz »

Hi Robert

i´ve looked at the _Mxxx() memvar funcs and it looks good. The only problem so far is the _MRelease() behaviour.

i had to change the line:

WHILE text != __Symbol{""}

to:

WHILE text != NULL

otherwise the DO .. WHILE is in a endless loop

Code: Select all

FUNCTION Start( ) AS VOID 
PRIVATE x1, x2,x3 

	x1 := 1 
	x2 := 2
	x3 := 3 
	

	 ? "Number of PRIVATEs:" , memvar:PrivatesCount()   // 3 
	 ?
	 
     ? "private x1 content before _MRelease()" , x1    // 1
     ? "private x2 content before _MRelease()" , x2     // 2
     ? "private x3 content before _MRelease()" , x3	 // 3
	
// 	 _MRelease ( "x*" , FALSE )  // ok, doesn´t release any of the privates 
   	 _MRelease ( "x*" , TRUE )  // ok, does release x1, x2 and x3 
//	 _MRelease ( "x1" , FALSE )  // ok, does release x2 and x3 only  	    
//	 _MRelease ( "x1" , TRUE )  // ok, does release x1 only  		
     
	 ?
     ? "private x1 content after _MRelease()" , x1   
     ? "private x2 content after _MRelease()" , x2   
     ? "private x3 content after _MRelease()" , x3   	
     ?
	 ? "Number of PRIVATEs before _MClear():" , memvar:PrivatesCount()   // 3
	 
  	?  
   	_MCLEAR() // remove all privates and publics
   	?
  	? "Number of PRIVATEs after _MClear():" , memvar:PrivatesCount()  // 0  		
    ?	   
		
	RETURN

// overrides the Xsharp.RT  _MRelease()
FUNCTION _MRelease(cMask AS STRING , lMatch AS LOGIC ) AS VOID
	LOCAL text AS STRING
	//
	cMask := XSharp.Core.Functions.Upper(cMask)
	text := _PrivateFirst(FALSE)
	WHILE text != NULL // __Symbol{""} //  KHR changed to NULL 
		IF (XSharp.Core.Functions._Like(cMask, text) == lMatch)
			MemVarPut(text, __Usual._NIL)
		ENDIF
		text := _PrivateNext()
	END WHILE    

regards
Karl-Heinz
User avatar
wriedmann
Posts: 3755
Joined: Mon Nov 02, 2015 5:07 pm
Location: Italy

MEMVARs, PUBLICs etc.

Post by wriedmann »

Hi Robert,

may I suggest to add functions without underscores and document them officially?
They are particularly interesting for macro evaluation, to inject variables into the macro compiler.

Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
Karl-Heinz
Posts: 774
Joined: Wed May 17, 2017 8:50 am
Location: Germany

MEMVARs, PUBLICs etc.

Post by Karl-Heinz »

Hi Wolfgang,

There are 5 funcs:

_MRelease()
_MXReleaese()
_MSave()
_MRestore()
_MClear()

and none of them are documented in VO, so i´m sure the intention is not to use these funcs directly. In VO they are only used if a command like "SAVE ..." is included, that the preprocessor translates to "_MSave ( .... ). Of course almost none of the VOers use PRIVATES and PUBLICs anymore, but they are essential for e.g. Foxpro users.

regards
Karl-Heinz
User avatar
wriedmann
Posts: 3755
Joined: Mon Nov 02, 2015 5:07 pm
Location: Italy

MEMVARs, PUBLICs etc.

Post by wriedmann »

Hi Karl-Heinz,

it would be interesting to have them documented and usable officially because they can help when pushing variables to the macrocompiler (this is the only case where I would need them).
Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
Karl-Heinz
Posts: 774
Joined: Wed May 17, 2017 8:50 am
Location: Germany

MEMVARs, PUBLICs etc.

Post by Karl-Heinz »

wriedmann wrote:Hi Karl-Heinz,

it would be interesting to have them documented
The functions are described in the XSharp runtime help.

regards
Karl-Heinz
Karl-Heinz
Posts: 774
Joined: Wed May 17, 2017 8:50 am
Location: Germany

MEMVARs, PUBLICs etc.

Post by Karl-Heinz »

Hi Wolfgang

you can do funny things with the memvar internals :-)

__MemVarDecl("c" , TRUE ) // create a private
__MemVarPut ( "c" , 100 )
// Memvar:put( "c" ,100 )

__MemVarDecl("d" , TRUE ) // create another private
__MemVarPut ( "d" , "c" )
// Memvar:put( "d" ,"c" )

? &("d" ) // "c"
? & ( &("d" ) ) + 100 // 200

regards
Karl-Heinz
User avatar
wriedmann
Posts: 3755
Joined: Mon Nov 02, 2015 5:07 pm
Location: Italy

MEMVARs, PUBLICs etc.

Post by wriedmann »

Hi Karl-Heinz,
you can do funny things with the memvar internals
I know!
Specially with macros or code blocks they are very powerful.

But also the .NET architects have seen the need for dynamic variables and added the Expando class, and dynamics.
But the VO/X# implementation IMHO is much more powerful.

Wolfgang
Wolfgang Riedmann
Meran, South Tyrol, Italy
wolfgang@riedmann.it
https://www.riedmann.it - https://docs.xsharp.it
Karl-Heinz
Posts: 774
Joined: Wed May 17, 2017 8:50 am
Location: Germany

MEMVARs, PUBLICs etc.

Post by Karl-Heinz »

Hi Robert,

I looked at the Foxpro RELEASE command.

-- Foxpro code ---

x = 12

RELEASE x

? x && Foxpro error "var 'x' not found" is thrown

--------

While the VO/X# RELEASE doesn´t delete a var, the Foxpro RELEASE does. In the X# runtime there´s already the method memVar:ClearAll(), but what´s IMO missing is something like MemVar:Clear ( <cVar>), so the Foxpro RELEASE could be mapped to memVar:Clear ( "x" ).

what do you think ?

regards
Karl-Heinz
User avatar
robert
Posts: 4520
Joined: Fri Aug 21, 2015 10:57 am
Location: Netherlands

MEMVARs, PUBLICs etc.

Post by robert »

Karl-Heinz,

This shows exactly how tricky it can be to support more than one dialect.
The current implementation of RELEASE does what the VO docs say.

"This command does not actually delete the specified variables from memory like CLEAR ALL or CLEAR MEMORY. Instead, it releases the value of the variables by assigning NIL to them. For this reason, variables that are hidden do not become visible until termination of the routine initiating the RELEASE operation."

To solve this problem I see 2 solutions:
1) have a different header file for VO and FOX or different implementations in the same header file (using conditional compilation) that map the RELEASE command to different function calls
2) Detect the active dialect at runtime and change the behavior of the _MRelease() function depending on the active dialect.

When choosing 1) we could also introduce a new command (or a new clause ) for VO to allow also code in the VO Dialect to completely remove the variables.

Robert
XSharp Development Team
The Netherlands
robert@xsharp.eu
Karl-Heinz
Posts: 774
Joined: Wed May 17, 2017 8:50 am
Location: Germany

MEMVARs, PUBLICs etc.

Post by Karl-Heinz »

Hi Robert/Chris,

i´m playing with my beloved privates again :-)

i checked the Type(), UsualType() and ValType() results. The only problem seems to be the Type() result of a NIL var. It shows "O" instead of "U"

@All: i also added some X# and Foxpro ;-) Eval tests. Once again, it's amazing to see what´s possible with X# !

Code: Select all


FUNCTION TestTypes()	
PRIVATE x0, x1, x2,x3, x4, x5, x6, x7,x8, x9 , x10 , x11 , c

   
    	x0 := 12.22  
	x1 := 1 
	x2 := "1234"
	x3 := today()
	x4 := { "1" , 12 } 
	x5 := NIL 	
	x6 := {|| }	
	x7 := TRUE 
	x8 := NULL_OBJECT 
	x9 := #TEST 
	x10 := NULL_PTR
	x11 := NULL_PSZ
	
	
	? Type ( "x0" ) , UsualType( x0 )  , ValType( x0 )	// N  , 3  , N
	? Type ( "x1" ) , UsualType( x1 )  , ValType( x1 )	// N  , 1  , N
	? Type ( "x2" ) , UsualType( x2 )  , ValType( x2 )  // C  , 7  , C
	? Type ( "x3" ) , UsualType( x3 )  , ValType( x3 )	// D  , 2  , D
	? Type ( "x4" ) , UsualType( x4 )  , ValType( x4 )	// A  , 5  , A 
	? Type ( "x4[1]" ) , UsualType( x4[1] )  , ValType( x4[1] )// C	 , 7 , C 	 
	? Type ( "x4[2]" ) , UsualType( x4[2] )  , ValType( x4[2] )// N  , 1 , N 	 	 	
	? Type ( "x5" )	 , UsualType( x5 ) , ValType( x5 )	// O <--instead of U  , 0  , U 
	? Type ( "x6" )	, UsualType( x6 )  , ValType( x6 )	// B  , 9  , B	
	? Type ( "x7" )	, UsualType( x7 )  , ValType( x7 )	// L	, 8  , L	
	? Type ( "x8" )	, UsualType( x8 )  , ValType( x8 )	// O 	, 6  , O
	? Type ( "x9" ) , UsualType( x9 )  , ValType( x9 )	// #  , 10 , #
	? type ( "x10" ) , UsualType ( x10 )  , ValType( x10 )	// - , 18 , - 
	? type ( "x11" ) , UsualType ( x11 )  , ValType( x11 )	// C , 7 , C 
	? 

	// NIL is evaluated as a NULL_OBJECT, so Type() returns "O" instead of "U"
	?  Evaluate( "x5" ) == NULL_OBJECT // TRUE	
    ?  &x5 == NULL_OBJECT   // TRUE 
    ?
    ?
   	? Eval( MCompile("substr(x2,1,2)") )  //  "12"
  	? Eval( MCompile("padl(x2,8,'0')") )  // "00001234" 
  	?
  	? &("substr(x2,1,2)") 			//  "12" 
  	c := "substr(x2,1,2)"
  	? &c  							//  "12" 
   	? Evaluate( "substr(x2,1,2)")   //  "12"
  	?
  	? &("padl(x2,8,'0')") 			// "00001234" 
  	c := "padl(x2,8,'0')"
  	? &c  							//  "00001234" 
  	? Evaluate ( "padl(x2,8,'0')" ) // "00001234" 
  	? 

 
   	//
  	// same running with Foxpro 
 	//

/*      
	clear
	set talk off

	DO TestEval



	PROCEDURE TestEval
	Private x2, c 


	x2 = "1234"

	? Evaluate ( "Substr(x2,1,2)" )  &&  "12"
	c = "substr(x2,1,2)"    
	? &c				&&  "12"			

	? Evaluate ( "padl(x2,8,'0')" )  && "00001234"
	c = "padl(x2,8,'0')"    
	? &c				&& "00001234"  

*/  	

regards
Karl-Heinz
Post Reply