Zum Inhalt springen

Mehrere Programmiersprachen in C/C++


DITTY

Empfohlene Beiträge

Sers COM,

ich habe ein interessantes Vorhaben und habe dazu ein paar Fragen:

1.) Pseudosprachen mit C/C++ bauen:

Ich würde gerne ein paar Programmiersprachen nachbauen, zumindest grob. Z.B. Pascal.

Solange es um Bezeichner geht, ist das kein Problem, etwa:

#define writeln printf(

#define BEGIN {

#define END };
Aber wie bringe ich C/C++ quasi folgendes bei:
#define := =
Ich suche also nach einer Möglichkeit, auch Sonderzeichen und Zeichenketten als Quellcode neu zu definieren:
#define "DO i = 1, 4711 {...} ENDDO" "for(i=1;i<=4711;++i){{...}}"
Ebenso würde ich gerne den Basisdatentyp int zu einem Klassendatentyp redefinieren, z.B.:
struct|class INT

{

  public:

    int var;

};


#define int INT()

Grund ist der, dass ich auch unter C++ wie in C# bei int ein Klassenobjekt instanzieren möchte, welches ich dann später z.B. um weitere Funktionen ergänzen könnte.

2.) Multicompilierung:

Gibt es auch sowas wie "extern "C"" bei C++ auch für andere Programmiersprachen? Etwa:

extern "g95"

extern "Pascal"

extern "C#"

etc.?

Kann man sowas selber implementieren oder ist das ein Feature, was der Compiler implementiert haben muss?

Ich möchte nämlich gerne programmiersprachenübergreifend mit C/C++ arbeiten, also auch mal Pascal-Code ohne manuelle Portierung und Wrapper INLINE in C/C++-Projekten verwenden.

Ich denke, dass hierfür die GCC sehr gut geeignet ist, da jeder GCC-Compiler letztendlich das selbe Code-Backend verwendet, ähnlich wie bei den .NET-Sprachen und LLVM, also eine Art universelle Zwischensprache.

So kann ich z.B. ganz komfortabel mit dem gcc oder auch g++, Fortran-Dateien mit übersetzen und linken lassen, da sowohl der gcc-, g++-, als auch der gfortran--Compiler binärkompatiblen OBJ-Code erzeugen und anschließend linken.

Hierfür muss ich aber immer im C++-Code Wrapper erstellen und der Fortran-Code lässt sich nur extern einbinden, aber nicht inline. Ich finde das z.B. beim nvcc für CUDA gut gemacht, wo beim Compilieren C/C++-spezifischer Code vom CUDA-spezifischen Code getrennt und je vom CUDA-Compiler und vom GCC übersetzt und am Schluss die OBJ-Dateien vom GCC zusammengelinkt werden. Dies wäre natürlich ideal für mein Vorhaben.

.NET und LLVM kommen für mich im Moment deshalb nicht infrage, weil da noch nicht die Plattformunterstützung soweit ist oder auch lizenzrechtlich noch nicht alles in trocknen Tüchern ist.

Wäre ja super, wenn die GCC die .NET-Zwischensprache CIL und LLVM unterstützen würde, tun sie leider aber nicht.

Da ich nun aber bei C++ primär bleiben möchte, suche ich nach Mittel und Wege, C/C++ irgendwie zu ergänzen.

Ich danke vielmals im Voraus!

MfG

DITTY :)

Link zu diesem Kommentar
Auf anderen Seiten teilen

definier Dir Deine eigene Sprache via Formale Grammatik

erzeuge Dir dann dazu passend Lexer & Parser und dann kannst Du das ganze dann so implementieren wie Du möchtest, sprich Du braust Dir Deinen eigenen Compiler ( Compilerbau )

Ich würde so ähnlich wie beim MOC Compiler von Qt arbeiten, d.h. Du bindest in der Sprache in der Du arbeitest eben entsprechende von Dir definierte Befehle übersetzt. Das Linken wird aber nicht gehen, da nur für C das Name Mangling definiert ist, bei C++ und anderen Sprachen sieht dies entsprechend anders aus, so dass die entsprechenden Sprungnamen nicht ermittelt werden können, wenn diese nicht konsistent sind

