Autor Thema: Eigener C++ Compiler  (Gelesen 10964 mal)

[MM]

  • Beiträge: 130
    • Profil anzeigen
    • www.mmcoding.eu
Gespeichert
« am: 19. February 2006, 21:54 »
Hallo, habe in den letzten Tagen meinen aktuellen C-Compiler zu einem C++ Compiler aufgebohrt. Neben C und Assembler Code kann man nun auch die meisten fortgeschrittenen Techniken der OO nutzen (ich hatte keine Lust mir eine Lib für dynamische Listen in C zu schreiben, da man mit C++ ja auch einfach eine Klasse List machen kann...).

Wäre nett, wenn der Eine oder Andere sich das Teil mal ansehen würde und mir seine Meinung schreibt (oder auch wenn was nicht geht):
http://wwwstud.fh-zwickau.de/~micmo/compiler.html
oder direkt
http://www.fh-zwickau.de/~micmo/files/coding/dc2.zip

MM

Coffee

  • Beiträge: 470
    • Profil anzeigen
Gespeichert
« Antwort #1 am: 20. February 2006, 01:14 »
hab bisher nur angetestet aber: fließkommazahlen sind wichtig, sonst ist der echt.......cooooooooooool......

[MM]

  • Beiträge: 130
    • Profil anzeigen
    • www.mmcoding.eu
Gespeichert
« Antwort #2 am: 20. February 2006, 13:20 »
Ich denke wenn man sich auf LowLevel Programme beschränkt kann man auch sehr gut ohne fließende Kommas leben, außerdem sind die langsam. Daher besser fixed Point, wenn man's braucht...

MM

DarkThing

  • Beiträge: 652
    • Profil anzeigen
Gespeichert
« Antwort #3 am: 23. February 2006, 15:42 »
Habs jetzt auch mal getestet und ich bin wirklich beeindruckt. Vor allem das ganze Klassenkonzept scheint bereits gut zu funktionieren. Allerdings hab ich ein paar Einschränkungen gefunden:
o Keine Referenzen (steht aber auch auf deiner Website), manchmal sind die aber echt brauchbar
o Beim Überladen von Funktionen, gibt es Probleme, wenn sich die Datentypen ändern. Es können nur weitere Parameter dazu kommen. Sowas geht also nicht:

void xyz(int i)
{}
void xyz(char c)
{}

int main()
{
    int i = 0;
    xyz(i);
    return 0;
}

o Der Datentyp long macht bei mir Probleme: "unknown token 'long l=0;'"

Wenn irgendwas davon eigentlich funktionieren sollte aber bei mir nicht, könnte das daran liegen dass ich es nur mit wine getestet hab - auch wenn ich nicht wirklich glaube dass das Probleme macht.
Ansonsten kann ich nur nochmal sagen: Respekt! Das ist schon ein wirklich beachtliches Ergebnis!

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 23. February 2006, 17:34 »
wow, ich find das ding genial. allerdings hab ich ein paar bugs gefunden:

erstmal was mit preincrement/postincrement:
int i = 1;
int x = (i++) + i;

x ist hier gleich 3. es muss aber 2 sein, denn der code ist aequivalent zu folgendem
int i = 1;
int x = i + i;
i++;

und
int i = 1;
int x = (++i) + i;

x ist hier gleich 4. es muss aber 3 sein, denn der code ist aequivalent zu folgendem
int i = 1;
i++;
int x = i + i;


auf diesen bug bin ich gestossen, weil es auch falsch in der dokumentation (2.18) steht.

dass folgendes moeglich ist, ist bestimmt nicht standardkonform ^^
#undef true
#define true 0

und NULL wird eigentlich nicht vom compiler sondern von einem header definiert.

noch was (ist eigentlich ein problem meiner ide): es ist so dass der compiler sich weigert eine .c-datei zu kompilieren, vom dem ein .obj vorliegt, die neuer ist als die .c-datei. das ist zwar normalerweise richtig, aber meine ide aktualisiert irgendwie beim speichern das datum nicht immer. deswegen muss ich die .obj datei loeschen. es waere deswegen nett, dass man diese abfrage mit einem compiler switch umgehen kann.
Dieser Text wird unter jedem Beitrag angezeigt.

