2011-05-03 22 views
9

nhiều (có thể là tất cả?) Ngôn ngữ lập trình bao gồm ngôn ngữ assemblylàm thế nào lisp được thực hiện trong ngôn ngữ lắp ráp?

cách ngôn ngữ lắp ráp được thực hiện?

có bất kỳ tham chiếu, hướng dẫn, hướng dẫn hoặc từ khóa nào tốt cho google không?

bất kỳ quy tắc/quy ước chính thức nào để xây dựng triển khai lisp của riêng bạn?

như đuôi đệ quy nên làm theo một số quy tắc hiện thân hoặc một cái gì đó ..

nhờ

+2

Điều này không có ý nghĩa gì cả – Mehrdad

Trả lời

21

Mặc dù các nhận xét và bài đăng khác là đúng, câu hỏi này quá mơ hồ và có thể hơi bối rối, tôi không thể không chia sẻ một số đề xuất. Tôi đã thu thập một số liên kết và sách về triển khai Lisp vì gần đây tôi đã phát triển một chút đam mê với việc thực hiện ngôn ngữ.Đó là một chủ đề sâu, tất nhiên, nhưng đọc những thứ liên quan đến Lisp là đặc biệt hấp dẫn bởi vì bạn có thể bỏ qua rất nhiều đọc mạnh về phân tích cú pháp nếu bạn thực hiện một trình biên dịch Lisp hoặc thông dịch viên trong Lisp, và chỉ sử dụng read. Điều này cho phép các tác giả tìm đến phần biên dịch hoặc giải thích nhanh chóng. Những khuyến nghị này là những cuốn sách tôi đã đọc hoặc bắt đầu hoặc đang đọc, và chủ yếu là đối phó với Đề án, không phải là Common Lisp, nhưng vẫn có thể có một số sự quan tâm.

Nếu bạn không có nền tảng trong việc thực hiện ngôn ngữ và chưa bao giờ có niềm vui khi đọc về Lisp và Scheme "bộ đánh giá siêu vòng cổ điển", tôi sẽ giới thiệu Structure and Interpretation of Computer Programs. Nếu bạn đã thấy Lisp-in-Lisp (hoặc Scheme-in-Scheme ...), bạn có thể bỏ qua. Trong hai chương cuối của SICP, các tác giả trình bày một vài thông dịch viên khác nhau cho Lisp/Scheme và một vài biến thể, cũng như một trình biên dịch mã byte và một máy ảo. Nó chỉ đơn giản là một cuốn sách tuyệt vời, và miễn phí.

Nếu bạn không có thời gian để đọc SICP, hoặc không muốn đăng nhập thông qua nó chỉ để có được các chương giải thích và biên dịch, tôi sẽ khuyên bạn nên The Little Schemer. Mặc dù nó rất ngắn và dành cho những người mới đến Lisp và Scheme, nếu bạn chưa bao giờ thấy một thông dịch viên Lisp viết bằng Lisp, họ trình bày một cuốn sách, và nó là một cuốn sách thú vị, nhưng có thể không dành cho mọi người do phong cách dễ thương .

Có một cuốn sách miễn phí khác về Đề án tương tự như SICP, được gọi là An Introduction to Scheme and its Implementation, mà tôi chưa đọc nhưng được sử dụng làm tài liệu tham khảo cho một vài bit. Có những phần về thông dịch viên và trình biên dịch trong đó, và nó dường như đi sâu hơn một chút so với SICP, giao dịch với những thứ hai chiều như phân tích quá. Nó có thể cần một trình soạn thảo, nhưng đó là một lời đề nghị ấn tượng.

Với ý tưởng tốt về cách thực hiện Lisp trong Lisp, bạn có thể tiếp cận triển khai Lisp ở mức độ thấp hơn.

Lisp in Small Pieces thường được đề xuất. Tôi đã đọc hầu hết nó, và có thể nói đó chắc chắn là một cuốn sách tuyệt vời, đầy những thứ gritty nitty. Tôi sẽ quay trở lại với một chiếc lược tốt, bởi vì nó dễ dàng để lướt qua khi bạn không hiểu công cụ. Tôi cũng phải vật lộn với việc lấy mã từ trang của tác giả để chạy; nếu bạn nhận được nó, tôi khuyên bạn nên sử dụng Gambit Scheme và chạy mã dựa trên Meroonet với Meroon, từ phân phối this. Lisp in Small Pieces trình bày một số thông dịch viên được viết trong Đề án cũng như trình biên dịch mã byte và trình biên dịch-tới-C.

