Page 1 of 4
OOP Syntax
Posted: Thu Jun 01, 2006 2:31 am
by Dare
This is a continuation of the OOP discussions, for those who wish to do so.
If people seriously want an OOP implementation of PureBasic, it can probably be done in the first instance as a pre-processor or translator of some sort. That being the case, defining the syntax is probably an important step.
So, what sort of syntax would suit? Our project (if there was one) would translate back to Pure, so it does not need to use Pure interface type syntax. Also the PreProcessor could do more than one pass. Etc Etc. In other words, bias towards Pure but don't be limited by the way it would be done if coding in Pure.
Obviously all PureBasic command/statement syntax remains intact. But for the OOPish stuff?
Eg:
Code: Select all
Class MyThing
property NameA.l
property NameB.l
Method procName.l(par1.l,par2.l)
EndClass
Class myOtherThing
inherit myThing
property NameC.l
EndClass
Function procName(par1.l,par2.l) ; To differentiate from proc
THIS.NameA + par2
procName = THIS.NameB + (par2 / par1)
EndFunction
Procedure helloThere(varA.l) ; Normal proc but uses wotsit
ProcedureReturn varA + wotsit.NameA
EndProcedure
Create myWotsit.myThing
myWotsit.NameB = 99
debug myWotsit.procName(11,12)
Excuse the above, it is just to get things going. Priming the pump, so to speak.
Edit: There is also this post:
http://www.purebasic.fr/english/viewtopic.php?t=22081
Posted: Thu Jun 01, 2006 3:03 am
by fsw
As you can see in the link you posted above I kept the syntax pretty close to pb.
Here again (from the link) what kind of syntax is working now (with my little class parser):
Code: Select all
;oop example by fsw
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;- start main:
Class YourObject
YourValueOfThat.l
YourAnotherValue.s
YourThis(par.l)
YourThat()
EndClass
Class MyObject Extends YourObject
ValueOfThat.l
AnotherValue.s
myThis(par.l)
myThat()
EndClass
NewObject YourThing.YourObject
NewObject myThing.MyObject
NewObject AnotherThing.MyObject
With myThing
\myThis(347)
\myThat()
EndWith
With AnotherThing
\myThis(123)
\myThat()
EndWith
With YourThing
\YourThis(789)
\YourThat()
EndWith
myThing\YourThis(5)
AnotherThing\YourThis(6)
myThing\YourThat()
AnotherThing\YourThat()
YourThing\YourThat()
End
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; for now no constructor or destructor
Procedure YOUROBJECT::yourThis(par.l)
*THIS\YourValueOfThat = par
EndProcedure
Procedure YOUROBJECT::yourThat()
*THIS\YourAnotherValue = " That: "
MessageRequester("YourObject", *THIS\YourAnotherValue + Str(*THIS\YourValueOfThat))
EndProcedure
Procedure MyObject::myThis(par.l)
*THIS\ValueOfThat = par
EndProcedure
Procedure MyObject::myThat()
*THIS\AnotherValue = " That: "
MessageRequester("MyObject", *THIS\AnotherValue + Str(*THIS\ValueOfThat))
EndProcedure
As you can see the only new keywords are:
Class
EndClass
NewObject
All other syntax is normal PB-V4 syntax.
Inheritance is done with:
Extends
The new object is declared with:
NewObject YourObjectName.ClassOfYourObject
The new object is always global, but I'm considering (for compatibily sake) to change the syntax to:
Global NewObject YourObjectName.ClassOfYourObject
The procedure for a class needs the class name in front with a following underscore:
MyClass_ProcName(...
This way procedures in different classes can have the same name.
And you know from the procedurename to which class it belongs to.
The first parameter for a class procedure needs THIS (or SELF or whatever you choose) with the class as the type:
MyClass_ProcName(*this.MyClass, ...
So nothing really new.
Keep it simple
EDIT:
THIS is now a keyword too.
Double colon is used now for Methods.
Code above changed to reflect the changes.
Posted: Thu Jun 01, 2006 9:19 am
by Kale
Something like this?:
Code: Select all
Class MY_CLASS()
Protected Name.s
Protected Address.s
Procedure SetName(Text.s)
Name.s = Text.s
EndProcedure
Procedure GetName.s()
ProcedureReturn Name.s
EndProcedure
Procedure SetAddress(Text.s)
Address.s = Text.s
EndProcedure
Procedure GetAddress.s()
ProcedureReturn Address.s
EndProcedure
Procedure Display.s()
ProcedureReturn GetName() + " : " + GetAddress()
EndProcedure
Procedure Constructor()
Name.s = ""
Address.s = ""
EndProcedure
Procedure ~Deconstructor()
;Whatever
EndProcedure
EndClass
Class MY_SUBCLASS() Extends MY_CLASS
Protected TelephoneNumber.s
Procedure SetTelephoneNumber(Text.s)
TelephoneNumber.s = Text.s
EndProcedure
Procedure GetTelephoneNumber.s()
ProcedureReturn TelephoneNumber.s
EndProcedure
Procedure Display.s()
ProcedureReturn GetName() + " : " + GetAddress() + " : " + GetTelephoneNumber()
EndProcedure
EndClass
NewObject Details.MY_SUBCLASS
Details\SetName("Charlotte the Harlott")
Details\SetAddress("22 Acacia Avenue")
Details\SetTelephoneNumber("666")
Debug Display()
If Purebasic ever moves to support OOP it must be done wholeheartedly. I'm not quite sure how it would be done though.
BUT, you do realise all of this can be done using interfaces???

Posted: Thu Jun 01, 2006 9:20 am
by thefool
BUT, you do realise all of this can be done using interfaces???
Don't you read what we write at all? We KNOW its possible, but its practically unreadable!
Posted: Thu Jun 01, 2006 12:05 pm
by Kale
thefool wrote:We KNOW its possible, but its practically unreadable!
What a load of rubbish. Interfaces are not that complicated. Why don't you try and see! Once the inital creation is out the way using them is childs play, and you'll probab;y never need to tweak the definition again.
Posted: Thu Jun 01, 2006 12:05 pm
by inc.
Do you like a nice pre-parser Plugin?
http://www.purebasic.fr/german/viewtopi ... hlight=oop
(The Plugin download contains examples and an install how-to)
Its still using the EBP approach but Edel is working on switching the resulted code to the via-interface way without EBP usage like shown in here:
http://www.purebasic-lounge.de/viewtopi ... hlight=oop
Theres a version of jaPBe out where you can set individual new commands for highlightning/folding (identation?).
The syntax of Edels Plugin is very comfortable and C++ like when defining Methods and I already used it in some of my workouts/projects.
Posted: Thu Jun 01, 2006 12:09 pm
by thefool
Kale wrote:thefool wrote:We KNOW its possible, but its practically unreadable!
What a load of rubbish. Interfaces are not that complicated. Why don't you try and see! Once the inital creation is out the way using them is childs play, and you'll probab;y never need to tweak the definition again.
Whatever you say; it would be a lot easier with purebasic if it had classes and so on.
Posted: Thu Jun 01, 2006 4:50 pm
by fsw
inc. wrote:Do you like a nice pre-parser Plugin?
http://www.purebasic.fr/german/viewtopi ... hlight=oop
(The Plugin download contains examples and an install how-to)
Its still using the EBP approach but Edel is working on switching the resulted code to the via-interface way without EBP usage like shown in here:
http://www.purebasic-lounge.de/viewtopi ... hlight=oop
Theres a version of jaPBe out where you can set individual new commands for highlightning/folding (identation?).
The syntax of Edels Plugin is very comfortable and C++ like when defining Methods and I already used it in some of my workouts/projects.
ENABLEOOP and DISABLEOOP are not C++ keywords.
The double colon is nice (have to look into it...)
AFAIK it's closed source... sorry, but this disqualifies it for me

Posted: Thu Jun 01, 2006 5:54 pm
by fsw
fsw wrote:
The double colon is nice (have to look into it...)
Done
Now It's possible to code Methods with:
Code: Select all
Procedure YourObject::SetIt(par.l) ;this is a comment
*THIS\YourValueOfThat = par
EndProcedure
Procedure YourObject::That()
*THIS\YourAnotherValue = " That: "
MessageRequester("YourObject", *THIS\YourAnotherValue + Str(*THIS\YourValueOfThat))
EndProcedure
"THIS" is now a keyword too.
Posted: Thu Jun 01, 2006 6:59 pm
by theNerd
This is a very good start!! Using this technique we may be able to have simply OO in PureBasic while retaining all the speed and tightness of code we've grown to expect from it.
Good work!
Posted: Thu Jun 01, 2006 9:53 pm
by inc.
ENABLEOOP and DISABLEOOP are not C++ keywords.
Jupp for shure not but as nomen-est-omen they do really make sense as its a parser these do got their function in ... guess what
AFAIK it's closed source... sorry, but this disqualifies it for me
Best would getting in contact with edel and
Hellhound, sharing ideas concepts how making it easy etc etc etc .... the community will benefit from that

As I do see you and edel are using almost the same syntax. Hellhounds method results in a very tight sized code-output and offers nice common OOP capabilities.
Cause ..... I do assume that in the future some people will do use that OOP way a lot and when sharing source code in the PB communities it could be a mess if many OOP parsers are out using diff. syntaxes ...
The double colon is nice (have to look into it...)
Thats one of the points I meant, thank you
So it would be "theoretically" a perfect thing if the OOP Parser developers like you and edel get in contact and define together a "syntax-OOP-in-PB standard" as he also right now is getting rid of the EBP approach and updating his Plugin refering to Hellhounds approach.
What do you think. Could be more than nice to read interesting sources in threads based on PB OOP where you just have to use "the" PB OOP Plugin for getting it work
just my two cents.
PS: I know its said that PB is basic and never well be officially a native OOP supporting language, but hey .... if some people like it and getting together making new stuff for it then lets at least speak the same language as if not the OOP approach will be even more difficult to newbies when they hear "Oh, these OOP believers made it even more complicated as many parsers are out using diff. syntaxes so just start getting into the jungle".
Posted: Thu Jun 01, 2006 10:50 pm
by fsw
Have you looked at my generated code?
This code:
Code: Select all
;oop example by fsw
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;- start main:
Class MyObject
ValueOfThat.l
AnotherValue.s
myThis(par.l)
myThat()
EndClass
Global NewObject myThing.MyObject ;this is a comment
With myThing
\myThis(347)
\myThat()
EndWith
myThing\myThat()
End
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; for now no constructor or destructor
Procedure MyObject::myThis(par.l)
*THIS\ValueOfThat = par
EndProcedure
Procedure MyObject::myThat()
*THIS\AnotherValue = " That: "
MessageRequester("MyObject", *THIS\AnotherValue + Str(*THIS\ValueOfThat))
EndProcedure
gets translated to:
Code: Select all
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; Special Notes About This Code:
;
; This code uses a NewArray Macro
; Dim does look too weird...
; It also goes well with NewList...
;
; Macro NewArray
; Dim
; EndMacro
;
; Uncomment this macro if you don't
; have it in a res file already...
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;oop example by fsw
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;- start main:
; Start of class
Structure MYOBJECT : VTable.l
ValueOfThat.l
AnotherValue.s
EndStructure
Interface MYOBJECT_Methods
myThis(par.l)
myThat()
EndInterface
Declare MYOBJECT_myThis(*THIS.MYOBJECT, par.l)
Declare MYOBJECT_myThat(*THIS.MYOBJECT)
DataSection : MYOBJECT_VTable:
Data.l @MYOBJECT_myThis()
Data.l @MYOBJECT_myThat()
EndDataSection : Global NewArray MYOBJECT_Self.MYOBJECT(0)
; End of class
; Define Object
ReDim MYOBJECT_Self.MYOBJECT(0) : MYOBJECT_Self(0)\VTable = ?MYOBJECT_VTable : Global MYTHING.MYOBJECT_Methods = MYOBJECT_Self(0) ;THIS IS A COMMENT
With myThing
\myThis(347)
\myThat()
EndWith
myThing\myThat()
End
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; for now no constructor or destructor
Procedure MYOBJECT_MYTHIS(*THIS.MYOBJECT, PAR.L) ;
*THIS\ValueOfThat = par
EndProcedure
Procedure MYOBJECT_MYTHAT(*THIS.MYOBJECT) ;
*THIS\AnotherValue = " That: "
MessageRequester("MyObject", *THIS\AnotherValue + Str(*THIS\ValueOfThat))
EndProcedure
IMHO it's much shorter and readable as what I've seen so far.
The other techniques use prototypes or/and EBP or Danilo's (PBv3) appoach.
Using DataSections (since PBv4) is much easier, shorter and readable IMHO.
Posted: Sat Jun 03, 2006 4:30 pm
by inc.
Ok, Datasections do make it easier, but why that NewArray Way?
What about this?
Code: Select all
Structure cMYOBJECT : VTable.l:
Value.l
AnotherValue.s
EndStructure
Interface iMYOBJECT
GetVal(PAR.l)
ShowVal()
EndInterface
Procedure iMYOBJECT_GetVal(*THIS.cMYOBJECT, PAR.l) ;
*THIS\Value = PAR
EndProcedure
Procedure iMYOBJECT_ShowVal(*THIS.cMYOBJECT) ;
*THIS\AnotherValue = "Value: "
MessageRequester("MyObject", *THIS\AnotherValue + Str(*THIS\Value))
EndProcedure
Procedure.l New_MYOBJECT()
Protected *obj.cMYOBJECT
*obj = AllocateMemory(SizeOf(cMYOBJECT))
*obj\VTable = ?MYOBJECT_VTable
ProcedureReturn *obj
EndProcedure
DataSection : MYOBJECT_VTable:
Data.l @iMYOBJECT_GetVal()
Data.l @iMYOBJECT_ShowVal()
EndDataSection
; Example 1: A single obj
Code: Select all
MYTHING.iMYOBJECT = New_MYOBJECT()
MYTHING\GetVal(347)
MYTHING\ShowVal()
; Example 2: An array of objs
Code: Select all
Dim AnotherThing.iMYOBJECT(5)
For i = 0 To 5
AnotherThing(i) = New_MYOBJECT()
AnotherThing(i)\GetVal(i)
AnotherThing(i)\ShowVal()
Next i
The generation of an array of objs could be easely implemented in your parser so the follwoing would be possible
Code: Select all
NewObject myThing.MyObject(5)
For i = 0 To 5
myThing(i)\GetVal(i)
myThing(i)\ShowVal()
Next i
Posted: Sat Jun 03, 2006 5:06 pm
by blueznl
i know NOTHING about oop (perhaps better keep it that way

) but i might offer some comments
i would try to stay a bit closer to the nature of basic, as if there is one
i understand there are three catagories, objects, classes, and methods... but euh... i do not understand the difference fully

especially the concept of 'classes'
lemme try...
Code: Select all
Class car
;
direction.l
speed.l
;
Method slower()
speed = speed-1
EndMethod
;
Method faster()
speed = speed-1
EndMethod
;
EndClass
i would prefer the use of a new keyword 'method' over the old 'procedure', just for readability
with perhaps the optional keyword 'Object'
this would pretty much look like a sort of extended structuring, not only could you use primitives, but also build in procedures etc.
from a readability point of view, everything would look pretty much like regular pb this way
not sure if this makes sense, i dunno anything about oop

Posted: Sat Jun 03, 2006 5:20 pm
by inc.
Object corvette.car
very above in fsw's way is:
NewObject corvette.car
corvette.car
corvette\faster()
... needs first to be constructed:
corvette.car = New_car() ; Class car
corvette\faster()
or in the parsers syntax ..
NewObject corvette.car
corvette\faster()
i would prefer the use of a new keyword 'method' over the old 'procedure', just for readability
Ok, but infact they are procedures/routines so imho theres no need to do a naming separation
so ...
Procedure ClassName::Methodname(param.l)
*this\Value = param
EndProcedure
.. is been kept in the parser syntax easy imho