Thoth

  • Beiträge: 62
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 23. February 2006, 19:49 »

int i = 1;
i++;
int x = i + i;


Ähm, also solang mich die Kopfrechengeister nicht total verlassen haben, kommt hier auch x = 4 raus, oder?


int i = 1;       //i = 1
i++;             //i = 2
int x = i + i; //x = 4
Madness isn't a bug - it's a feature

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 23. February 2006, 20:00 »
Zitat von: PorkChicken
erstmal was mit preincrement/postincrement:
int i = 1;
int x = (i++) + i;

x ist hier gleich 3. es muss aber 2 sein, denn der code ist aequivalent zu folgendem

Sicher? Soweit ich weiß, ist die Auswertungsreihenfolge bei C nicht fest definiert, sondern compilerabhängig, so daß 3 durchaus ein gültiges Ergebnis sein kann (wenn der Compiler eben von links nach rechts auswertet).

Wenn die Auswertungsreihenfolge tatsächlich nicht definiert ist (und da bin ich mir recht sicher), wäre es übrigens auch einem Compiler erlaubt, je nach Optimierungsstufe oder sonstige undurchsichtige Bedingungen unterschiedliche Ergebnisse zu liefern.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

bluecode

  • Beiträge: 1 391
    • Profil anzeigen
    • lightOS
Gespeichert
« Antwort #7 am: 23. February 2006, 20:03 »
ich würde auch sagen das post/preinkrement in komplexeren Konstrukten in denen die gleiche nicht inkrementierte Variable nochmals vorkommt, nicht definiert ist :!:
lightOS
"Überlegen sie mal 'nen Augenblick, dann lösen sich die ganzen Widersprüche auf. Die Wut wird noch größer, aber die intellektuelle Verwirrung lässt nach.", Georg Schramm

Jidder

  • Administrator
  • Beiträge: 1 625
    • Profil anzeigen
Gespeichert
« Antwort #8 am: 23. February 2006, 21:13 »
ok kann sein, dass ihr recht habt. also ich habe bisher immer gedacht postincrement bedeutet ganz einfach, dass erst inkrementiert wird, wenn der restliche ausdruck fertig ausgewertet ist (alle mir bekannten compiler haben das bisher so gemacht), und dass es nur undefinierte sachen beim preincrement gibt.

Zitat von: Thoth
Ähm, also solang mich die Kopfrechengeister nicht total verlassen haben, kommt hier auch x = 4 raus, oder?


ups, anscheinend habe ich gedacht 1+1 = 1,5 ^^ also doch kein bug  :roll:
Dieser Text wird unter jedem Beitrag angezeigt.

[MM]

  • Beiträge: 130
    • Profil anzeigen
    • www.mmcoding.eu
Gespeichert
« Antwort #9 am: 24. February 2006, 20:46 »
Wow, da ist man mal einen Tag nicht online und dann kommen so viele Antworten.
Also, der Reihe nach:

@DarkThing:
* bei den zwei xyz() Funktionen muss man bedenken, dass die Parameter char und int nicht als unterschiedlich gelten, da sie per standard ineinander überführt werden können, anders würde es aussehen, wenn Zeiger dabei wären.

* Den Datentyp long gib es gar nicht (siehe Punkt 2.3 in der Doku), da int bereits 32Bit hat und ich keinen 64Bit long machen wollte.

@PorkChicken:
* Nun, du hättest Punkt 2.18 genauer lesen sollen (wobei die Sache mit den Pre/Post-Increments von Compiler zu Compiler eh immer etwas anders ist): Das Increment/Decrement passiert vor oder nach dem Zugriff auf die Variable!
Das heißt folgendes:
int i=1,x;
x=
(i++) // auslesen der 1 aus i (danach Increment von i)
+i; // + 2

oder aber:
int i=1,x;
x=
(++i) // (increment von i) auslesen der 2 aus i
+i; // + 2

auch sehr interessant:  :wink:
int i=1,x;
x=++i--; // i=1 x=2

