2013-08-13 41 views
5

Tôi đã bị thu hút khi tôi nghe nói rằng GHC có thể xuất ra tệp cho C.Không thể xuất từ ​​.hs sang .hc bằng GHC trong Haskell

Trình biên dịch Haskell Glasgow (GHC) biên dịch thành mã gốc trên một số kiến ​​trúc khác nhau — cũng như ANSI C — sử dụng ngôn ngữ trung gian.

Vì vậy, tôi đã cài đặt Nền tảng Haskell và tạo tệp .hs đơn giản.

main = putStrLn "Hello, World!" 

Và theo hướng dẫn.

C Dừng sau khi tạo ra C (file .hc)

Bây giờ tôi chạy lệnh.

ghc -C test.hs 

Nhưng nó không tạo tệp .hc, cũng không dừng quá trình biên dịch giữa.

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

Bạn đã thử vượt qua -fvia-C ngoài -C chưa? IIRC GHC không sử dụng backend C theo mặc định (nó có thể tạo trực tiếp các assembly cho các máy khác nhau, bao gồm cả llvm). – Cubic

+0

Tôi nhận được cảnh báo rằng "Cờ -fvia-C không làm gì cả, nó sẽ bị xóa trong bản phát hành GHC trong tương lai". Augustss, tại sao tôi sẽ thất vọng? –

+2

Nó trông hoàn toàn không giống như mã C một con người sẽ viết. Đó là về cơ bản không đọc được. Nó cũng không hiệu quả như bạn mong đợi. Cách duy nhất nó được hiệu quả là bằng cách mangling mã lắp ráp được tạo ra bởi trình biên dịch C. – augustss

Trả lời

7

Nếu bạn muốn hiểu các chương trình Haskell hoạt động ở mức thấp, tốt nhất bạn nên học Core thay vì (-ddump-simpl). Sau đó, mã trở nên thực sự khó đọc ngay cả đối với các chuyên gia. Lý do chính là việc quản lý đống và đống của GHC bị mã hóa cứng. Kết quả là, mã Haskell được tạo ở mức độ thấp về cơ bản là một mớ hỗn độn khổng lồ của các thủ tục nhỏ, làm số học con trỏ phức tạp trước khi kết thúc với các bước nhảy gián tiếp đến các vị trí không xác định. Loại spaghetti tồi tệ nhất.

Để cung cấp một cái gì đó của một câu trả lời thực tế - bạn thể tạo C bằng cách so với backend LLVM:

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

Nhưng kết quả sẽ chỉ là minh họa cho điểm. Ngay cả chức năng fib tầm thường cũng sẽ mất khoảng 80 dòng mã.

Trong trường hợp bạn thực sự quan tâm đến chi tiết đẫm máu, tôi khuyên bạn nên đọc qua this blog post bởi Edward Z. Yang. Ông về cơ bản đi qua toàn bộ đường ống biên dịch liên quan đến việc dịch một đoạn mã Haskell đơn giản.

+0

Tuyệt vời, có nó trong C++. Biến đổi thành hiện tượng này: D http://pastebin.com/r4Dy0ZD5 –

+0

Điều này làm tăng tấn lỗi trong Clang và GCC: P –

+0

Lưu ý rằng mã C++ mà bạn dán thực sự là * máy phát * cho mã máy cuối cùng (sử dụng LLVM làm thư viện). Nhưng cố gắng chạy nó là vô ích trong mọi trường hợp, hãy tin tôi ... –