Erlang编译器如何实现模式匹配?

3lxsmp7m  于 2022-12-08  发布在  Erlang
关注(0)|答案(4)|浏览(185)

我想知道模式匹配通常是如何实现的。例如,在Erlang中,你认为它是在字节码级别实现的(有一个字节码,以便它有效地完成),还是由编译器生成为一系列指令(字节码系列)?
它是如此有用的东西,我只需要把它变成我正在构建的玩具语言。

kmbjn2e3

kmbjn2e31#

"The implementation of functional programming languages" by Simon Peyton Jones中给出了编译模式匹配的一个很好的描述。这是一本有点旧但非常好的书。它还包含了编译列表解析的描述。
Erlang编译器使用书中的这两种算法。

v6ylcynt

v6ylcynt2#

You can see what happen if compile some code

-module(match).
-export([match/1]).
match(X) -> {a,Y} = X.

When you want see how looks like core

> c(match, to_core).

or

$ erlc +to_core match.erl

result is

module 'match' ['match'/1,
                'module_info'/0,
                'module_info'/1]
    attributes []
'match'/1 =
    %% Line 3
    fun (_cor0) ->
        case _cor0 of
          <{'a',Y}> when 'true' ->
              _cor0
          ( <_cor1> when 'true' ->
                primop 'match_fail'
                    ({'badmatch',_cor1})
            -| ['compiler_generated'] )
        end
'module_info'/0 =
    fun () ->
        call 'erlang':'get_module_info'
            ('match')
'module_info'/1 =
    fun (_cor0) ->
        call 'erlang':'get_module_info'
            ('match', _cor0)

If you want see asm code of beam you can do

> c(match, 'S').

or

$ erlc -S match.erl

and result

{module, match}.  %% version = 0

{exports, [{match,1},{module_info,0},{module_info,1}]}.

{attributes, []}.

{labels, 8}.

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

{function, module_info, 0, 5}.
  {label,4}.
    {func_info,{atom,match},{atom,module_info},0}.
  {label,5}.
    {move,{atom,match},{x,0}}.
    {call_ext_only,1,{extfunc,erlang,get_module_info,1}}.

{function, module_info, 1, 7}.
  {label,6}.
    {func_info,{atom,match},{atom,module_info},1}.
  {label,7}.
    {move,{x,0},{x,1}}.
    {move,{atom,match},{x,0}}.
    {call_ext_only,2,{extfunc,erlang,get_module_info,2}}.

As you can see {test,is_tuple,... , {test,test_arity,... , {get_tuple_element,... and {test,is_eq_exact,... are instruction how this match is performed in beam and it's transformed directly to byte-code of beam.
Erlang compiler is implemented in Erlang itself and you can look at each phase of compilation in source code of compile module and details in depend modules.

7uzetpgm

7uzetpgm3#

如果你想构建你自己的模式匹配器,有一个paper by Scott and Ramsey和一个paper by Luc Maranget,它们都描述了如何将模式编译成有效的决策树(也就是嵌套的switch语句)。

dwthyt8l

dwthyt8l4#

我能建议的最好的事情是编译一些测试函数并查看生成的代码。

erlc -S test.erl

生成可读性很好的test. S。
为了回答这个问题,模式匹配是从更原始的操作中以一种有效的方式建立起来的。|T ]}的时间。

{test,is_tuple,{f,1},[{x,0}]}.
{test,test_arity,{f,1},[{x,0},2]}.
{get_tuple_element,{x,0},0,{x,1}}.
{get_tuple_element,{x,0},1,{x,2}}.
{test,is_nonempty_list,{f,4},[{x,2}]}.

相关问题