2009-05-27 60 views
32

Có trình biên dịch mã nguồn gốc cho Lisp không? Ở mức độ nào nó có thể được biên dịch, với tất cả tính năng động, thu gom rác thải, các macro và những thứ khác?Có trình biên dịch mã nguồn gốc của Lisp không?

+2

Và để suy nghĩ cho đến bây giờ tôi nghĩ rằng LISP đã được giải thích. –

+1

Bạn đang nói về Common Lisp, độc quyền? –

+2

@Amit, có và không. Tôi muốn tìm một cách để tạo ra các tệp Windows * .exe để viết một số tiện ích ném một mục đích, như các trình chuyển đổi tệp, sau đó tôi có thể cung cấp cho người khác ở nơi làm việc để sử dụng mà không cần cầu xin họ để cài đặt Lisp trên máy của họ (đặc biệt là kể từ khi họ vẫn còn giận tôi sau khi tôi đã làm cho họ cài đặt Python). Vì mục đích đó tôi thích Common Lisp vì nó có vẻ "thực tế" hơn. Mặt khác, tôi cũng muốn biết về các trình biên dịch (hoặc bất cứ thứ gì), để xem bức tranh lớn. – Headcrab

Trả lời

53

Nhiều trình biên dịch Lisp biên dịch thành mã 'gốc'. 'Gốc' có nghĩa là 'mã máy' ở đây (x86 ở chế độ 32 bit hoặc 64 bit, PowerPC, SPARC, ...).

câu hỏi khác:

  • có thể biên dịch 'mã không có nguồn gốc' tạo thực thi tập tin duy nhất? -> Có.

  • trình biên dịch 'mã nguồn gốc' có thể tạo ra tệp thực thi duy nhất không? -> Có.

  • cách 'gốc' là 'gốc'? -> Hệ thống Lisp sẽ hầu hết thời gian có bố trí cấu trúc dữ liệu nội bộ riêng (các lớp CLOS), xử lý lỗi riêng ('điều kiện'), quản lý bộ nhớ riêng của họ (thu gom rác), thư viện riêng của họ, ...

  • Lisp có thể chạy mà không có GC không? -> Thường thì không. Có những ngoại lệ.

  • Còn kích thước ứng dụng thì sao? - Theo mặc định, các cách đơn giản để tạo một ứng dụng Lisp thường dẫn đến các tệp thực thi lớn.Các tập tin thực thi bao gồm toàn bộ Lisp bao gồm thư viện của nó, tên của tất cả các ký hiệu, thông tin về các danh sách đối số cho các hàm, trình biên dịch, trình gỡ lỗi, thông tin vị trí mã nguồn và nhiều hơn nữa. Một số trình biên dịch tạo ra cũng mã số lớn (SBCL là một ví dụ).

  • có cách nào để thu nhỏ kích thước ứng dụng không? -> Điều đó phụ thuộc vào hệ thống Lisp. Các hệ thống Lisp thương mại như LispWorks và Allegro CL có thể. Để phân phối ứng dụng, họ có thể xóa mã không sử dụng, xóa thông tin gỡ lỗi, xóa các phần của Lisp (thư viện, trình biên dịch, ...) và hơn thế nữa.

  • các hệ thống Lisp thường có thể tạo các tệp thi hành nhỏ. Tôi có nghĩa là thực sự nhỏ. -> Không hẳn. Các tệp thực thi là lớn (CCL) hoặc rất lớn (SBCL). Một số hệ thống Lisp thường có thể tạo ra các tệp thực thi có kích thước trung bình. Nhưng không ai thực sự có thể tạo ra các tập tin thực thi nhỏ.

  • thực sự không có cách nào để tạo ra các tệp thực thi nhỏ? -> Nhiều năm trước, các trình biên dịch được viết để tạo ra mã C tương đối nhỏ gọn mà không có các thư viện lớn. Nhưng những trình biên dịch này không được duy trì.

  • có cách nào khác để thu nhỏ tệp thi hành không? -> Nếu bạn muốn chạy nhiều hơn một ứng dụng Lisp, bạn nên sử dụng lại thời gian chạy, trình biên dịch, thư viện trong một hoặc nhiều thư viện được chia sẻ. Bằng cách đó, mã để phân phối sẽ nhỏ hơn, khi một thời gian chạy đã được cài đặt như một thư viện được chia sẻ (hoặc tương tự).

  • làm cách nào để tìm hiểu những gì Lisp tôi đang sử dụng hỗ trợ dưới dạng phân phối ứng dụng? -> đọc hướng dẫn và hỏi người dùng khác.

  • được, vì vậy hầu hết các hệ thống Lisp thường không thể tạo ra các ứng dụng nhỏ. Có những phương ngữ Lisp khác có thể tạo ra các tệp thực thi nhỏ hơn không. -> Có, một số trình biên dịch Scheme có thể.

  • lỗi Common Lisp xử lý thời gian chạy như thế nào? -> phụ thuộc vào cách bạn tạo ứng dụng. Theo mặc định, bạn nhận được một trình gỡ rối Lisp (trừ khi bạn đã gỡ bỏ nó). Nhưng bạn có thể sử dụng các lỗi xử lý lỗi của chính mình trong ứng dụng của mình và có thể ngăn không cho trình gỡ rối xuất hiện.

  • Điểm mạnh đặc biệt của Common Lisp là gì khi tạo các tệp thực thi nhỏ không phải là một? -> bạn có thể bao gồm một REPL để tương tác với ứng dụng, bạn có thể sử dụng một trình biên dịch kèm theo để biên dịch mã mới (hoặc thay đổi) khi chạy, bạn có thể sử dụng bộ nạp mã FASL (biên dịch mã Lisp) để LOAD thêm mã gốc vào thời gian chạy (nghĩ plugin, bản vá, tiện ích mở rộng, ...), xử lý lỗi phức tạp bao gồm khôi phục lỗi là có thể, ...

  • nhưng Lisp là động? -> Có, năng động có nghĩa là nó có thể thay đổi rất nhiều thứ trong thời gian chạy. Ví dụ trong Common Lisp bạn có thể thay đổi một lớp CLOS trong thời gian chạy và các cá thể của lớp sẽ áp dụng cho các thay đổi. Nhưng các hệ thống Lisp khác nhau có những cách khác nhau để loại bỏ một số tính năng động. Các cấu trúc kém năng động hơn các lớp CLOS. Bạn có thể khai báo các loại và biên dịch với các cài đặt tối ưu hóa khác nhau (tốc độ, an toàn, gỡ lỗi, ...). Bạn có thể nội tuyến chức năng. Và hơn thế nữa.

