2009-02-25 5 views
18

ну я надеюсь, что я не нарушу правила для рассылки спама здесь. Я просто задал вопрос о том, как Эрл компилятор реализует поиск по шаблону, и я получил некоторые большие ответы, один из которых является скомпилированный байт-код (полученный с параметром, передаваемым в директиву с()):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}} 

все его простые эрланговые кортежи. Я ожидал какой-то загадочной бинарной вещи, не думаю. поэтому я спрашиваю об этом по импульсу здесь (я мог бы посмотреть на источник компилятора, но задавать вопросы всегда заканчивается лучше с дополнительным пониманием), как этот вывод выводится на двоичном уровне?

скажем {test,is_tuple,{f,3},[{x,0}]} например. Я предполагаю, что это одна инструкция, называемая «тест» ... в любом случае, поэтому этот вывод будет по существу АСТ для языка уровня байткода, из которого двоичное кодирование является всего лишь 1-1 переводом? Это все так увлекательно, я понятия не имел, что я могу это легко увидеть, что компилятор erlang нарушает.

большое спасибо

+0

+1, так как я тоже заинтересован и следовал из вашего предыдущего вопроса через Google :) –

ответ

12

нормально, так что я выкопал в исходный код компилятора, чтобы найти ответ, и, к моему удивлению, ASM-файл, созданный с помощью параметра «S» к компиляции: файл() функция фактически консультировались in as is (file: consult()), и затем кортежи проверяются один за другим для дальнейшего действия (строка 661 - beam_consult_asm (St) -> - compile.erl). далее, тогда там есть сгенерированная таблица сопоставления (папка компиляции источника erlang), которая показывает, что такое порядковый номер каждой метки байт-кода, и я предполагаю, что это используется для генерации фактической бинарной сигнатуры байт-кода. отличный материал. но вы просто должны любить функцию consult(), у вас почти может быть синтаксис типа lispy для случайного языка и полностью исключить необходимость в синтаксическом анализаторе/лексере и просто проконсультироваться с исходным кодом в компиляторе и делать с ним что-нибудь ... code как данные в виде кода ...

+3

Вы посмотрели на Lisp-Flavored Erlang Роберта Вирдинга (http://forum.trapexit.org/viewtopic.php?p= 40268) –

+0

Да, я видел это, он еще не использовал его, хотя его довольно высокий в моем списке вещей, которые нужно сделать в краткосрочной перспективе. спасибо, что – deepblue

5

Компилятор имеет так называемый компилятор , соответствующий шаблону соответствия шаблону, который примет шаблон и скомпилирует его до того, что по существу представляет собой ряд ветвей, переключателей и т. д. Код для Erlang находится в v3_kernel.erl в компиляторе. Он использует Саймон Пейтон Джонс, «Реализация функционального языков программирования», доступную на сайте

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

Другой достойный документ является один на Питер Сестофт,

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

который выводит шаблонный компилятор, проверяя частичную оценку более простой системы. Это может быть легче читать, особенно если вы знаете ML.

Основная идея заключается в том, что если у вас есть, скажем:

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

Предположим теперь у нас есть вызов f(X, Y). Скажите X = a. Тогда применимы только 1 и 2. Итак, мы проверяем Y = b, а затем Y = c. Если, с другой стороны, X /= a, то мы знаем, что мы можем пропустить 1 и 2 и начать тестирование 3 и 4. Ключ в том, что если что-то делает не, это говорит нам о том, где матч может продолжаться, а также когда мы соответствуем. Это набор ограничений, которые мы можем решить путем тестирования.

Компиляторы с комбинацией рисунков стремятся оптимизировать количество тестов, чтобы их было как можно меньше, прежде чем мы закончим. Статически типизированный язык имеют некоторые преимущества здесь, так как они могут знать, что:

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

, а затем, если мы имеем

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

и мы не совпадают f(a), f(b) то F (C) сусло матча. Erlang должен проверить, а затем провалиться, если он не соответствует.