[erlang-questions] pattern match test operator

Matthew Dempsky <>
Tue Nov 20 00:49:57 CET 2007


On 11/19/07, Matthew Dempsky <> wrote:
> If you don't want to patch compile.erl (or can't), change the compile
> line above to -compile({parse_transform, match}), the module line
> below to -module(match), and change Name in the case clause to '~'.

Just one more message from me (hopefully :-)... the module below takes
advantage of implementation details in how parameterized modules work,
so you can write

    -compile({parse_transform, match}).

to use the default syntax of '~'(Pattern = Expr).  Alternatively, if
you've patched compile.erl to allow parameterized modules, you can
write (e.g.)

    -compile({parse_transform, {match, is_match}}).

to change the syntax to is_match(Pattern = Expr).

To be explicit: this version only requires patching if you don't like
the default syntax using '~'.  (I suppose if you were really
interested, the parse transform could look for an -match_name(Name)
attribute or something, but this works and was less effort. ;-)


-module(match).

-export([parse_transform/2, parse_transform/3]).

parse_transform(Forms, _Options) ->
    Fun = fun(Form) -> doit(Form, '~') end,
    erl_syntax:revert_forms(
      [erl_syntax_lib:map(Fun, Form) || Form <- Forms]).

parse_transform(Forms, _Options, {match, Name}) ->
    Fun = fun(Form) -> doit(Form, Name) end,
    erl_syntax:revert_forms(
      [erl_syntax_lib:map(Fun, Form) || Form <- Forms]).

doit(Form, Name) ->
    %% Want to transform Name(Pattern = Body) to case Body of Pattern
    %% -> true; _ -> false end.
    case erl_syntax:type(Form) of
        application ->
            Operator = erl_syntax:application_operator(Form),
            case erl_syntax:type(Operator) of
                atom ->
                    case erl_syntax:atom_value(Operator) of
                        Name ->
                            [Args] = erl_syntax:application_arguments(Form),
                            match_expr = erl_syntax:type(Args),
                            Pattern = erl_syntax:match_expr_pattern(Args),
                            Body = erl_syntax:match_expr_body(Args),
                            erl_syntax:case_expr(
                              Body,
                              [erl_syntax:clause([Pattern],
                                                 none,
                                                 [erl_syntax:atom(true)]),
                               erl_syntax:clause([erl_syntax:underscore()],
                                                 none,
                                                 [erl_syntax:atom(false)])]);
                        _ ->
                            Form
                    end;
                _ ->
                    Form
            end;
        _ ->
            Form
    end.



More information about the erlang-questions mailing list