Welcome To The Home Of The Visual FoxPro Experts  
home. signup. forum. archives. search. google. articles. downloads. faq. members. weblogs. file info. rss.
 From: Boudewijn Lutgerink
  Where is Boudewijn Lutgerink?
 Hoonaardstraat, Driel
 Netherlands
 Boudewijn Lutgerink
 Tags
Subject: Implementing VFP Funcs in NetCompiler
Thread ID: 209429 Message ID: 209429 # Views: 65 # Ratings: 1
Version: Visual FoxPro 9 Category: 3rd Party Software
Date: Sunday, December 28, 2008 5:30:29 PM         
   


Today I found an interesting whitepaper, written by Pertti Karjalainen, one enthusiastic NetCompiler user.

It is all about how to implement your own VFP functions in the Net Compiler.

***
If you know VFP, even a little (and even if you don't know much at all about .NET), you, too, can participate in building a fully VFP syntax -compatible compiler for .NET. All you need to know is VFP syntax, you don't need to know C# or VB.NET or any other "foreign" stuff, to get started at least.


Disclaimer: I am in no way affiliated with eTecnologia.net, financially or otherwise. Heck, I don't even know where these guys are located! But the budding technology here is quite amazing and holds a lot of promise for us soon-to-be-orphaned-from-Microsoft VFP developers.


To demonstrate how simple it is for pretty much anyone to help out here, I created a new BETWEEN() -function for .NET that is 100% compatible with the same VFP function. This was one of the functions "Not yet implemented" http://www.etecnologia.net/Products/VFPCompiler/ImplementedFunctionality.htm.

To differentiate the .NET version from the VFP version for unit testing, I prefaced the function name with "_", but this is by no means a generally accepted way, it just made sense to me. Which is not to say that it might not collide with internal .NET functions or accepted .NET syntax rules.)

And here's what the .NET BETWEEN() -function/procedure looks like:


FUNCTION BETWEEN  
   LPARAMETERS tu1, tu2, tu3
   LOCAL llRetVal
   llRetVal = .T.
   IF VARTYPE(tu1) = 'U' OR VARTYPE(tu2) = 'U' OR VARTYPE(tu3) = 'U'
      ?"ERROR: Invalid number of parameters!"   && Error handling stub
      llRetVal = .F.
   ENDIF
   IF llREtVal = .T. AND ;
      ( VARTYPE(tu1) != VARTYPE(tu2) OR ;
        VARTYPE(tu1) != VARTYPE(tu3) OR ;
        VARTYPE(tu2) != VARTYPE(tu3) ;
      )
      ?"ERROR: Data type mismatch!"   && Error handling stub
      llRetVal = .F.
   ENDIF
   IF llRetVal = .T.
      llRetVal = .F.
      IF tu1 >= tu2 AND tu1 <= tu3
         llRetVal = .T.
      ENDIF
   ENDIF
RETURN llRetVal


&& To call the function, you would do this: 
? _BETWEEN(1,2,3)
? _BETWEEN('B','A','C')
etc.

You can actually check this code out for yourself.

1. Copy and paste the function code into: http://etecnologia.net/onlinecompiler/

1.1. Add the function calls to the top of the listing

2. Click "Compile and generate assembly"

3. Download the generated Mydemo.exe to your computer (click the Mydemo.exe -link)

4. Make sure that you have also downloaded and extracted the VFP Runtime ZIP file from the same page into the same folder where your mydemo.exe is

5. Go to the VFP compiler folder in MS-DOS prompt

6. Type MYDEMO.EXE

7. See the resulting output

It really is that easy. And now we have added one more of the as-of-yet unimplemented functions (BETWEEN()) to the VFP .NET compiler. Granted, this is an easy one, but the majority of the missing functions are about as easy. And the funny thing is that this is both the egg and the hen, since we are writing VFP syntax to implement VFP syntax. Boggles the mind.

And here's my unit test listing, which may serve as a template (to be improved, for sure). This unit test makes sure that the _BETWEEN() function behaves exactly like the VFP's BETWEEN () function under all circumstances.


