2009-02-25 14 views
18

well Tôi hy vọng Im không vi phạm một số quy tắc gửi thư rác ở đây với điều này. Tôi chỉ hỏi một câu hỏi về cách thức biên dịch erlang thực hiện phù hợp với mô hình, và tôi đã nhận một số phản ứng tuyệt vời, một trong số đó là bytecode biên dịch (thu được với một tham số truyền cho các chỉ thị c()):erlang BEAM bytecode

{function, match, 1, 2}. 
    {label,1}. 
    {func_info,{atom,match},{atom,match},1}. 
    {label,2}. 
    {test,is_tuple,{f,3},[{x,0}]}. 
    {test,test_arity,{f,3},[{x,0},2]}. 
    {get_tuple_element,{x,0},0,{x,1}}. 
    {test,is_eq_exact,{f,3},[{x,1},{atom,a}]}. 
    return. 
    {label,3}. 
    {badmatch,{x,0}} 

tất cả mọi thứ đều đơn giản. Tôi đã mong đợi một số thingy nhị phân khó hiểu, đoán không. Vì vậy, Im hỏi điều này trên xung ở đây (tôi có thể nhìn vào nguồn trình biên dịch nhưng đặt câu hỏi luôn luôn kết thúc tốt hơn với cái nhìn sâu sắc hơn), làm thế nào là đầu ra này dịch ở mức độ nhị phân? Ví dụ:

nói {test,is_tuple,{f,3},[{x,0}]}. Im giả sử đây là một lệnh, được gọi là 'test' ... anyway, vì vậy đầu ra này về cơ bản sẽ là AST của ngôn ngữ cấp bytecode, từ đó mã hóa nhị phân chỉ là một bản dịch 1-1? Điều này thật thú vị, tôi không có ý tưởng rằng tôi có thể dễ dàng thấy những gì trình biên dịch erlang phá vỡ mọi thứ.

cảm ơn rất nhiều

+0

+1 vì tôi cũng quan tâm và theo dõi câu hỏi trước của bạn qua Google :) –

Trả lời

12

ok vì vậy tôi đào vào mã nguồn trình biên dịch để tìm câu trả lời, và tôi ngạc nhiên file asm sản xuất với tham số 'S' để biên dịch: tập tin() chức năng là thực sự tham khảo ý kiến như là (file: consult()) và sau đó các tuple được kiểm tra từng cái một để có thêm hành động (dòng 661 - beam_consult_asm (St) -> - compile.erl). thêm vào đó có một bảng lập bản đồ được tạo ra trong đó (thư mục biên dịch của nguồn erlang) cho biết số sê-ri của mỗi nhãn bytecode là gì, và tôi đoán nó được sử dụng để tạo ra chữ ký nhị phân thực tế của bytecode. những thứ tuyệt vời. nhưng bạn chỉ cần yêu cầu hàm consult(), bạn có thể có một cú pháp kiểu lispy cho một ngôn ngữ ngẫu nhiên và tránh sự cần thiết của một trình phân tích cú pháp/lexer đầy đủ và chỉ tham khảo mã nguồn vào trình biên dịch và làm việc với nó ... như dữ liệu dữ liệu dưới dạng mã ...

+3

Bạn đã xem Erlang Lisp-Flavored của Robert Virding chưa (http://forum.trapexit.org/viewtopic.php?p= 40268) –

+0

vâng tôi đã nhìn thấy nó, havent sử dụng nó được nêu ra mặc dù nó khá cao trong danh sách của tôi về những điều cần làm trong ngắn hạn. cảm ơn – deepblue

5

Trình biên dịch có một trình biên dịch khớp mẫu sẽ lấy mẫu và biên dịch xuống về cơ bản là một loạt các nhánh, công tắc và như vậy. Mã cho Erlang là trong v3_kernel.erl trong trình biên dịch. Nó sử dụng Simon Peyton Jones, "Việc thực hiện chức năng Ngôn ngữ lập trình", có sẵn trực tuyến tại

http://research.microsoft.com/en-us/um/people/simonpj/papers/slpj-book-1987/

Một giấy xứng đáng là một trong những Peter Sestoft,

http://www.itu.dk/~sestoft/papers/match.ps.gz

mà xuất phát một trình biên dịch khớp mẫu bằng cách kiểm tra đánh giá từng phần của một hệ thống đơn giản hơn. Nó có thể dễ đọc hơn, đặc biệt là nếu bạn biết ML.

Ý tưởng cơ bản là nếu bạn có, nói:

% 1 
f(a, b) -> 
% 2 
f(a, c) -> 
% 3 
f(b, b) -> 
% 4 
f(b, c) -> 

Giả sử bây giờ chúng tôi có một cuộc gọi f(X, Y). Nói X = a. Sau đó chỉ 1 và 2 được áp dụng. Vì vậy, chúng tôi kiểm tra Y = b và sau đó Y = c. Nếu mặt khác, X /= a thì chúng ta biết rằng chúng ta có thể bỏ qua 1 và 2 và bắt đầu thử nghiệm 3 và 4. Điều quan trọng là nếu có điều gì đó không phù hợp. chúng tôi làm phù hợp. Đó là một tập hợp các ràng buộc mà chúng ta có thể giải quyết bằng cách thử nghiệm.

Trình biên dịch khớp mẫu tìm cách tối ưu hóa số lượng kiểm tra để có ít nhất có thể trước khi chúng tôi có kết luận. Tĩnh gõ ngôn ngữ có một số lợi thế ở đây kể từ khi họ có thể biết rằng:

-type foo() :: a | b | c. 

và sau đó nếu chúng ta có

-spec f(foo() -> any(). 
f(a) -> 
f(b) -> 
f(c) -> 

và chúng tôi không tìm thấy f(a), f(b) sau đó f (c) phải trận đấu. Erlang phải kiểm tra và sau đó thất bại nếu nó không khớp.