XTC OOP-PreCompiler-PlugIn

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
Leonhard
Beiträge: 602
Registriert: 01.03.2006 21:25

Beitrag von Leonhard »

Update:
- Code-Datei wird nicht immer ersetzt (nur bei Parameter 'PlugIn' VOR dem Dateinamen).
- Methoden können nun Public und Private verwendet werden. Attribute werden nur Private verwendet.
Download-Link: DEAD LINK
inc. hat geschrieben:Interessant wären vor allem Klassenhierarchien neben Vererben (nennt man das so?) und so kleine kosmetische Dinge wie wenn man inerhalb einer Methode auf Elemente jener Klasse zugreifen will, so z.B. anstatt "*this\element" die Schreibweise "->element" zulassen. Ist nur was kosometisches, aber machts etwas "netter" und lässt sich leicht in einen Parser einbauen.
Ich hab das jetzt eigebaut, das Klassen verrebt werden können (die Klassenhierarchie). Ich weis nicht direkt, was du danach mit "*this\element" und "->elemnt" meinset. Das funktioniert eigendlich über vererben. Dies kann man teilweise einschränken. Ich hab jetzt erst mal das reingebracht, das Methoden entweder Public (öffendlich) oder Private (nur in anderen Methoden zugäglich) eingebaut habe. Im nächstem Update kann man einem Attribut einen Start-Wert zuordnen. Dazu kommt dann auch erstellung von Klassen in einer Klasse.
inc. hat geschrieben:Es wäre für viele auch interessant die Source deines Parsers zu sehen, wenn dies möglich ist (falls sie nicht dabei liegt). Sodann können manche dir helfen etwas zu verbessern etc.
Ja, ich überarbeite noch den Code. In dieser Version noch nicht dabei. Warscheinlich nächste Version.
Zuletzt geändert von Leonhard am 31.07.2018 12:34, insgesamt 1-mal geändert.
Benutzeravatar
inc.
Beiträge: 348
Registriert: 27.10.2004 12:25

Beitrag von inc. »

Habe lediglich die Zeit mir kurz deine Beispiele anzusehen und kann daher jetzt nur was zur OOP Syntax sagen.

Code: Alles auswählen

Class IMessageBox
	Private
		; Dies sind die Daten der Klasse.
		Attribute
			Title.s
			Text.s
			Flag.l
		EndAttribute
	EndPrivate
	
	Public
		; Eine Methode kann genauso wie eine Procedure genutzt werden.
		; Um etwas zurückzugeben ist der Befehl MethodeReturn zuständig.
		Methode SetTitle(String$)
			*this\Title = String$
		EndMethode
		
		; Diese Procedure ist besonders. Sie wird bei der
		; Klassenerstellung aufgerufen. Sie enthält keine Parameter.
		; Diese Funktion wird bei Vererbung im moment nur von der
		; Haupt-Klasse benutzt. Dies wird aber noch geändert.
		Methode CreateClass()
				Debug "Create IMessageBox"
		EndMethode
		
		Methode SetText(String$)
			*this\Text = String$
		EndMethode
		
		Methode.l FastMessage(Title$,Text$)
			; Hier wird auf eine Methode in dieser Klasse zugegriffen.
			; Dies kann auch verwendet werden, wenn die angegebene
			; Methode noch nicht Declamiert wurde.
			IThis\SetTitle(Title$)
			IThis\SetText (Text$)
			MethodeReturn IThis\Show()
		EndMethode
		
		Methode.l Show()
			MethodeReturn MessageRequester(*this\Title,*this\Text,*this\Flag)
		EndMethode
	EndPublic
EndClass
Schaue dir mal die Syntax an, welche bei Edels OOP Plugin genutzt wird.
Ist übersichtlicher und unkomplizierter:

a) Nach Private bräuchte kein EndPrivate stehen, der Parser erkennt das Ende der Privaten Elemente und Methoden wenn sodann ein "Public" auftaucht oder ein "EndClass" daherkommt.

b) Ich sehe alle Methoden werden innerhalb der Classenerstellung "definiert".
Kann ich diese nicht auch innerhalb der Klasse deklarieren und separat ausserhalb der Klassenerstellung definieren?
Somit hast du eine übersichtliche Klasse mit der deklaration aller Elemente/Attribute und Methoden. Die Definition der Methoden könnten sodann zusätzlich auch (wie man eben will) ausserhalbd er Klasse definiert werden.