Bearbeitet von flashpixx
Link zu diesem Kommentar
Auf anderen Seiten teilen

Ja genau das wollte ich ja eben nicht machen. Ich möchte keine neue oder eine bestehend Programmiersprache (nach)bauen, auch keinen eigenen neuen Compiler.

Ich spiele mit dem Gedanken, einem C/C++-Compiler mit den Möglichkeiten von C/C++ andere Programmiersprachen beizubringen.

Mein erster Gedanke zielt in die Richtung von #defines / Präprozessor-/Compilerdirektiven, typedefs, structs und class´s.

Pascal lässt sich z.B. größtenteils in C/C++ abbilden, nur eben bislang nicht alles bzw. gemäß meiner obigen Fragen weiß ich nicht, wie ich gewisse Dinge realisieren könnte. Es ist von mir explizit gewollt, dass am Ende ruhig wieder C/C++-Code herauskommt der zu einem Exec. übersetzt wird.

Ich würde nur gerne andere Programmiersprachen in C/C++ direkt inline nutzen können, so wie bei CUDA-C, extern "C" in C++ und Inline-Assembler. Ähnliches ist bereits bei den Embarcadero-Produkten möglich, wo sich C/C++, Delphi/Pascal/Objective-Pascal und Assembler wild mischen lassen. Aber dies ist denke ich stark Compiler-implementiert, doch ich bin nicht daran interssiert, einen neuen, eigenen Compiler zu bauen, sondern C/C++ mit seinen gegebenen Mitteln entsprechend zu erweitern.

Ich stelle gerade fest, dass GCC doch mit LLVM, Clang und CIL zusammenarbeiten kann. Ich werde wohl beide Lösungsansätze weiterverfolgen. Deshalb würde ich in diesem Thread meinen ersten Lösungsversuch mittels den gegebenen Mitteln von C/C++ (defines, Präprozessor-/Compilerdirektiven, typedefs, structs, class´s) angehen wollen (und LLVM, CIL seperat).

Deshalb wäre ich sehr dankbar für Hinweise, Tipps, Tricks, vlt. gar schon Lösungen oder Lösungsansätze für meine obigen zwei Hauptfragen, sowie zahlreichen Teilfragen.

MfG

DITTY :-)

Link zu diesem Kommentar
Auf anderen Seiten teilen

Mein erster Gedanke zielt in die Richtung von #defines / Präprozessor-/Compilerdirektiven, typedefs, structs und class´s.

Das wird aber nicht gehen, denn sobald Du komplexere Strukturen hast (z.B. Verschachtelungen) brauchst Du mind. eine kontextfreie Grammatik ( Chomsky-Hierarchie ) um diese prüfen zu können, d.h. eine Pattern Struktur z.B. via regulärer Ausdrücke ist nicht mächtig genug um die Sprache zu verarbeiten

Pascal lässt sich z.B. größtenteils in C/C++ abbilden, nur eben bislang nicht alles bzw. gemäß meiner obigen Fragen weiß ich nicht, wie ich gewisse Dinge realisieren könnte. Es ist von mir explizit gewollt, dass am Ende ruhig wieder C/C++-Code herauskommt der zu einem Exec. übersetzt wird.

Die Idee ist gar nicht so schlecht, ich würde da so etwas wie OpenMP verwenden.


language code eg Pascal, Fortran....


startblock C++ Code

std::cout << "hello" << std::endl;

endblock


language code eg Pascal, Fortran....

Der Block lässt sich mit einem regulären Ausdruck finden und muss dann nur passend eingebunden werden, so dass es richtig compilierbar wird. Kann man natürlich auch genau umgekehrt machen, so dass man z.B. Pascal Code in C++ verwenden kann.

Natürlich muss man sich dann überlegen wie man diese beiden Codestrukturen später verbindet, z.B. über einen automatisch generierten Wrapper (z.B. wie SWIG )

Ich würde nur gerne andere Programmiersprachen in C/C++ direkt inline nutzen können, so wie bei CUDA-C, extern "C" in C++ und Inline-Assembler.