klar soweit?
Entschieden habe ich mich für diese Vorgehensweise, weil es im ersten C-Compiler der Welt genauso war, da existierten nämlich auf der Architekur Befehle vergleichbar mit einem mov, nur dass sie beim Auslesen aus dem Speicher davor/danach ein increment/decrement automatisch durchführen konnten.

* Naja, das die ganzen Konstanten wie NULL und true, false als Defines gesetzt sind sollte eigentlich nicht weiter stören, oder?
Außerdem hat es mich schon immer gestört, dass ich für NULL einen Header brauchte...

* Und es gibt eine Möglichkeit das Überprüfen des Datums zu umgehen, indem man den Parameter -all benutzt.

@Thoth:
Ja, da kommt 4 raus, ansonsten siehe oben...

@taljeth, bluecode, PorkChicken:
Ich hoffe meine ausführliche Erklärung von oben löst dieses Problem mit den Pre/Post-Inc/Decrementen, oder?

MM

Coffee

  • Beiträge: 470
    • Profil anzeigen
Gespeichert
« Antwort #10 am: 24. February 2006, 21:04 »
jep. alles richtig erklärt....

@[MM]: was genau studierst du?
           wie und womit(bücher tutorials, ....) hast du angefangen                                                          
           programmiersprachen zu schreiben?

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #11 am: 24. February 2006, 22:09 »
Zitat von: [MM]
@taljeth, bluecode, PorkChicken:
Ich hoffe meine ausführliche Erklärung von oben löst dieses Problem mit den Pre/Post-Inc/Decrementen, oder?

Ich hatte kein Problem, mir war das schon klar, wie die Operatoren funktionieren. Ich war mir nur nicht hundertprozentig sicher, ob nicht der C-Standard eventuell doch eine bestimmte Auswertungsreihenfolge vorschreibt. Wenn man den Ausdruck von rechts nach links auswerten würde (wie es der gcc in meinem Testprogramm getan hat), käme ja ein anderes Ergebnis raus.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

[MM]

  • Beiträge: 130
    • Profil anzeigen
    • www.mmcoding.eu
Gespeichert
« Antwort #12 am: 24. February 2006, 23:26 »
@taljeth:
Ich war mir anfangs auch nicht sicher, wenn man die Variable auf die man ++/-- anwendet nur einmal in einem Ausdruck verwendet, dann ist es ja klar. Bei allen anderen Kombinationen habe ich zB feststellen müssen, dass sich auch die Ergebnisse vom BCB, TurboC und gcc unterscheiden...
Daher habe ich diese eindeutige Variante gewählt, weil der C Standard an dieser Stelle tatsächlich nichts vorgibt (und mal ehrlich, welchen Sinn hat sowas: (i++)+(++i)+i ).

@Coffee:
Ich studiere grad Systeminformatik, aber habe bereits vor 6 Jahren nach meiner Ausbildung meinen ersten kleinen (und noch sehr simplen) Assembler geschrieben. Naja, und was Assembler betrifft verweise ich gerne auf das PDF von Intel über den Befehlssatz des 386 (musst mal die Boardsuche benutzen, hab den Link grad nicht da). Anhand der Opcodetabellen in dem Dokument, einem guten Degugger und etwas Nachdenken sollte der Stein eigentlich ins rollen kommen...
Aber Tutorials zum Compilerbau hab ich noch nirgends gesehen, dann wärs ja aber auch keine Kunst mehr ...  :wink:

MM

Coffee

  • Beiträge: 470
    • Profil anzeigen
Gespeichert
« Antwort #13 am: 25. February 2006, 11:05 »
doch tutorials zum compilerbau gibs hab ich schon gesehen, visit www.fdos.de musst auch ma rumgucken aber die gibs nur  für basic und für kleinere interpreter wie brainfuck

[MM]

  • Beiträge: 130
    • Profil anzeigen
    • www.mmcoding.eu
Gespeichert
« Antwort #14 am: 26. February 2006, 16:13 »
@Coffee:
Ja, du hast tatsächlich recht, nur besteht das "Tutorial" aus über 80% Quelltext und wer um alles in der Welt schreibt einen Compiler in BASIC (und dann noch einen Basic-Compiler)???
Des weiteren ist es 'nur' ein Crosscompiler, der aus Basic Assembler Quelltext macht.

