7 Stimmen

Implementierung einer stapelbasierten virtuellen Maschine für eine Teilmenge von C

Hallo zusammen, ich bin gerade dabei, eine einfache Programmiersprache zu implementieren, um Erfahrungen zu sammeln, aber ich brauche einen Rat. Ich bin gerade dabei, meinen Interpreter zu entwerfen und bin auf ein Problem gestoßen.

Meine Sprache ist eine Untermenge von C und ich habe ein Problem mit der Implementierung des Stack-Interpreters. In der Sprache wird die folgende kompilieren:

somefunc ()
{
    1 + 2;
}

main ()
{
    somefunc ();
}

Das ist in Ordnung, aber wenn "1+2" berechnet wird, wird das Ergebnis auf einen Stapel geschoben, und dann kehrt die Funktion zurück, aber es ist immer noch eine Zahl auf dem Stapel, und das sollte nicht sein. Wie kann ich dieses Problem umgehen?

Ich habe darüber nachgedacht, einen "Zustand" des Stacks vor einem Funktionsaufruf zu speichern und diesen "Zustand" nach dem Funktionsaufruf wiederherzustellen. Zum Beispiel die Anzahl der Elemente auf dem Stack zu speichern, dann den Funktionscode auszuführen, zurückzukehren und dann vom Stack zu popen, bis wir die gleiche Anzahl von Elementen wie vorher haben (oder vielleicht +1, wenn die Funktion etwas zurückgegeben hat).

Irgendwelche Ideen? Danke für jeden Tipp!

9voto

John Kugelman Punkte 327535

Tolle Frage! Eines meiner Hobbys ist das Schreiben von Compilern für Spielzeugsprachen, also Hut ab vor Ihrem ausgezeichneten Programmiergeschmack.

Eine Ausdrucksanweisung ist eine, bei der der Code in der Anweisung einfach ein Ausdruck ist. Dies bedeutet, dass alles in der Form <expression> ; was Dinge wie Zuweisungen und Funktionsaufrufe einschließt, aber nicht if s, while s, oder return s. Bei jeder Ausdrucksanweisung bleibt am Ende ein Wert auf dem Stapel übrig, den Sie verwerfen sollten.

1 + 2 ist eine Ausdruckserklärung, aber das sind diese auch:

  • x = 5;
    Der Auftrag Ausdruck lässt den Wert 5 auf dem Stapel liegen, da das Ergebnis einer Zuweisung der Wert des linken Operanden ist. Nach der Anweisung fertig ist, löschen Sie den nicht verwendeten Wert 5.

  • printf("hello world!\n");
    printf() gibt die Anzahl der ausgegebenen Zeichen zurück. Dieser Wert verbleibt auf dem Stack und wird nach Beendigung der Anweisung ausgegeben.

Effektiv hinterlässt jede Ausdrucksanweisung einen Wert auf dem Stack, es sei denn, der Typ des Ausdrucks ist void . In diesem Fall müssen Sie entweder den Spezialfall void Anweisungen und geben danach nichts aus, oder Sie legen einen vorgetäuschten "void"-Wert auf den Stack, damit Sie immer einen Wert ausgeben können.

2voto

Hans Passant Punkte 894572

Sie brauchen einen intelligenteren Parser. Wenn Sie einen Ausdruck sehen, dessen Wert nicht verwendet wird, müssen Sie einen POP ausgeben.

0voto

Nergal Punkte 320

Dies ist eine wichtige Gelegenheit, Optimierung zu lernen. Sie haben eine Funktion, die Zahl, sondern Integer-Mathematik, die int Mathe-Ergebnis ist nicht einmal in irgendeiner Weise verwendet, Form oder Gestalt.

Wenn Ihr Compiler die Funktion wegoptimiert, wird eine Menge Bytecode umsonst erzeugt und ausgeführt!

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X