Test cases for BETWEEN_E -function (etechnologia replacement for VFP BETWEEN(var1, var2, var3)NOTES: Run this test in VFP, not the .NET compiler!This test covers the most likely data types: numeric, date and character.To complete unit test, we should probably add all of other possible VFP data types.


        *Pertti Karjalainen
	*Northern Lights Software
	*pertti@northernlightssoftware.com
	*Original code: 3-26-07
	*	CLEAR
	SET CONSOLE OFF
	SET ALTERNATE TO Test_between
	SET ALTERNATE ON
	&& all possible test cases (I hope!)	&& numeric:	_BETWEEN(1,1,1)		&&same, same, same
	_BETWEEN(2,2,2)		&&same, same, same
	_BETWEEN(3,3,3)		&&same, same, same	_BETWEEN(1,1,2)		&&small, small, medium
	_BETWEEN(1,2,2)		&&small, medium, medium
	_BETWEEN(1,2,1)		&&small, medium, small	_BETWEEN(1,1,3)		&&small, small, large
	_BETWEEN(1,3,3)		&&small, large, large
	_BETWEEN(1,3,1)		&&small, large, small	_BETWEEN(1,3,2)		&&small, large, medium
	_BETWEEN(1,2,3)		&&small, medium, large	_BETWEEN(2,1,2)		&&medium, small, medium
	_BETWEEN(2,2,2)		&&medium, medium, medium
	_BETWEEN(2,2,1)		&&medium, medium, small	_BETWEEN(2,1,3)		&&medium, small, large
	_BETWEEN(2,3,3)		&&medium, large, large
	_BETWEEN(2,3,1)		&&medium, large, small	_BETWEEN(2,3,2)		&&medium, large, medium
	_BETWEEN(2,2,3)		&&medium, medium, large	_BETWEEN(3,1,2)		&&large, small, medium
	_BETWEEN(3,2,2)		&&large, medium, medium
	_BETWEEN(3,2,1)		&&large, medium, small	_BETWEEN(3,1,3)		&&large, small, large
	_BETWEEN(3,3,3)		&&large, large, large
	_BETWEEN(3,3,1)		&&large, large, small	_BETWEEN(3,3,2)		&&large, large, medium
	_BETWEEN(3,2,3)		&&large, medium, large		*Characters
	_BETWEEN('A','A','A')		&&same, same, same
	_BETWEEN('B','B','B')		&&same, same, same
	_BETWEEN('C','C','C')		&&same, same, same	_BETWEEN('A','A','B')		&&small, small, medium
	_BETWEEN('A','B','B')		&&small, medium, medium
	_BETWEEN('A','B','A')		&&small, medium, small	_BETWEEN('A','A','C')		&&small, small, large
	_BETWEEN('A','C','C')		&&small, large, large
	_BETWEEN('A','C','A')		&&small, large, small	_BETWEEN('A','C','B')		&&small, large, medium
	_BETWEEN('A','B','C')		&&small, medium, large	_BETWEEN('B','A','B')		&&medium, small, medium
	_BETWEEN('B','B','B')		&&medium, medium, medium
	_BETWEEN('B','B','A')		&&medium, medium, small	_BETWEEN('B','A','C')		&&medium, small, large
	_BETWEEN('B','C','C')		&&medium, large, large
	_BETWEEN('B','C','A')		&&medium, large, small	_BETWEEN('B','C','B')		&&medium, large, medium
	_BETWEEN('B','B','C')		&&medium, medium, large	_BETWEEN('C','A','B')		&&large, small, medium
	_BETWEEN('C','B','B')		&&large, medium, medium
	_BETWEEN('C','B','A')		&&large, medium, small	_BETWEEN('C','A','C')		&&large, small, large
	_BETWEEN('C','C','C')		&&large, large, large
	_BETWEEN('C','C','A')		&&large, large, small	_BETWEEN('C','C','B')		&&large, large, medium
	_BETWEEN('C','B','C')		&&large, medium, large											*Dates
	_BETWEEN(DATE(),DATE(),DATE())		&&same, same, same
	_BETWEEN(DATE()+1,DATE()+1,DATE()+1)		&&same, same, same
	_BETWEEN(DATE()+2,DATE()+2,DATE()+2)		&&same, same, same	_BETWEEN(DATE(),DATE(),DATE()+1)		&&small, small, medium
	_BETWEEN(DATE(),DATE()+1,DATE()+1)		&&small, medium, medium
	_BETWEEN(DATE(),DATE()+1,DATE())		&&small, medium, small	_BETWEEN(DATE(),DATE(),DATE()+2)		&&small, small, large
	_BETWEEN(DATE(),DATE()+2,DATE()+2)		&&small, large, large
	_BETWEEN(DATE(),DATE()+2,DATE())		&&small, large, small	_BETWEEN(DATE(),DATE()+2,DATE()+1)		&&small, large, medium
	_BETWEEN(DATE(),DATE()+1,DATE()+2)		&&small, medium, large	_BETWEEN(DATE()+1,DATE(),DATE()+1)		&&medium, small, medium
	_BETWEEN(DATE()+1,DATE()+1,DATE()+1)	&&medium, medium, medium
	_BETWEEN(DATE()+1,DATE()+1,DATE())		&&medium, medium, small	_BETWEEN(DATE()+1,DATE(),DATE()+2)		&&medium, small, large
	_BETWEEN(DATE()+1,DATE()+2,DATE()+2)	&&medium, large, large
	_BETWEEN(DATE()+1,DATE()+2,DATE())		&&medium, large, small	_BETWEEN(DATE()+1,DATE()+2,DATE()+1)	&&medium, large, medium
	_BETWEEN(DATE()+1,DATE()+1,DATE()+2)	&&medium, medium, large	_BETWEEN(DATE()+2,DATE(),DATE()+1)		&&large, small, medium
	_BETWEEN(DATE()+2,DATE()+1,DATE()+1)	&&large, medium, medium
	_BETWEEN(DATE()+2,DATE()+1,DATE())		&&large, medium, small	_BETWEEN(DATE()+2,DATE(),DATE()+2)		&&large, small, large
	_BETWEEN(DATE()+2,DATE()+2,DATE()+2)	&&large, large, large
	_BETWEEN(DATE()+2,DATE()+2,DATE())		&&large, large, small	_BETWEEN(DATE()+2,DATE()+2,DATE()+1)	&&large, large, medium
	_BETWEEN(DATE()+2,DATE()+1,DATE()+2)	&&large, medium, large										
	*--error conditions
	_BETWEEN(2,1)				&&too few parameters
	_BETWEEN(2,'A')				&&data mismatch	SET ALTERNATE TO
	MODIFY COMMAND TEST_BETWEEN.TXT NOWAIT
RETURNFUNCTION _BETWEEN  
   LPARAMETERS tu1, tu2, tu3
   LOCAL llRetVal
   llRetVal = .T.
   IF VARTYPE(tu1) = 'U' OR VARTYPE(tu2) = 'U' OR VARTYPE(tu3) = 'U'
      ?"ERROR: Invalid number of parameters!"   && Error handling stub
      llRetVal = .F.
   ENDIF
   IF llREtVal = .T. AND ;
      ( VARTYPE(tu1) != VARTYPE(tu2) OR ;
        VARTYPE(tu1) != VARTYPE(tu3) OR ;
        VARTYPE(tu2) != VARTYPE(tu3) ;
      )
      ?"ERROR: Data type mismatch!"   && Error handling stub
      llRetVal = .F.
   ENDIF
   IF llRetVal = .T.
      llRetVal = .F.
      IF (tu1 >= tu2 AND tu1 <= tu3
         llRetVal = .T.
      ENDIF
   ENDIF
   CompareResults(tu1, tu2, tu3, llRetVal)	&&Compare the result from this function with that of VFP function
RETURN llRetVal
FUNCTION CompareResults(tu1, tu2, tu3, llRetVal)
	?'Function: BETWEEN('+TRANSFORM(tu1)+', '+TRANSFORM(tu2)+', '+TRANSFORM(tu3)+')'
	?'	Test Result: '+TRANSFORM(llRetVal)
	?'	VFPFunction: '+TRANSFORM(BETWEEN(tu1, tu2, tu3))
	IF llRetVal != BETWEEN(tu1, tu2, tu3)
		?'	NOT OK!'
	ELSE
		?'	Ok.'
	ENDIF
ENDFUNC


So, what are you waiting for? Implement your own "pet" function, test it thoroughly and then send it over to etechnologia.net, so that can be integerated and implemented as a truly .NET compatible VFP function for the entire community!

Boudewijn LutgeĀ®ink
http://www.vfpdevelopers-online.com
The truth will set you free, Ken knew the truth!

COMPLETE THREAD

Implementing VFP Funcs in NetCompiler Posted by Boudewijn Lutgerink @ 12/28/2008 5:30:29 PM
RE: Implementing VFP Funcs in NetCompiler Posted by Tom Saddul @ 12/29/2008 7:20:33 AM
RE: Implementing VFP Funcs in NetCompiler Posted by Camil Ghircoias @ 12/29/2008 10:37:44 AM