xsharp.eu • Implementing missing VFP functions
Page 1 of 4

Implementing missing VFP functions

Posted: Wed Mar 17, 2021 6:45 pm
by Chris
Hello all!

One of the remaining tasks for properly supporting VFP in X#, is to implement the missing FoxPro-specific functions. We will soon start working on that, but we need your help in order to prioritize what gets done first. You can see a list of those already implemented and many missing in the runtime source code here: https://github.com/X-Sharp/XSharpPublic ... XSharp.VFP

The .prg files with filenames Todo* contain those that are not implemented in the X# runtime yet (they have an empty body) and I am sure there exist others that are still missing and have not been included in the list yet. So can you please let us know which missing functions are being used more often in VFP applications or are most important, so should be implemented with higher priority? And of course, if you'd like to further contribute by impementing some of those yourselves, that would be most welcome!

Implementing missing VFP functions

Posted: Wed Mar 17, 2021 6:54 pm
by Eric Selje
I'm trying to think if there's a tool that VFP devs can run on their codebase that counts up function call into a nice report. Anybody know of such a thing. A profiler of sorts.

Implementing missing VFP functions

Posted: Thu Mar 18, 2021 1:55 am
by FoxProMatt
Let me give a reminder that most (non-dbf related) FoxPro functions were implemented in a C# library way back in June of 2020 a long time ago and the source code is on my GitHub account. It is called "Visual FoxPro Toolkit for .NET". Of course we probably wouldn't want to use these DLLs or the C# code directly, but the code could be helpful in seeing how the VFP functions were implemented in C#.

The source code and documentation can be found here:
https://github.com/mattslay/Visual-FoxPro-Toolkit-for-.NEThttps://github.com/mattslay/Visual-FoxPro-Toolkit-for-.NET

Implementing missing VFP functions

Posted: Thu Mar 18, 2021 11:14 am
by Chris
Hi Matt,

Thank you, this is helpful indeed! But I am not sure how thoroughly those functions have been designed and tested to be compatible with VFP. I made a quick test, the very first implemented function I tried was GetWordCount() and tested the following:

? GetWordCount("abc" + Chr(13) + "def")

VFP returns 1. Also the X# implementation of the function returns 1. But the GetWordCount() as implemented in the toolkit returns 2.

This was just the very first test I did, I am sure there will be many incompatibilities with other functions as well. So unfortunately we can't just go ahead and use those functions "as is", but can certainly serve as a starting point!

Implementing missing VFP functions

Posted: Thu Mar 18, 2021 11:19 am
by Karl-Heinz
Hi Matt

The toolkit doesn´t help that much. I looked e.g. at the BitOr() function which has a signature for 2 params

Code: Select all

public static int BitOr(int tnExpression1, int tnExpression2)

{	
return tnExpression1 | tnExpression2;
}
X# has the pseudo (compiler) function _or(), where it´s possible to pass more than two values. A similar BitOr() runtime function might look like

Code: Select all

FUNCTION BitOr ( a PARAMS OBJECT[] ) AS INT 
LOCAL nRet AS INT
LOCAL nCount := a:Length AS INT

	IF nCount < 2

		// Throw a exception like 'Arguments missing'	
		
	ELSE 	
	    FOR VAR i := 1 UPTO nCount

    		nRet |= (INT) a[i]

		// same as:
    		// nRet := _OR ( nRet , (INT) a[i] ) 


	    NEXT		
	    
	ENDIF 	    
    
	RETURN nRet 

? BitOr ( 234 , 6 , 8 )	
? BitOr ( 3456 , 5 , 8 , 9 , 10) 

? _or ( 234 , 6 , 8 )	
? _or ( 3456 , 5 , 8 , 9 , 10)	

But, it would IMO make sense to look at the c# functions that open standard dialogs. I don't have VFP to see how such dialogs behave in detail, but it should be no big deal to translate the sources to X# and compare / change the behaviour.

regards
Karl-Heinz

Implementing missing VFP functions

Posted: Thu Mar 18, 2021 3:53 pm
by kevclark64
Chris, at the github link you give there is a document called "functionsToImplement.txt". Is that up to date?

Implementing missing VFP functions

Posted: Thu Mar 18, 2021 6:52 pm
by Chris
Kevin, yes, I checked and it should be up to date, at least almost all. Not sure if the list is complete though or there exist more other functions that we might have missed.

Implementing missing VFP functions