c) Warum immer Methode/EndMethode und Attribute/EndAttribute?
Der Parser könnte fix erkennen ob es sich in der Zeile um ein Element oder eine Methode handelt, welche da deklariert wird. (Logik wie bei C++)

Somit wäre so etwas übersichtlicher:

Code: Alles auswählen

Class IMyClass
  Public

    EinElement.l
    AuchEinElement.f
    DiesElement.b
   
    DieseMethode(a.l, b.l, c.l)
    JeneMethode(a.l, b.l, c.l)
    EineMethode(a.l, b.l, c.l)
  
  Private
    DiesesLong.l
    JenesByte.b
    NochEinLong.l

EndClass
Jetzt die Definition der Methoden und anstatt des *this\xxxx ein ->xxxx (das *this\xxx könnte weiterhin akzeptiert werden um kompatibel mit bestehenden OOP Codes zu sein) zudem kann der Parser am "::" erkennen, dass es sich um die Definition einer Methode handelt.

Code: Alles auswählen

Procedure IMyClass::DieseMethode(a.l, b.l, c.l)
  ->DiesesLong = a * b
  If c > 0
    ProcedureReturn ->DiesesLong/c
  Else
   ProcedureReturn #False
EndProcedure
Somit wärst du in der Schreibweise (imho) kompatibel mit dem bereits vorhandenen OOP Plugin un die Leutz welche schon Code hinter sich gelegt ahben müssen nicht alles neu tippen - denn das hemmt.

Jetzt zur Vererbung vs. Hierarchie.

Dies in deinem Beispiel sehe ich als Vererbung:

Code: Alles auswählen

Class IClass Extends IInClass

Und dies meine ich mit Hierarchie, also eine "Klasse" innerhalb einer "Klasse" ohne die von dir genutzte "Struktur":

Code: Alles auswählen

Class IWavePlay
  ....
  StopPlayback()
  ......
  Buffer.IWaveBuffer[4]
  ....
  .....
  .....
EndClass

...
.
....
...
;Hier die Definitionen der Methoden, etc. etc., der Konstruktor etc etc etc

IWavePlay\Buffer[2]\Flush()
IWavePlay\StopPlayback()
Benutzeravatar
Leonhard
Beiträge: 602
Registriert: 01.03.2006 21:25

Beitrag von Leonhard »

inc. hat geschrieben:a) Nach Private bräuchte kein EndPrivate stehen, der Parser erkennt das Ende der Privaten Elemente und Methoden wenn sodann ein "Public" auftaucht oder ein "EndClass" daherkommt.
Stimmt. Werd ich ändern.
inc. hat geschrieben:b) Ich sehe alle Methoden werden innerhalb der Classenerstellung "definiert".
Kann ich diese nicht auch innerhalb der Klasse deklarieren und separat ausserhalb der Klassenerstellung definieren?
Somit hast du eine übersichtliche Klasse mit der deklaration aller Elemente/Attribute und Methoden. Die Definition der Methoden könnten sodann zusätzlich auch (wie man eben will) ausserhalbd er Klasse definiert werden.
Wird im nächsten Update mit
Methode MetodeName() Assign @MethodePointer()
Möglich sein.
inc. hat geschrieben:c) Warum immer Methode/EndMethode und Attribute/EndAttribute?
Der Parser könnte fix erkennen ob es sich in der Zeile um ein Element oder eine Methode handelt, welche da deklariert wird. (Logik wie bei C++)

Somit wäre so etwas übersichtlicher:

Code: Alles auswählen

Class IMyClass
  Public

    EinElement.l
    AuchEinElement.f
    DiesElement.b
   
    DieseMethode(a.l, b.l, c.l)
    JeneMethode(a.l, b.l, c.l)
    EineMethode(a.l, b.l, c.l)
  
  Private
    DiesesLong.l
    JenesByte.b
    NochEinLong.l

EndClass
Dies wird nicht funktionierten, da ich dann konflikte mit den neuen Funktionen bekomme: Attribute erhalten einen Start-Wert und können als Object erstellt werden (mit NewObject).
inc. hat geschrieben:Jetzt die Definition der Methoden und anstatt des *this\xxxx ein ->xxxx (das *this\xxx könnte weiterhin akzeptiert werden um kompatibel mit bestehenden OOP Codes zu sein) zudem kann der Parser am "::" erkennen, dass es sich um die Definition einer Methode handelt.

