================================================================================
record index
================================================================================

f() -> #record.field.

--------------------------------------------------------------------------------

(source_file
  (fun_decl
    (function_clause
      (atom)
      (expr_args)
      (clause_body
        (record_index_expr
          (record_name
            (atom))
          (record_field_name
            (atom)))))))

================================================================================
record field
================================================================================

f(X) -> X#record.field.

--------------------------------------------------------------------------------

(source_file
  (fun_decl
    (function_clause
      (atom)
      (expr_args
        (var))
      (clause_body
        (record_field_expr
          (var)
          (record_name
            (atom))
          (record_field_name
            (atom)))))))

================================================================================
record expr
================================================================================

f() -> #record{a = 1}.

--------------------------------------------------------------------------------

(source_file
  (fun_decl
    (function_clause
      (atom)
      (expr_args)
      (clause_body
        (record_expr
          (record_name
            (atom))
          (record_field
            (atom)
            (field_expr
              (integer))))))))

================================================================================
record update
================================================================================

f(X) -> X#record{a = 1}.

--------------------------------------------------------------------------------

(source_file
  (fun_decl
    (function_clause
      (atom)
      (expr_args
        (var))
      (clause_body
        (record_update_expr
          (var)
          (record_name
            (atom))
          (record_field
            (atom)
            (field_expr
              (integer))))))))

================================================================================
try
================================================================================

f(X) ->
  try 1 of
    X -> ok;
    Y when Z -> ok
  catch
    Pattern -> ok;
    error:Pattern -> ok;
    throw:Pattern:Stack -> ok;
    exit:Complex + Pattern:Stack -> ok
  after
    ok
  end,
  try _
  catch
  end.

--------------------------------------------------------------------------------

(source_file
  (fun_decl
    (function_clause
      (atom)
      (expr_args
        (var))
      (clause_body
        (try_expr
          (integer)
          (cr_clause
            (var)
            (clause_body
              (atom)))
          (cr_clause
            (var)
            (guard
              (guard_clause
                (var)))
            (clause_body
              (atom)))
          (catch_clause
            (var)
            (clause_body
              (atom)))
          (catch_clause
            (try_class
              (atom))
            (var)
            (clause_body
              (atom)))
          (catch_clause
            (try_class
              (atom))
            (var)
            (try_stack
              (var))
            (clause_body
              (atom)))
          (catch_clause
            (try_class
              (atom))
            (binary_op_expr
              (var)
              (var))
            (try_stack
              (var))
            (clause_body
              (atom)))
          (try_after
            (atom)))
        (try_expr
          (var))))))

================================================================================
funs
================================================================================

f() -> [
  fun foo/1,
  fun mod:foo/1,
  fun () -> ok end
].

--------------------------------------------------------------------------------

(source_file
  (fun_decl
    (function_clause
      (atom)
      (expr_args)
      (clause_body
        (list
          (internal_fun
            (atom)
            (arity
              (integer)))
          (external_fun
            (module
              (atom))
            (atom)
            (arity
              (integer)))
          (anonymous_fun
            (fun_clause
              (expr_args)
              (clause_body
                (atom)))))))))

================================================================================
list
================================================================================

f() ->
  [],
  [A],
  [A, B],
  [A | B],
  [A + B | B + C],
  [A, B | C].

--------------------------------------------------------------------------------

(source_file
  (fun_decl
    (function_clause
      (atom)
      (expr_args)
      (clause_body
        (list)
        (list
          (var))
        (list
          (var)
          (var))
        (list
          (pipe
            (var)
            (var)))
        (list
          (pipe
            (binary_op_expr
              (var)
              (var))
            (binary_op_expr
              (var)
              (var))))
        (list
          (var)
          (pipe
            (var)
            (var)))))))

================================================================================
binary
================================================================================

f(<<_>>) ->
  <<>>,
  <<1>>,
  <<1/integer>>,
  <<1:32/integer>>,
  <<+1:32/integer>>,
  <<1:32/integer-unit:8>>.

--------------------------------------------------------------------------------

