FoxPro class syntax

This forum is meant for questions about the Visual FoxPro Language support in X#.

Post Reply
User avatar
robert
Posts: 4558
Joined: Fri Aug 21, 2015 10:57 am
Location: Netherlands

FoxPro class syntax

Post by robert »

Just a quick update to tell you that we are making good progress with the FoxPro class syntax,
The following is a sample program that I used to test some of the syntax. The sample shows:
- Property declaration
- Property initialization
- Add Object clause
- Method declaration
- Access methods
- Custom class and Collection Class to support

Code: Select all

FUNCTION Start() AS VOID
	LOCAL oPerson //ASPerson
        // VFP compatible object creation, Checks for type at runtime
        oPerson := CreateObject("Person", "Fabrice","Foray") 
	oPerson := Person{"Fabrice","Foray"}    
	  
	? "First:", oPerson:FirstName
	? "Last :", oPerson:LastName 
	? "Full :", oPerson:	
        ? "Address:"
	? oPerson:Address:AddressBlock       
         WAIT  
	RETURN

DEFINE CLASS Address AS Custom  
        PUBLIC Street, Zip, City as STRING  // note that we have added the AS Type clause, 
         // Possible (optional) modifiers are PUBLIC, PROTECT, HIDDEN, INTERNAL
	Street = ""
	Zip = ""
	City = ""   
	FUNCTION AddressBlock_Access AS STRING                     // Access method
		RETURN This.Street+CRLF+This.Zip+" "+This.City  
	ENDFUNC

END DEFINE
  
DEFINE CLASS Person AS Custom
       // Untyped. properties
	FirstName, LastName  
	FirstName = "John"
	LastName  = "Doe"  
	ADD OBJECT Address AS Address WITH Street = "Main Street 1", ZIP = "12345", City = "Phoenix"
        // Access method
	FUNCTION FullName_Access  as string                                
		RETURN This.FirstName+" "+This.LastName	
	ENDFUNC 
         
        // Init event handler gets called after object has been created.
	PROCEDURE init(cFirst, cLast)  
		DODEFAULT()
		FirstName := cFirst
		LastName  := cLast  
END DEFINE	
This code uses a Custom class in the X# runtime that contains Name/Value pairs for the properties. The compiler also generates real .Net properties that read/write from the name value collection.
FirstName property gets compiled to:

Code: Select all

public virtual XSharp.__Usual FirstName
{
	get
	{
		return _GetProperty("FirstName");
	}
	set
	{
		_SetProperty("FirstName", value);
	}
}
The addressblock access method (in C#):

Code: Select all

public virtual string AddressBlock => Street + "rn" + Zip + " " + City;
I hope this was interesting to some of you.
We are wrapping up this build for testing this weekend.

Robert
XSharp Development Team
The Netherlands
robert@xsharp.eu
User avatar
lumberjack
Posts: 729
Joined: Fri Sep 25, 2015 3:11 pm
Location: South Africa

FoxPro class syntax

Post by lumberjack »

Hi Robert,
Robert van der Hulst wrote:Just a quick update to tell you that we are making good progress with the FoxPro class syntax,
Great work and looking good. Ok maybe I should rather let the VFP guys do the praise or bashing... :evil:
@Matt, Eric, VFP Lurkers...
______________________
Johan Nel
Boshof, South Africa
atlopes
Posts: 83
Joined: Sat Sep 07, 2019 11:43 am
Location: Portugal

FoxPro class syntax

Post by atlopes »

This looks fantastic and promising, Robert. Kudos are in order.

I'll comment only on a VFP perspective.

In VFP, the _Access methods (which are events, actually) require the declaration of the associated property. In the cases of your example, FullName in Person class, and AddressBlock in the Address class would require a proper declaration.

All user-defined properties, as well as most of the base properties, may have accompanying _Access and _Assign methods, which basically should function as setters and getters destined to override the built-in ones.

For now, two and a half questions (that may already have been addressed elsewhere, probably):

1) Must properties be declared before their initialization? And what's the execution context of the initialization?

2) You skipped the This prefix when referencing FirstName and LastName in the Init method of Person. Was this on purpose? In VFP, this would generate Private variables and left the object's properties untouched.

Again: it's a great and inspiring job. Thank you.
FoxProMatt

FoxPro class syntax

Post by FoxProMatt »

Robert - this looks good and useful when writing new X#.VFP code.

I wanted to show you a common class code sample you'll see in existing VFP code. Not everyone uses AddObject to get an auxiliary object on a class. See this example:

Would this compile in X# with the next release??

Code: Select all

DEFINE CLASS Person AS Custom

	FirstName = "John"
	LastName  = "Doe" 
	oAddress = .null.
         
	PROCEDURE init(cFirst, cLast)
		This.oAddress = CreateObject("Address")
		
		With This.oAddress
			.Street = 'Main Street 1'
			.ZIP = "12345"
			.City = "Phoenix"
		EndWith

		DODEFAULT()
		This.FirstName = cFirst
		This.LastName = cLast 
	EndProc
END DEFINE	
User avatar
lumberjack
Posts: 729
Joined: Fri Sep 25, 2015 3:11 pm
Location: South Africa

FoxPro class syntax

Post by lumberjack »

Hi Antonio,
António Lopes wrote:This looks fantastic and promising, Robert. Kudos are in order.
Thanks for the feedback, great to see the VFP guys getting involved! I will not do a full reply since I feel Robert is the best guy to make such a reply, but will give some comments.
In VFP, the _Access methods (which are events, actually) require the declaration of the associated property. In the cases of your example, FullName in Person class, and AddressBlock in the Address class would require a proper declaration.
It is not required in X#, by design.
2) You skipped the This prefix when referencing FirstName and LastName in the Init method of Person. Was this on purpose? In VFP, this would generate Private variables and left the object's properties untouched.
By default X# will "know" that FirstName and LastName is of the class, hence no need for "this." prefix. If you have a