Das "extern C" hat nur indirekt etwas mit der Sprache zu tun, der aufruft bezieht sich auf das Name Mangling, sobald man damit eine Funktion definiert. Denn der Compiler und Linker müssen identische Namen erzeugen, damit die Sprungadressen auch später gefunden werden. Z.B. lässt sich eine in Visual Studio C++ erstellte DLL nicht so ohne weitere mit einem g++ übersetzten Programm verwenden, eben weil die Namen nicht gleich sind.

Der Sprachumfang von C ist Teil von C++, darum kann man in C++ eben C schreiben. Wenn Du so etwas willst, dann musst Du einen eigenen Compiler entwickeln, der eben Deine Sprachen alle passend enthält, denn dafür brauchst Du dann eine passende komplexere Grammatik. Zusätzlich wirst Du aber gerade bei Fortran interessante Effekte dann haben, denn gerade bei 2D Array Strukturen verhalten sich C und Fortran völlig anders (Column- versus Row-Major-Order) bzw. String Darstellung unter Pascal ist so angelegt, dass im ersten Element des String die Länge steht und danach folgen die Chars, bei C/C++ ist es ein null-terminierter String.

Ich würde lediglich externen Code einbetten und diesen dann mit Hilfe eines automatisch erzeugten Wrappers einbinden, was deutlich einfacher ist, als selbst eine Grammatik zu entwickeln. Man kann ja dann den Wrapper auch entsprechend parametrisieren, so dass Typenkonvertierungen direkt möglich sind.

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 2 Monate später...
Die Idee ist gar nicht so schlecht, ich würde da so etwas wie OpenMP verwenden.

language code eg Pascal, Fortran....


startblock C++ Code

std::cout << "hello" << std::endl;

endblock


language code eg Pascal, Fortran....
Der Block lässt sich mit einem regulären Ausdruck finden und muss dann nur passend eingebunden werden, so dass es richtig compilierbar wird. Kann man natürlich auch genau umgekehrt machen, so dass man z.B. Pascal Code in C++ verwenden kann.
Sowas wäre mir auch recht, funktioniert gut mit OpenMP. Bei CUDA-C geht das ganze noch einen Schritt weiter, indem es dort einfach spezielle Schlüsselwörter oder Syntaxänderungen (die sich aber hervorragend in die C/C++-Syntax einpasst) gibt und der nvcc automatisch CUDA-spezifischen Code und C/C++-Code trennt, übersetzt und beide OBJ´s gegeneinander linkt (scheint mir aber eine Compiler-Änderung bzw. externes Tool zu sein, als syntaktisch gelöst). Aber wie lässt sich sowas umsetzen, ohne auf externe Tools zurückzugreifen oder den Compiler zu verändern??? Und gemäß dem Fall, sowas wie eigene Direktiven a´la OpenMP schaffen zu wollen. Wie kann man eigene Direktiven deklarieren / implementieren, sodass jeder Compiler (so die üblichen) damit umgehen können? Ist es im Fall von OpenMP nicht so, dass hierfür dann auch ein OpenMP-kompatibler Compiler benötigt wird? Hier wäre dann ja wieder eine Compileranpassung gefragt. Wäre ja schön, wenn die diversen Programmiersprachen entsprechende Inline-Konstrukte ähnlich OpenMP besitzen würden, hier halt nur zur gezielten Inline-Verwendung von mehreren Sprachen. In etwa solch ein Pragma (z.B. in C/C++:
#pragma language <Name> [optionale Parameter...]

{

}

So könnte man sich das ständige Schreiben von Wrappern sparen.

Ich finde ja .NET und LLVM hier zwei andere interessante Lösungsansätze system- & programmiersprachenunabhängig zu programmieren. Mich interessieren hier aber primär die Möglichkeiten mit C/C++-eigenen Mitteln.

Gilt vlt. auch als Herausforderung für andere, das vermeintlich Unmachbare, machbar zu machen. :D

Das "extern "C"" hat nur indirekt etwas mit der Sprache zu tun, der aufruft bezieht sich auf das Name Mangling, sobald man damit eine Funktion definiert.

Achso, heißt das also, dass das "extern "C"" nicht zum Sprachstandard (gemessen an Feature-Unterstützung der prominentesten Compiler) von C++ gehört?

Und wenn ich ähnliche Konstrukte implementieren möchte, z.B. "extern "f95"", geht das nur über eine Compiler-Anpassung, also nix mit syntaktische Erweiterung im Sinne von Bibliotheken?

Ich würde lediglich externen Code einbetten und diesen dann mit Hilfe eines automatisch erzeugten Wrappers einbinden, was deutlich einfacher ist, als selbst eine Grammatik zu entwickeln. Man kann ja dann den Wrapper auch entsprechend parametrisieren, so dass Typenkonvertierungen direkt möglich sind.

Mein eigentlicher Hauptgrund auf Wrapper-Lösungen zu verzichten, liegt eigentlich nur darin begründet:

a.) herauszufinden, ob es nicht doch noch andere Möglichkeiten gibt (rein aus Interesse und vielmehr eine Machbarkeitsstudie), und

