2013-08-13 12 views
5

Ich war fasziniert, als ich hörte, dass GHC eine Datei an C ausgeben kann.Ausgabe von .hs auf .hc mit GHC in Haskell nicht möglich

Der Glasgow Haskell Compiler (GHC) kompiliert zu nativem Code auf einer Reihe von verschiedenen Architekturen - sowie zu ANSI C - mit C-- als Zwischensprache.

Also habe ich die Haskell-Plattform installiert und eine einfache .hs-Datei erstellt.

main = putStrLn "Hello, World!" 

Und entsprechend der Anleitung.

-C Stopp nach Erzeugung von C (.hc Datei)

Jetzt laufe ich den Befehl.

ghc -C test.hs 

Aber es erstellt keine. HC-Datei, noch stoppt es mitten in der Kompilierung.

$ ls 
test.exe test.hi test.hs test.o 
+2

Haben Sie versucht, -fvia-C zusätzlich zu -C zu übergeben? IIRC GHC verwendet standardmäßig nicht das C-Backend (es kann direkt Assemblies für verschiedene Maschinen generieren, einschließlich llvm). – Cubic

+0

Ich habe eine Warnung erhalten, dass "die -fvia-C-Markierung nichts tut; sie wird in einer zukünftigen GHC-Version entfernt". Augusts, warum sollte ich enttäuscht sein? –

+2

Es sieht ganz anders aus als C-Code, den ein Mensch schreiben würde. Es ist im Grunde nicht lesbar. Es ist auch nicht so effizient, wie Sie es sich wünschen. Der einzige Weg, wie es effizient wird, besteht darin, den vom C-Compiler generierten Assembler-Code zu verfälschen. – augustss

Antwort

7

Wenn Sie verstehen wollen, wie Haskell-Programme auf einem niedrigen Niveau auszuführen, ist es wahrscheinlich am besten Kern statt zu studieren (-ddump-simpl). Nach diesem Punkt wird der Code selbst für Experten wirklich schwer zu lesen. Der Hauptgrund dafür ist, dass das Stack- und Heap-Management von GHC fest codiert ist. Als Ergebnis ist niedriger generierter Haskell-Code im Grunde eine riesige Ansammlung von winzigen Prozeduren, die komplexe Zeigerarithmetik ausführen, bevor sie mit indirekten Sprüngen zu unbekannten Orten fertig sind. Die schlechteste Art von Spaghetti Code.

Um etwas von einer tatsächlichen Antwort geben - Sie C, indem Sie über das LLVM Backend erzeugen könnten:

ghc -ddump-llvm -ddump-to-file hello_world.hs 
opt -O2 hello_world.dump-llvm | llc -O2 -march c -o hello_world.c 

Aber das Ergebnis wird nur den Punkt illustrieren. Selbst eine triviale fib Funktion benötigt etwa 80 Zeilen Code.

Falls Sie wirklich an den blutigen Details interessiert sind, würde ich empfehlen, durch this blog post von Edward Z. Yang zu lesen. Er durchläuft im Grunde die gesamte Übersetzungs-Pipeline, die mit der Übersetzung eines einfachen Haskell-Codes zu tun hat.

+0

Awesome, habe es in C++. Verwandelt sich scheinbar dazu: D http://pastebin.com/r4Dy0ZD5 –

+0

Das wirft Tonnen von Fehlern in Clang und GCC: P –

+0

Beachten Sie, dass der C++ Code, den Sie eingefügt haben, eigentlich ein * Generator * für den endgültigen Maschinencode ist (LLVM als Bibliothek verwenden). Aber versuchen, es zu betreiben, ist auf jeden Fall vergeblich, vertrau mir ... –