Lisp in Pieces nhỏ di chuyển nhanh và khá dày đặc. Nếu nó quá nhiều cho bạn, có lẽ bắt đầu với The Essentials of Programming Languages. Tôi đã đọc một số của nó và nó khá tốt, nhưng nó là nhiều thông dịch viên hơn. Rõ ràng là một trong những phiên bản cũ (1st? Tôi không chắc chắn ...) bao gồm một trình biên dịch. Có vẻ như có rất nhiều thay đổi giữa 3 phiên bản, nhưng lần đầu tiên là siêu rẻ trên Amazon, vì vậy hãy kiểm tra nó.

Để biên dịch thành C, đây là loại chủ thể thô với nhiều bit lông. Việc biên dịch thành C sẽ trả về tất cả các vấn đề góc kỳ lạ, như cách tối ưu hóa các cuộc gọi đuôi và xử lý các đóng, tiếp tục lớp đầu tiên và thu gom rác, nhưng nó khá thú vị và rất nhiều triển khai thực hiện của Scheme. Bài trình bày của Marc Feeley về điều này khá thú vị, có tiêu đề The 90 Minute Scheme to C compiler.

Tôi có ít tài nguyên hơn để biên soạn tất cả các cách để lắp ráp, nhưng có một bài báo thường được giới thiệu để biên soạn Đề án thành x86, được gọi là An Incremental Approach to Compiler Construction. Nó giả định rất ít người đọc, tuy nhiên tôi thấy rằng nó chỉ đơn giản là đi quá nhanh và không điền đủ chi tiết. Có lẽ bạn sẽ có may mắn hơn.

Rất nhiều đề xuất ở trên xuất phát từ nhận xét quái vật này trên Hacker News từ hơn một năm trước, từ mahmud. Nó tham khảo một số tài nguyên ML, và biên dịch bằng cách sử dụng tiếp tục.Tôi đã không nhận được điều đó trong nghiên cứu của tôi, vì vậy tôi không thể nói những gì tốt hay không. Nhưng đó là một nhận xét vô cùng quý giá. Các tác phẩm được tham chiếu bao gồm "Biên dịch với các sự tiếp tục" của Andrew Appel và bài "Kỹ thuật thu gom rác không cần xử lý" của Paul Wilson.

Chúc may mắn!

+2

cũng xem Đề án 9 từ Không gian trống: http://www.lulu.com/product/paperback/scheme-9-from-empty-space/13002199 –

+0

Sách PAIP (Mô hình lập trình AI) của Peter Norvig chứa một lược đồ trình biên dịch trong Common Lisp. –

+0

Vâng, tôi đã nghĩ đến việc bao gồm cả PAIP, nhưng tôi chưa đọc hết cả. Trình biên dịch phát ra gì? – spacemanaki

-2

Đó đó là một câu hỏi lớn để trả lời tốt.

Câu trả lời ngắn: JIT.

Câu trả lời lớn: Dragon book.

+3

bạn có chắc rằng các tài nguyên đó có liên quan đến Lisp không? –

+0

Một trình biên dịch lisp (không phải là một thông dịch viên) nó là một trình biên dịch thông thường với sự hỗ trợ jit. Không thể học jit mà không có kiến ​​thức biên dịch thông thường. –

+4

Hầu hết các triển khai Lisp với trình biên dịch không sử dụng trình biên dịch JIT. Không, trình biên dịch Lisp cũng không phải là trình biên dịch 'thông thường' như được mô tả trong cuốn sách Dragon. –

2

Câu hỏi của bạn dựa trên các giả định rất lỗi thời. Những ngày này, hầu như không có ngôn ngữ triển khai được viết bằng ngôn ngữ lắp ráp, và tôi biết không triển khai Lisp được. Bên cạnh việc triển khai tự lưu trữ, C là ngôn ngữ triển khai phổ biến trong những ngày này.