(source_file
  (fun_decl
    (function_clause
      (atom)
      (expr_args
        (binary
          (bin_element
            (var))))
      (clause_body
        (binary)
        (binary
          (bin_element
            (integer)))
        (binary
          (bin_element
            (integer)
            (bit_type_list
              (atom))))
        (binary
          (bin_element
            (integer)
            (bit_size_expr
              (integer))
            (bit_type_list
              (atom))))
        (binary
          (bin_element
            (unary_op_expr
              (integer))
            (bit_size_expr
              (integer))
            (bit_type_list
              (atom))))
        (binary
          (bin_element
            (integer)
            (bit_size_expr
              (integer))
            (bit_type_list
              (atom)
              (bit_type_unit
                (integer)))))))))

================================================================================
catch
================================================================================

f() ->
  catch 1 + 2.

--------------------------------------------------------------------------------

(source_file
  (fun_decl
    (function_clause
      (atom)
      (expr_args)
      (clause_body
        (catch_expr
          (binary_op_expr
            (integer)
            (integer)))))))

================================================================================
receive
================================================================================

f() ->
  receive
  end,
  receive
    ok -> ok;
    error -> error
  end,
  receive
    after 1000 -> ok
  end,
  receive
    ok -> ok
    after Timeout -> timeout
  end.

--------------------------------------------------------------------------------

(source_file
  (fun_decl
    (function_clause
      (atom)
      (expr_args)
      (clause_body
        (receive_expr)
        (receive_expr
          (cr_clause
            (atom)
            (clause_body
              (atom)))
          (cr_clause
            (atom)
            (clause_body
              (atom))))
        (receive_expr
          (receive_after
            (integer)
            (clause_body
              (atom))))
        (receive_expr
          (cr_clause
            (atom)
            (clause_body
              (atom)))
          (receive_after
            (var)
            (clause_body
              (atom))))))))

================================================================================
case
================================================================================

f() ->
  case _ of
  end,
  case Foo of
    A when A; B, C -> ok;
    _ -> error
  end.

--------------------------------------------------------------------------------

(source_file
  (fun_decl
    (function_clause
      (atom)
      (expr_args)
      (clause_body
        (case_expr
          (var))
        (case_expr
          (var)
          (cr_clause
            (var)
            (guard
              (guard_clause
                (var))
              (guard_clause
                (var)
                (var)))
            (clause_body
              (atom)))
          (cr_clause
            (var)
            (clause_body
              (atom))))))))

================================================================================
function call
================================================================================

f() ->
  foo(),
  (foo)(),
  mod:foo(),
  (mod:foo)(),
  (Mod):(Foo)().

--------------------------------------------------------------------------------

(source_file
  (fun_decl
    (function_clause
      (atom)
      (expr_args)
      (clause_body
        (call
          (atom)
          (expr_args))
        (call
          (paren_expr
            (atom))
          (expr_args))
        (call
          (remote
            (remote_module
              (atom))
            (atom))
          (expr_args))
        (call
          (paren_expr
            (remote
              (remote_module
                (atom))
              (atom)))
          (expr_args))
        (call
          (remote
            (remote_module
              (paren_expr
                (var)))
            (paren_expr
              (var)))
          (expr_args))))))

================================================================================
variable assignment
================================================================================

f() ->
  A = 3 + B.

--------------------------------------------------------------------------------

    (source_file
      (fun_decl
        (function_clause
          (atom)
          (expr_args)
          (clause_body
            (match_expr
              (var)
              (binary_op_expr
                (integer)
                (var)))))))

================================================================================
fun
================================================================================

 foo() -> fun(X) -> X end.

--------------------------------------------------------------------------------

    (source_file
      (fun_decl
        (function_clause
          (atom)
          (expr_args)
          (clause_body
            (anonymous_fun
              (fun_clause
                (expr_args
                  (var))
                (clause_body
                  (var))))))))

================================================================================
named fun
================================================================================

 foo() -> fun Named(X) -> X end.

--------------------------------------------------------------------------------

    (source_file
      (fun_decl
        (function_clause
          (atom)
          (expr_args)
          (clause_body
            (anonymous_fun
              (fun_clause
                (var)
                (expr_args
                  (var))
                (clause_body
                  (var))))))))