Posted: Sat Mar 20, 2021 5:40 pm
by mainhatten
FoxProMatt wrote:Let me give a reminder that most (non-dbf related) FoxPro functions were implemented in a C# library way back in June of 2020 a long time ago and the source code is on my GitHub account. It is called "Visual FoxPro Toolkit for .NET". Of course we probably wouldn't want to use these DLLs or the C# code directly, but the code could be helpful in seeing how the VFP functions were implemented in C#.
Chris already pointed out that the implementation of vfp Toolkit is not free of errors.
As he used "my" function pair as example, let me add how I approached implementation:
first I spent about an H behind car steering wheel of a drive back from Munich to get a first idea on problems involved and probably needed additional effort (mostly nodding on unicode and possible string/char/array issues at first to the speedometer).

Only then I looked at the code in the toolkit, but just from reading the code it was clear that it was not free of issues ;-)
Still, it verified my basic idea on how to resolve implementation and made me aware of the System:Char:IsWhiteSpace(tc2Check) method, for which I added one of the additional implementation branches. Getting speed of X# near ol' vfp on long test strings involved quite a few tweaks and optimizations, already ballooning code size to a multiple of toolkit size plus solidifying the need to offer a special approach for speed junkies when used in SQL or table usage. Also possible parallel or asynch issues - all of which did not faze vfp, as the option of paralellization, while existing in vfp, is offered only at a much higher level (think COM threads most of the time).

Further benchmarking showed that x# .dbf handling speed back then was not really comparable to vfp speeds, so I did not implement that part back then - might resume if my time permits and x# .dbf handling is in the same ballpark.

So yes, look at that code AFTER thinking on the problems involved, but with distrust, a few basic tests and an eye for runtime optimization.

Implementing missing VFP functions

Posted: Wed Mar 24, 2021 5:37 pm
by Karl-Heinz
Guys,

i´m looking at the BitTest(),BitSet() and BitClear() functions, and try - according to the VFP help - to implement at least the *numeric* behaviour. But i can´t compare the results because my old FP doesn´t know Bitwise operators. Could someone run this code with VFP and report back the results ?

Code: Select all


PRIVATE n
	
? BitSet ( 3400 , 0 , 3 )	&& 3407 
? BitSet ( 3400 , 0 , 2 )	&& 3403 
? BitSet ( 3400 , 0 , 1 )  	&& 3401
? BitSet ( 3400 , 0 )  		&& 3401
? BitSet ( 3400)  		&& 2147483647  - sets the int32.maxvalue bits 
? BitTest ( 3400 , 12 ) 	&& .f.
? BitTest ( 3400 , 13 ) 	&& .f.
n = BitSet ( 3400 , 12 , 2 ) 
? n 				&& 15688 
? BitTest ( n , 12 ) 		&& .t.
? BitTest ( n , 13 ) 		&& .t.
n = BitClear ( n , 12 , 2 )  
? n  				&& 3400 
? BitTest ( n , 12 ) 		&& .f.
? BitTest ( n , 13 ) 		&& .f.
? BitClear ( n )			&& 0 - clears all bits 

If it works as i´m thinking that it should work ;-) i´ll upload the sources as a starting point. So someone who has VFP installed might add the missing varbinary/Blob support.

regards
Karl-Heinz

Implementing missing VFP functions

Posted: Wed Mar 24, 2021 6:21 pm
by Eric Selje
It looks like in VFP the first parameter needs to be explicitly in binary to allow all three parameters like you have, so I tweaked your code a little bit.

Code: Select all

LOCAL bTest AS varbinary, n
bTest = 0h110101001000
? BitSet( bTest, 0 , 3 )	&& 3407 
? BitSet( bTest, 0 , 2 )	&& 3403 
? BitSet( bTest, 0 , 1 )  	&& 3401
? BITSET(bTest, 0 )  		&& 3401
? BitSet( bTest)  		&& 2147483647  - sets the int32.maxvalue bits 
? BITTEST(bTest, 12 ) 	&& .f.
? BitTest (bTest, 13 ) 	&& .f.
n = BitSet (bTest , 12 , 2 ) 
? n 				&& 15688 
? BitTest ( n , 12 ) 		&& .t.
? BitTest ( n , 13 ) 		&& .t.
n = BitClear ( n , 12 , 2 )  
? n  				&& 3400 
? BitTest ( n , 12 ) 		&& .f.
? BitTest ( n , 13 ) 		&& .f.
? BitClear ( n )
Here's the result:

0h170101001000
0h130101001000
0h110101001000
0h110101001000
0hFFFFFFFFFFFF
.F.
.F.
0h113101001000
.T.
.T.
0h110101001000
.F.
.F.
0h000000000000

Here's the syntax in the help file:
BITSET(nNumericExpression1, nNumericExpression2)
BITSET(BinaryExpression [, nStartBit [, nBitCount]])