Code: Alles auswählen

Procedure IMyClass::DieseMethode(a.l, b.l, c.l)
  ->DiesesLong = a * b
  If c > 0
    ProcedureReturn ->DiesesLong/c
  Else
   ProcedureReturn #False
EndProcedure
Somit wärst du in der Schreibweise (imho) kompatibel mit dem bereits vorhandenen OOP Plugin un die Leutz welche schon Code hinter sich gelegt ahben müssen nicht alles neu tippen - denn das hemmt.
Muss ich mir nochmal überlegen. Möglich wird dies sein (funktioniert dann mit 'Assign' (im Englischem 'zuweisen')).
inc. hat geschrieben:Jetzt zur Vererbung vs. Hierarchie.

Dies in deinem Beispiel sehe ich als Vererbung:

Code: Alles auswählen

Class IClass Extends IInClass

Und dies meine ich mit Hierarchie, also eine "Klasse" innerhalb einer "Klasse" ohne die von dir genutzte "Struktur":

Code: Alles auswählen

Class IWavePlay
  ....
  StopPlayback()
  ......
  Buffer.IWaveBuffer[4]
  ....
  .....
  .....
EndClass

...
.
....
...
;Hier die Definitionen der Methoden, etc. etc., der Konstruktor etc etc etc

IWavePlay\Buffer[2]\Flush()
IWavePlay\StopPlayback()
Ist das nächste mal dabei. Attribute werden dann mit 'NewObject' erstellt werden können. Kann aber leider nicht so, wie du das da angegeben hast nicht verwendet werden. Da kann man dan nur in einer Methode auf diese Klassen zugreifen.
Benutzeravatar
inc.
Beiträge: 348
Registriert: 27.10.2004 12:25

Beitrag von inc. »

Wird im nächsten Update mit
Methode MetodeName() Assign @MethodePointer()
Möglich sein.
? Warum "Assign"??
Machs doch so wie in Edels Plugin via "Procedure ClassXXX::GetThis()" so kennt man es von C++ und ist imho simpel.
Dies wird nicht funktionierten, da ich dann konflikte mit den neuen Funktionen bekomme: Attribute erhalten einen Start-Wert und können als Object erstellt werden (mit NewObject).
Dann muss der Parser eben erkennen können, ob es sich um ein Element/Attribut oder eine Methode handelt. Sonst wird die Syntax unübersichtlich. In Edels Plugin geht dies auch (sorry wenn ich mich immer wieder drauf beziehe, aber für mich ist es eben in punkto Syntax eine Referenz, da einfach und überschaubar).
Muss ich mir nochmal überlegen. Möglich wird dies sein (funktioniert dann mit 'Assign' (im Englischem 'zuweisen')).
Warum hier schon wieder "Assign" ???
Wenn "->xxxx = yyyy" genutzt wird, wird es einfach nachher zu "*this/xxxx = yyyy" im Parser übersetzt. Demnach bleibt zudem die Kompatibilität erhalten.


