2009-02-25 30 views
18

Umarım bununla birlikte bazı spam kurallarını ihlal etmem. Sadece erlang derleyici desen eşleştirme nasıl uyguladığını hakkında bir soru sordu, ben (c() yönergesi geçirilen bir parametre ile elde edilir) derlenen baytkod bunlardan biri bazı büyük tepkiler aldık: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}} 

hepsi sadece düz erlang tuples. Bazı şifreli ikili şeyleri bekliyordum, sanırım değil. Bu yüzden bunu dürtü üzerinde soruyorum (derleyici kaynağına bakabilirim fakat soru sormak her zaman ek bir anlayışla daha iyi olur), bu çıktı nasıl ikili düzeyde tercüme edilir?

, örneğin {test,is_tuple,{f,3},[{x,0}]} diyelim. Bunun, 'test' olarak adlandırılan bir komut olduğunu farzedeyim ... bu nedenle, bu çıktı aslında ikili kodlamanın sadece 1-1 çeviri olduğu bayt kodu düzeyindeki dilin AST'si olacak mı? Hepsi bu kadar heyecan verici, ben de erlang derleyicisinin neyi içine soktuğunu kolayca görebileceğim konusunda hiçbir fikrim yoktu.

+0

+1 Ayrıca ilgileniyorum, ve önceki sorudan itibaren Google'dan takip edebilirsiniz :) –

cevap

12

tamam, çok

teşekkürler yüzden cevap bulmak için derleyici kaynak koduna kazılmış ve sürpriz derleme için 'S' parametresi ile üretilen asm dosyası için: Dosya() işlevi aslında danışılması olduğunu olduğu gibi (dosya: consult()) ve daha sonra tuple bir sonraki eylem için tek tek kontrol edilir (satır 661 - beam_consult_asm (St) -> - compile.erl). daha sonra orada her bir bytecode etiketinin seri numarasını gösteren bir erteleme kaynağı oluşturulmuş bir eşleme tablosu var ve bu tahmin bytecode gerçek ikili imza üretmek için kullanılır. harika bir şey. ama sadece consult() işlevini sevmeniz gerekir, neredeyse rastgele bir dil için bir lispy tipi sözdizimine sahip olabilirsiniz ve bir ayrıştırıcı/lexer'a olan gereksinimi tamamen ortadan kaldırır ve sadece derleyici için kaynak koduna başvurup onunla bir şeyler yapın ... kod olarak veri verileri olarak ...

+3

Robert Virding'in Lisp-Flavored Erlang (http://forum.trapexit.org/viewtopic.php?p= 40268) –

+0

Evet, onu görmedim, henüz kullanılmamış olsa da, kısa vadede yapılacak şeyler listemdeki oldukça yüksek olmasına rağmen. teşekkürler – deepblue

5

Derleyici, desen eşleme derleyicisi olarak adlandırılan bir desen derleme ve temelde bir dizi dallar, anahtarlar ve bu gibi bir derleme olacak derler. Erlang için kod derleyici v3_kernel.erl içinde. Bu bir türetir Başka layık kağıt Peter Sestoft tarafından biridir

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

de "Programlama Dilleri Fonksiyonel Uygulanmasına", mevcut çevrimiçi,

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

Simon Peyton Jones kullanır Daha basit bir sistemin kısmi değerlendirmesini inceleyerek desen eşleme derleyicisidir. Özellikle ML'yi biliyorsanız, daha kolay okunabilir.

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

şimdi bir çağrı f(X, Y) olduğunu varsayalım:

temel fikir varsa, demek olmasıdır. X = a deyin. Sonra sadece 1 ve 2 uygulanabilir. Bu yüzden Y = b ve ardından Y = c'u kontrol ediyoruz. Öte yandan, X /= a ise, 1 ve 2'yi 0 ve 3 ve 4'ü test etmeye başlayabileceğimizi biliyoruz. Anahtar, eşleşmesini yapmazsa, eşleşmenin ne zaman olabileceğine dair bir şey söyleyeceğidir. eşleşiyoruz Test ederek çözebileceğimiz bir dizi kısıtlamadır.

Desen eşlemeli derleyiciler, test sayısını en uygun hale getirmeye çalışırlar, böylece sonuç vermeden önce mümkün olduğunca az sayıda var. onlar biliyor olabileceğinden statik dil bazı avantajları burada var yazmış:

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

ve sonra biz

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

varsa ve biz (c) zorunluluk maçın f sonra f(a), f(b) eşleşmedi. Erlang eşleşmezse kontrol etmeli ve başarısız olmalı.