Подтвердить что ты не робот

Erlang BEAM байт-код

Я надеюсь, что Im не нарушит правила для рассылки спама здесь. Я просто задал вопрос о том, как компилятор erlang реализует сопоставление шаблонов, и я получил несколько отличных ответов, одним из которых является скомпилированный байт-код (полученный с параметром, переданным директиве c()):

{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}}

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

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

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

4b9b3361

Ответ 1

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

Ответ 2

У компилятора есть так называемый компилятор соответствия шаблону, который возьмет шаблон и скомпилирует его до того, что по существу представляет собой ряд ветвей, переключателей и т.д. Код для 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 должен проверить, а затем сбой, если он не соответствует.