Nếu bạn muốn xem đại diện ngôn ngữ assembly của một hàm lisp, có DISASSEMBLE function.

7

Tôi đã nghĩ về nó một chút trong quá khứ (sau đó sử dụng hạt nhân C thay thế). Tất nhiên không có đơn "lắp ráp", nhưng đối với x86/32bit đây là những gì tôi đang có kế hoạch:

giá trị cơ bản được lưu trữ trong các nút 64-bit với ba bit thấp nhất được sử dụng như thẻ với ý nghĩa như sau:

000 -> cell (64 bits are basically two pointers: car/cdr) 
001 -> fixnum (64-3-1 bits usable for values) 
010 -> vector (32-3 bits for size and 32 bit for pointer to first element) 
011 -> symbol (32 bits pointing to values in global env, 32 pointing to name) 
100 -> native code (32 bits pointing to executable machine code, 32 bits to args) 
101 -> float (using 64-3-1 bit by dropping 4 bits from mantissa) 
110 -> string (using 32-3 bits for size and 32 bits pointing to bytes) 
111 -> struct (32 bits pointing to definition, 32 bits pointing to content) 

3 bit vẫn có thể sử dụng khi xem xét con trỏ nếu tất cả phân bổ được giả định là bội số của 8 byte (hợp lý với kích thước ô là 8 byte). Cần thêm một chút để thực hiện một bộ thu gom rác đơn giản (bit "còn sống"). Trong triển khai C, tôi đã phân bổ bit này ở các phần khác nhau (ví dụ: bit ít quan trọng nhất của 32 bit cao hơn nếu đó là một con trỏ) tùy thuộc vào loại nút.

Ý tưởng của tôi là có bộ nhớ của hai loại: "bộ nhớ nút" (được bố trí ở trên) được phân bổ trong các trang và được sử dụng lại với danh sách miễn phí và "bộ nhớ nhị phân" được sử dụng cho các chuỗi có kích thước biến/mã/mảng.

Mã cụ thể là cần thiết tùy thuộc vào loại nút để triển khai hàm touch đánh dấu đệ quy là các nút còn sống được gọi bằng nút còn sống.

Tất cả điều này tất nhiên chỉ là một cách tiếp cận ngây thơ, nhưng tôi vẫn làm nó trong "C" và tôi chắc rằng tôi có thể làm điều đó trong assembly (mã C của tôi đang sử dụng void * ở khắp mọi nơi. bộ lắp ráp 32 bit di động). Đối với sự lười biếng trong thực hiện C của tôi, tôi chỉ sử dụng 32 bit cho phao và cho số nguyên (sử dụng 32 bit cao hơn) thay vì sử dụng tất cả các bit có sẵn.

6

Hãy xem Clozure Common Lisp để biết ví dụ về ngôn ngữ lắp ráp được sử dụng trong việc triển khai lisp. Clozure CL chủ yếu được triển khai trong Common Lisp, nhưng có một hạt nhân được viết bằng C và một số chức năng cấp thấp trong assembly.

Ví dụ, đây là một vĩ mô từ trình biên dịch/X86/x86-lapmacros.lisp thực hiện một CAR chức năng nguyên thủy trên phần cứng x86, với hướng dẫn một lắp ráp cho tương ứng 32bit và 64bit:

(defx86lapmacro %car (src dest) 
    (target-arch-case 
     (:x8632 
      `(movl (@ x8632::cons.car (% ,src)) (% ,dest))) 
     (:x8664 
      `(movq (@ x8664::cons.car (% ,src)) (% ,dest))))) 

Như được hiển thị, mã assembly được tự mã hóa dưới dạng Lisp. Việc chuyển sang một nền tảng khác liên quan đến (trong số những thứ khác) để dịch các hoạt động cấp thấp này sang một ngôn ngữ lắp ráp khác và biên dịch chéo để tạo ra một thời gian chạy trên nền tảng mới.

ECL (Embeddable Common Lisp) có cách tiếp cận khác bằng cách biên dịch thành C. Điều này giúp việc triển khai cổng đến các nền tảng có trình biên dịch C trở nên thuận tiện.