Quintessenz:
Generell würde ich in der Syntax sowenig neue Begriffe wie möglich addieren -> "Keep it simple", denn sonst hat der User soviel zu tippen, dass er direkt die ganze OOP Rangehensweise PB-"Nativ" tippen kann. Also so als ob man kein Plugin braucht. Dann ist zwar kein private/public möglich, aber andererseits können die erfahrenen Nutzer auf ihren nativ-getippten Code vertrauen. (siehe fsw's und Hellhounds Beispiele)
Benutzeravatar
Leonhard
Beiträge: 602
Registriert: 01.03.2006 21:25

Beitrag von Leonhard »

inc. hat geschrieben:? Warum "Assign"??
Machs doch so wie in Edels Plugin via "Procedure ClassXXX::GetThis()" so kennt man es von C++ und ist imho simpel.
Ich glaub, ich mach eine C++ -Version und eine Basic -Version. Eigendlich passt das nähmlich mit PureBasic nicht rein, da Basic eigendlich mit dem "" -Zeiche solche dinge trennt. In C++ geschiet das mittels '::' oder '->'.
inc. hat geschrieben:Dann muss der Parser eben erkennen können, ob es sich um ein Element/Attribut oder eine Methode handelt. Sonst wird die Syntax unübersichtlich. In Edels Plugin geht dies auch (sorry wenn ich mich immer wieder drauf beziehe, aber für mich ist es eben in punkto Syntax eine Referenz, da einfach und überschaubar).
Das dann schon. Aber es treten bei mir dann fehler bei der Compilierung auf.
inc. hat geschrieben:Warum hier schon wieder "Assign" ???
Wenn "->xxxx = yyyy" genutzt wird, wird es einfach nachher zu "*this/xxxx = yyyy" im Parser übersetzt. Demnach bleibt zudem die Kompatibilität erhalten.
Im Programm von mir wird (im moment) ein Interface für solche dinge verwendet. Schau mal, ob ich das ändern kann.
Benutzeravatar
inc.
Beiträge: 348
Registriert: 27.10.2004 12:25

Beitrag von inc. »

Leonhard hat geschrieben:Ich glaub, ich mach eine C++ -Version und eine Basic -Version. Eigendlich passt das nähmlich mit PureBasic nicht rein, da Basic eigendlich mit dem "" -Zeiche solche dinge trennt. In C++ geschiet das mittels '::' oder '->'.
?
Wie auch immer, du musst es selbst wissen.



Btw.: PB's "" vs. C++'s "->" und "::" ..... ??

"xxxx->yyyy" = Zeiger auf das Element yyyy einer Struktur/Klasse
"xxxx.yyyy" = yyyy Element einer Klasse/Struktur

Beispiele:

Code: Alles auswählen

BITMAPINFOHEADER myBmp
xyz = myBmp.width 

VIDEOINFO* pVInfo
xyz = pVInfo->width

IVideoEnvironment *env
res = env->GetFrame(x)
Benutzeravatar
Leonhard
Beiträge: 602
Registriert: 01.03.2006 21:25

Beitrag von Leonhard »

Ich hab mir das mit dem Code von deinem verwendetem Pearser angeschaut. Ist eigendlich nicht schlecht. Ich bekomm es nur nicht hin, Private und Public-Methoden bzw. Attribute zu erstellen. Das fellt dann bei einer C++ -Version weg. Ist das schlimm?
Benutzeravatar
Leonhard
Beiträge: 602
Registriert: 01.03.2006 21:25

UPDATE mit SUUPER verbesserungen

Beitrag von Leonhard »

Hey, UPDATE:

Der PreCompiler kann nun auch Proceduren auserhalb der Klasse erstellen. Leider ist der Syntax noch nicht verbessert worden. Aber für die, die selber gern basteln, hab ich den Code des PreCompilers hier freigegeben.

p.s.
Ich hab mir das mit dem Code von deinem verwendetem Pearser angeschaut. Ist eigendlich nicht schlecht. Ich bekomm es nur nicht hin, Private und Public-Methoden bzw. Attribute zu erstellen. Das fellt dann bei einer C++ -Version weg. Ist das schlimm?
Vergess das ganz schnell. Das ist nun mit dem neuen PlugIn möglich.

Download: DEAD LINK
Zuletzt geändert von Leonhard am 31.07.2018 12:35, insgesamt 1-mal geändert.
Benutzeravatar
ZeHa
Beiträge: 4760
Registriert: 15.09.2004 23:57
Wohnort: Friedrichshafen
Kontaktdaten:

Beitrag von ZeHa »

Ganz schlimm finde ich übrigens daß die neuen Befehle teilweise deutsch sind!
Bild     Bild

ZeHa hat bisher kein Danke erhalten.
Klicke hier, wenn Du wissen möchtest, woran ihm das vorbeigeht.
Benutzeravatar
Leonhard
Beiträge: 602
Registriert: 01.03.2006 21:25

Beitrag von Leonhard »

Ich raff nicht, welchen Befehl du meinst. 'ExternMethode' kann eigendlich nicht teilweise Deutsch sein, da es auch einen Befehl in ASM mit !EXTEN gitb, der auf fast das gleiche hinausläuft. Und die einzigsten Neuen Befehle sind nun mal 'ExternMethode' und 'Assign' (ist Englisch. Auf Deusch: zuweisen).
Antworten