Code: Select all

LOCAL FirstName, LastName
Then you need a "this." prefix, the LOCAL will take preference without the prefix.
______________________
Johan Nel
Boshof, South Africa
atlopes
Posts: 83
Joined: Sat Sep 07, 2019 11:43 am
Location: Portugal

FoxPro class syntax

Post by atlopes »

Got your points, Johan, thank you very much.

My main concern is that even if, by design, it is not required for an accessible property to have been declared, _Access and _Assign events will be still available for control of regularly declared properties. They will, right?

There is also a particular This_Access method, but I'm sure we'll come to that later.
By default X# will "know" that FirstName and LastName is of the class, hence no need for "this." prefix.
Ok, copy that. But what about cursor fields that might be open in the current work area? Or This is only optional on the left side of assignment statements and required otherwise?

By the way, is X# supporting the m-dot syntax to allow for explicit references to memory objects? I don't seem to have seen it in your and others' examples so far.

[I'll try to set up a machine for testing later on the week, I'm sure these questions could easily be answered with simple tests]
User avatar
lumberjack
Posts: 729
Joined: Fri Sep 25, 2015 3:11 pm
Location: South Africa

FoxPro class syntax

Post by lumberjack »

Hi Antonio,
António Lopes wrote:Got your points, Johan, thank you very much.
My main concern is that even if, by design, it is not required for an accessible property to have been declared, _Access and _Assign events will be still available for control of regularly declared properties. They will, right?
Basically the default for properties in VFP is they are public hence they have by default access/assign, or in X# terms a GET/SET access.
There is also a particular This_Access method, but I'm sure we'll come to that later.
Yes we have something similar in X#:

Code: Select all

PROPERTY SELF[nID AS INT] AS STRING // SELF = THIS
  GET
     RETURN Str(nID, 10, 2)
  END GET
  SET
    ...
  END SET
END PROPERTY
Ok, copy that. But what about cursor fields that might be open in the current work area? Or This is only optional on the left side of assignment statements and required otherwise?
X# uses currently the old FIELD->FieldName or you can have a FIELD x, y, z declaration, which would take preference and then you need this.x to access the object property.
By the way, is X# supporting the m-dot syntax to allow for explicit references to memory objects? I don't seem to have seen it in your and others' examples so far.
It was discussed already, but I think Robert need to answer that.
I'll try to set up a machine for testing later on the week, I'm sure these questions could easily be answered with simple tests]
Yes I agree, and we here to help. Good luck with the testing!
______________________
Johan Nel
Boshof, South Africa
User avatar
robert
Posts: 4558
Joined: Fri Aug 21, 2015 10:57 am
Location: Netherlands

FoxPro class syntax

Post by robert »

Antonio,
1) you don't have to declare properties before initializing. And you can also write initializers for properties that are defined in the parent class. If you do, then your class will get overrides for these properties, but these overrides will write to the same location as the properties in the parent class.
2) The This. prefix is optional in .Net. If you had declared a local variable with the same name as the property then the This. prefix would have been mandatory, because when local variables have precedence over properties with the same name. If you would have used a different name for a variable that does not exist as local and also not as property then the compiler would have generated a private, but only when you have enabled the compiler option "/undeclared"

Robert
XSharp Development Team
The Netherlands
robert@xsharp.eu
User avatar
robert
Posts: 4558
Joined: Fri Aug 21, 2015 10:57 am
Location: Netherlands

FoxPro class syntax

Post by robert »

Matt,
This should work, including DoDefault(), .null. and WITH .. ENDWITH

Robert
XSharp Development Team
The Netherlands
robert@xsharp.eu
User avatar
robert
Posts: 4558
Joined: Fri Aug 21, 2015 10:57 am
Location: Netherlands

FoxPro class syntax

Post by robert »

Antonio,

If you declare fields with the FIELD FirstName, Lastname .... synax then identifiers will be seen as field name. Likewise if you declare memory variables with MEMVAR or initialize then with PUBLIC or PRIVATE then the identifiers will be mapped to dynamic memory variables. Identiers that are not declared as FIELD, MEMVAR or LOCAL are assumed to be instance fields or properties of the class (or STATIC/CLASS level properties).
We have looked at the m-dot syntax. At this moment only M-> works and indicates that the identifier following the ALIAS (->) operator is a dynamic memory variable.

From what I have seen FoxPro uses m-dot both for dynamic variables as well as LOCAL variables. In other words: M-dot means that something is NOT a field. That is somewhat ambiguous. We are looking at this.

In general, we have a potential problem with the use of Dotted names in FoxPro, which is sometimes very ambiguous:

m-dot - can be both a local and a dynamic variable
customer.FieldName can be a field in a workarea/cursor named customer , but also be the FieldName property of a (undeclared?) variable named customer.

Especially the last one is difficult to resolve at compiler time because both the undeclared variable as well as the workarea can be created/opened outside of the scope of the current function / method.

The customer->FieldName syntax does not have that problem, because the ALIAS (->) operator is only used for memvars and fields and never for properties.

We will probably translate the Customer DOT FieldName syntax to code that will resolve this at runtime (or throw a runtime error when there is no cursor or variable with the name "Customer".

Robert
XSharp Development Team
The Netherlands
robert@xsharp.eu
Post Reply