Cách đơn giản để xem mã được biên dịch cho các hàm là sử dụng hàm Lisp chung DISASSEMBLE. Ví dụ trong Clozure CL trên một x86-64 Mac

? (defun foo (x y) (if (= x y) (sin x) (* y (cos x)))) 
FOO 
? (disassemble 'foo) 
L0 
    [0]  (leaq (@ (:^ L0) (% rip)) (% fn)) 
    [7]  (cmpl ($ 16) (% nargs)) 
    [10] (jne L209) 
    [16] (pushq (% rbp)) 
    [17] (movq (% rsp) (% rbp)) 

...

[172] (pushq (@ 77752)) 
    [179] (jmpq (@ 10 (% temp0))) 
L189 
    [189] (leaq (@ (:^ L0) (% rip)) (% fn)) 
    [196] (jmpq (@ .SPNVALRET)) 
L209 
    [209] (uuo-error-wrong-number-of-args) 
NIL 

Kết quả của tháo rời rõ ràng phụ thuộc vào kiến ​​trúc vi xử lý, hệ điều hành, trình biên dịch Lisp sử dụng và các thiết lập tối ưu hóa hiện nay .

+0

Và nếu một cái gì đó được thay đổi trong thời gian chạy, những gì sẽ xảy ra? Lisp có tạo ra phiên bản mới của mã máy hay thay đổi chỉ ảnh hưởng đến "bố cục cấu trúc dữ liệu nội bộ" của nó không? – Headcrab

+0

Tùy thuộc vào các thay đổi. Một số có thể không yêu cầu trình biên dịch, một số có thể sử dụng trình biên dịch nội bộ, một số sẽ chỉ sử dụng mã mới tải (để thay thế hoặc mở rộng mã hiện có), một số có thể không cần trình biên dịch. Tất cả các biến thể đều có thể. –

4

Bạn đặt cược. Chez Scheme (một trình biên dịch thương mại) là một trong những cái tốt hơn. Gambit và Larceny là các trình biên dịch nghiên cứu cũng tạo ra mã gốc.

+0

http://www.iro.umontreal.ca/~gambit/ Gambit Trang chủ http://www.ccs.neu.edu/home/will/Larceny/ Larceny Trang chủ Gambit biên dịch thành C, Larceny biên dịch hoặc C, mã máy hoặc CLR. –

3

Có. Xem http://en.wikipedia.org/wiki/Common_Lisp. Nó đề cập rằng Steel Bank Common Lisp (một thực hiện khá phổ biến) biên dịch tất cả mọi thứ để bản địa theo mặc định. Thực tế là các bộ sưu tập rác và được sử dụng không phải là một trở ngại đối với mã nguồn gốc. Điều đó chỉ có nghĩa là một loại thời gian chạy là cần thiết. Nhưng cái gì cơ? Thậm chí C có thời gian chạy.

9

Có nhiều trình biên dịch Lisp biên dịch thành mã gốc. CMUCL, SBCL, ClozureCL được biết đến trong số các trình biên dịch Lisp nguồn mở.

Thu gom rác không phải là một trở ngại để biên dịch thành mã gốc. Ngoài ra, trong một số trường hợp, Lisp có thể sử dụng phân bổ stack không cần GC và có thể cải thiện đáng kể hiệu suất (sử dụng khai báo mức động, ít nhất SBCL hỗ trợ điều này).

Macro (và bất kỳ mã nào chạy ở chế độ đọc (đọc macro và đọc-eval), thời gian biên dịch (macro, macro trình biên dịch, mã trong eval-when)) yêu cầu biên dịch gia tăng (hàm macro đầu tiên có được biên dịch, và sau đó mã sử dụng macro có thể được biên dịch). Điều này hơi phức tạp biên soạn, nhưng nó không phải là quá nhiều một vấn đề. Ngoài ra, macro và macro trình biên dịch thậm chí còn giúp quá trình biên dịch vì chúng cho phép lập trình viên viết các trình tạo mã và trình tối ưu hóa mã, về cơ bản tùy biến trình biên dịch.

Vì vậy, trình biên dịch phức tạp hơn một số ngôn ngữ đơn giản hơn (như C), nhưng độ phức tạp có thể quản lý được (xem Design of CMU Common Lisp).

Bản chất động của Common Lisp có thể điều khiển và được thiết kế để có khả năng tương thích hiệu quả. Ngược lại với một số ngôn ngữ động khác (ví dụ: Python), tính năng động bị hạn chế (ví dụ: bạn không thể lấy môi trường từ vựng hiện tại vào thời gian chạy), cho phép các trình biên dịch tự do tối ưu hóa.

+0

Tôi đã thử một số trình biên dịch một số thời gian trước đây. Những gì tôi có thể làm với họ là một cái gì đó giống như ~ 10 MB cho một "Xin chào, Thế giới!" Tệp Windows .exe, hiển thị cho bạn lời nhắc Lisp nếu có lỗi thời gian chạy. Vì vậy, có vẻ như toàn bộ hệ thống Lisp đã được kéo cùng với nó, mà làm cho bạn nghĩ rằng nó không thực sự quá "bản địa", có thể ... – Headcrab

+10

Hmm, java kéo toàn bộ thời gian chạy java, .net kéo toàn bộ clr, C++ kéo toàn bộ C++ rt, lisp kéo toàn bộ thời gian chạy lisp. Nó chỉ là điều tương tự - hầu như mọi ngôn ngữ đều yêu cầu thời gian chạy của riêng nó. Thời gian chạy của Lisp là lớn vì tính linh hoạt của nó (điều này cũng đúng với jvm và clr). Tuy nhiên, mã vẫn là nguồn gốc: tức là, các hướng dẫn không dành cho VM, nhưng đối với CPU mục tiêu. –

+0

Tôi nghĩ rằng một số lisps cung cấp một cách để bán phá giá hình ảnh với một số tính năng bị loại bỏ (như trình biên dịch, nếu nó không được sử dụng). có lẽ điều đó có thể giúp co lại nó một chút? –

4

Đừng quên Chicken Đề án.

+0

Tại sao các Downvotes? OP cũng muốn biết về chương trình, và gà là một trình biên dịch tự nhiên. –

Các vấn đề liên quan