b.) weil Kapselungen im Sinne von Wrapper-Methoden zusätzlichen Overhead erzeugen. Ich bin vielmehr an einer Inline-Lösung interessiert, wo beim Compilieren eine x-beliebige Sprache zunächst in C/C++ übersetzt (daher auch der Gedanke mit dem #define zur Über- bzw. Ersetzung von nicht-konformer C/C++-Syntax in konforme C/C++-Syntax) und dann erst der eigentliche Compile-Vorgang ausgeführt wird. Natürlich ist mir schon bewusst, dass einige Dinge nicht gehen werden, aber die meisten Programmiersprachen sind von der Funktionalität her nunmal kompatibel zueinander bzw. lassen sich kompatibel zueinander einsetzen. Genau hier würde ich gerne ansetzen, eben die "möglichen" Funktionalitäten syntaktisch nach C/C++ zu integrieren / migrieren (ohne Einsatz von externen Tools).

Wie gesagt, das soll erstmal eine Art Machbarkeitsstudie und Ideensammlung sein. Falls wer dazu Lösungen, Lösungsansätze oder weitere Ideen hat, bitte..

MfG

Schlitzauge :)

Bearbeitet von Schlitzauge
Link zu diesem Kommentar
Auf anderen Seiten teilen

Ja, schon, glaube ich zumindest, lasse mich aber auch gerne eines besseren belehren.

Das "extern "C""{} dient meines Wissens nach dazu, dass solcher Code, insb. Funktionsdeklarationen vom C++-Compiler wie von einem C-Compiler behandelt wird (Stichwort: name mangeling bei Funktionsdeklarationen).

Da es zum Standard gehört, ist es wohl also ne Frage des Compilers.

Wollte ich z.B. ein:

extern "f95"

implementieren, ginge das also nur über eine Anpassung des Compilers, korrekt?

Gibt es da sonst noch ne Möglichkeit, sowas mit Sprachmitteln zu realisieren (ich glaube ja eher nicht)?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Das "extern "C""{} dient meines Wissens nach dazu, dass solcher Code, insb. Funktionsdeklarationen vom C++-Compiler wie von einem C-Compiler behandelt wird.
Nein. Dazu müsste der C++-Compiler auch C übersetzen können.

Es bewirkt nur, dass der Code so compiliert wird, dass er aus C benutzbar ist. Was das im einzelnen bedeutet, ist implementierungsspezifisch. Üblicherweise betrifft es den Namen des exportierten Symbols und die Aufrufkonvention. Es ist nach wie vor C++-Code.

extern "Irgendwas" dient nicht dazu, Code in Sprache Irgendwas in C++ einzubetten!

Link zu diesem Kommentar
Auf anderen Seiten teilen

Es bewirkt nur, dass der Code so compiliert wird, dass er aus C benutzbar ist. Was das im einzelnen bedeutet, ist implementierungsspezifisch. Üblicherweise betrifft es den Namen des exportierten Symbols und die Aufrufkonvention. Es ist nach wie vor C++-Code.

Nein, nein, da habe ich mich etwas missverständlich ausgedrückt.

Ich meinte damit genau den Export von Symbolen und die Aufrufkonvention.

Aber: "so compilliert, dass der Code aus C benutzbar ist", wage ich mal zu bezweifeln. Oder ließe sich damit C++-Code (so mit class etc.) dann auch mit einem C-Compiler übersetzen? Ich glaube ja nicht.

Nun jut, dann verwerfe ich gleich mal wieder den Gedanke mit "extern "irgendwas""...

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...