Program als string kompilieren und ausführen



  • Hallo,

    ich würde gerne ein C++ Program aus strings zusammenbauen, dann in meinem Program kompilieren, ausführen und die Ergebnisse weiter verwenden.

    Ich stelle mir das ungefähr so vor:

    #include <iostream>
    #include <string>
    
    int main()
    {
        std::string program =
    		"double compute(double x)\n"
    		"{\n"
    		"    return 2*x;\n"
    		"}\n"
    		"int main()\n"
    		"{\n"
    		"    double result = compute();\n"
    		"}\n";
    
        auto prog = compile(program);
    
        double x = 3;
        double result = prog.run(x);
    
        std::cout << "program(" << x << ") = " << result << "\n";
    }
    

    So wie oben dargestellt geht bzw. kompiliert das natürlich nicht, aber wie könnte man etwas in der Art erreichen?

    Ich will letztendlich die compute Funktion erst zur Laufzeit kompilieren, aber dann wie eine "normale" Funktion aufrufen können, samt Übergabe-Parameter und Rückgabewerte.

    Gibt es da schon etwas fertiges, das man verwenden könnte?


  • Mod

    happystudent schrieb:

    Gibt es da schon etwas fertiges, das man verwenden könnte?

    Ja, nennt sich Compiler.

    Jedoch wäre dir fast mit Sicherheit besser geholfen, würdest du danach fragen, was du erreichen möchtest, anstatt nach der Art und Weise, wie du denkst, dahin zu kommen.



  • Mach das, wenn möglich, nicht. Falls du sowas doch unverzichtbar brauchst, kannst du dir ja mal anschauen, wie das mit cling funktioniert.



  • SeppJ schrieb:

    Ja, nennt sich Compiler.

    Schon klar. Die Frage ist, wie beschrieben, wie man das dynamisch vom Programm aus selbst machen kann.

    SeppJ schrieb:

    Jedoch wäre dir fast mit Sicherheit besser geholfen, würdest du danach fragen, was du erreichen möchtest, anstatt nach der Art und Weise, wie du denkst, dahin zu kommen.

    Ich möchte erreichen, Code dynamisch erzeugen zu können. Also ein Programm in einem String zusammen bauen und dieses dann ausführen und die Berechnungen weiter verarbeiten.

    wob schrieb:

    Mach das, wenn möglich, nicht.

    Was spricht denn dagegen?

    wob schrieb:

    Falls du sowas doch unverzichtbar brauchst, kannst du dir ja mal anschauen, wie das mit cling funktioniert.

    Ok, werde ich mir mal anschauen, Danke.


  • Mod

    happystudent schrieb:

    Ich möchte erreichen, Code dynamisch erzeugen zu können. Also ein Programm in einem String zusammen bauen und dieses dann ausführen und die Berechnungen weiter verarbeiten.

    Aber warum? Und vor allem: Warum C++-Code? Was spricht dagegen, ein Script in einer Scriptsprache zu verfassen?



  • Oder direkt Assembler. Sowas wie AsmJit oder LLVM zu benutzen, wäre doch viel naheliegender, als C++ Code zu kompilieren.



  • SeppJ schrieb:

    Aber warum?

    Wenn man zum Beispiel einen Taschenrechner implementiert, baut der ja auch dynamisch einen Baum, der den zu berechnenden Ausdruck repräsentiert. Den Ausdruck auswerten kann man dann, indem man den Baum durchläuft.

    Wenn ich jetzt den selben Ausdruck aber nicht als Baum aufstellen lasse, sondern direkt hardcode, ist die Auswertung oft um ein vielfaches schneller.

    Das wird insbesondere wichtig, wenn die Funktion etliche male ausgewertet werden soll (nicht nur einmal, wie bei einem klassischen Taschenrechner).

    Daher dachte ich, es wäre eine gute Idee, einen solchen Baum erst zu kompilieren und dann den kompilierten Ausdruck etliche Male auswerten zu lassen.

    Wenn es dazu aber bessere Alternativen gibt, bin ich dafür natürlich offen.

    SeppJ schrieb:

    Und vor allem: Warum C++-Code? Was spricht dagegen, ein Script in einer Scriptsprache zu verfassen?

    Eine Skriptsprache ist halt oft langsamer als kompilierter Code... habe das davor mal mit Matlab probiert und das war deutlich langsamer...

    Mechanics schrieb:

    Oder direkt Assembler. Sowas wie AsmJit oder LLVM zu benutzen, wäre doch viel naheliegender, als C++ Code zu kompilieren.

    Kenn ich beides noch nicht, werde ich mir mal ansehen...


  • Mod

    happystudent schrieb:

    SeppJ schrieb:

    Und vor allem: Warum C++-Code? Was spricht dagegen, ein Script in einer Scriptsprache zu verfassen?

    Eine Skriptsprache ist halt oft langsamer als kompilierter Code... habe das davor mal mit Matlab probiert und das war deutlich langsamer...

    Selbst, wenn du es compilieren möchtest: Mittlerweile hat man dir ja entlocken können, dass es sich nur um sehr begrenzte Minifunktiönchen handelt. Wieso dann eine der am kompliziertesten zu übersetzenden Sprachen überhaupt, gegenüber irgendetwas, dass der Aufgabe angemessen ist?



  • happystudent schrieb:

    Eine Skriptsprache ist halt oft langsamer als kompilierter Code... habe das davor mal mit Matlab probiert und das war deutlich langsamer...

    Es gibt auch Libraries die Script-Code JITen und damit gute bis sehr gute Performance erreichen.

    Und es gibt Umgebungen wie .NET wo du nen vollständigen Compiler im Framework mit drinnen hast. Die von dir gewünschte "compile()" Funktion gibt es quasi in dieser Form für C# im .NET Framework.

    Ansonsten ist es oft auch genug den Syntaxbaum in eine einfach zu interpretierende Form zu bringen.



  • Wenn es nicht unbedingt C++ sein muss: Es gibt noch den TCC.
    Damit kannst du eine DLL erstellen.

    https://de.wikipedia.org/wiki/Tiny_C_Compiler



  • happystudent schrieb:

    Wenn man zum Beispiel einen Taschenrechner implementiert, baut der ja auch dynamisch einen Baum, der den zu berechnenden Ausdruck repräsentiert. Den Ausdruck auswerten kann man dann, indem man den Baum durchläuft.

    Wenn ich jetzt den selben Ausdruck aber nicht als Baum aufstellen lasse, sondern direkt hardcode, ist die Auswertung oft um ein vielfaches schneller.

    Das wird insbesondere wichtig, wenn die Funktion etliche male ausgewertet werden soll (nicht nur einmal, wie bei einem klassischen Taschenrechner).

    Daher dachte ich, es wäre eine gute Idee, einen solchen Baum erst zu kompilieren und dann den kompilierten Ausdruck etliche Male auswerten zu lassen.

    Wenn es dazu aber bessere Alternativen gibt, bin ich dafür natürlich offen.

    warum machst du das nicht mit flex und bison?

    Wenn es deutlich mächtiger sein muss als statische Formel-Auswertung (bedingte Verzweigungen z.B.), kann man den Parser um Laufzeit-Semantik erweitern, sprich Code-Erzeugung für eine CPU oder VM, die Befehle zur Kontrollfluß-Steuerung (bedingte Verzweigungen etc) haben und ausführen können.

    Wenn du Spaß daran findest und den Parser und Code Generator immer weiter ausbaust, hast du irgenwann eine kleine Programmiersprache mit Variablen und Verzweigungen, dann eine große mit Typsystem, Variablen, Verzweigungen ...


Log in to reply