MM

Coffee

  • Beiträge: 470
    • Profil anzeigen
Gespeichert
« Antwort #15 am: 26. February 2006, 16:16 »
stimmt...... naja hab nur n bissl nach sonem tut gegooglet und das gefunden....
und massig interpreter-codes für brainfuck...

noob

  • Beiträge: 63
    • Profil anzeigen
Gespeichert
« Antwort #16 am: 11. March 2006, 22:33 »
kann dein compiler eventl 16 bit code erzeugen? das waere naemlich super!

[MM]

  • Beiträge: 130
    • Profil anzeigen
    • www.mmcoding.eu
Gespeichert
« Antwort #17 am: 11. March 2006, 23:06 »
Also der erzeugte Code ist IMMER 32 Bit (also ein Integer ist zB immer 32 Bit lang und wird in 32 Bit Registern gespeichert). Aber was du vermutlich meinst ist, ob man den Code auch im Real Mode ausführen kann?

Ja, das geht. Man kann den Code sowohl unter DOS als auch direkt von einer Bootdiskette ausführen, denn auch im Real Mode sind 32Bit Operationen erlaubt (nur keine 32 Bit Speicherzugriffe).
Die Beispielprogramme sind zB für DOS, die in dem zip Teil drin waren (kann man mit dem Switch -mode bestimmen).

Also ich habe mir den Bootloader (im Real Mode) so wie den Kernel (im Protected Mode) mit dem Gerät gebastelt.
Meintest du das so?

MM

noob

  • Beiträge: 63
    • Profil anzeigen
Gespeichert
« Antwort #18 am: 12. March 2006, 16:00 »
hi!

deinen c compiler werd ich hernehmen nur hab ich folgendes prob ich hab diese c datei:

int main(){
    char *text = "Hi I am the Railex Kernel";
    char far *vidMem = (char far*) 0xB800;
   
    while(*text){
*vidMem = *text;
*vidMem++;
*vidMem = 7;
*vidMem++;
*text++;
    }

    return 0;
}


dann gebe ich ein:
dc2.exe kernel.c -mode kernel

dann bekomme ich:
Michael Moenchs Deutsch-C 2.0



*** compile: kernel.c ***

 E kernel.c(9): unknown type '){'

 W kernel.c(11): unknown number 'char far*' read as 0

 E kernel.c(11): unknown char '0' in number-constant

 E kernel.c(13): unknown type 'while(*text){'

 E kernel.c(14): unknown type '*vidMem=*text;'

 E kernel.c(15): unknown type '*vidMem++;'

 E kernel.c(16): unknown type '*vidMem=7;'

 E kernel.c(17): unknown type '*vidMem++;'

 E kernel.c(18): unknown type '*text++;'

 E kernel.c(19): unknown type '}'

 E kernel.c(21): unknown type 'while(1){'

 E kernel.c(21): unknown type '}'

 E kernel.c(21): unknown type ';'

 E kernel.c(23): unknown type 'return 0;'

 E kernel.c(24): unknown type '}'

 W kernel.c(25): global var 'far*vidMem' was never used

 W kernel.c(25): global var 'text' was never used

 done (0.00s)



total: 0.00s

warnings: 3

errors: 14


was mache ich da falsch?
aber es wird eine kernel.obj datei erzeugt!

wo finde ich eine genaue beschreibung zu deinen modes?

danke!!

Coffee

  • Beiträge: 470
    • Profil anzeigen
Gespeichert
« Antwort #19 am: 12. March 2006, 16:25 »
ein paar kleine tips:



int main(){
    char *text = "Hi I am the Railex Kernel";  
    char *vidMem = (char) 0xB800; <- prob. mal ohne far
   
    while(*text) {                                   <- leerzeichen zwischen( und {
   *vidMem = *text;
   *vidMem++;                                      
   vidMem = 7;                                    <- lass den stern weg
   *vidMem++;
   *text++;
    }

    return 0;
}

 

Einloggen