cerl_clauses
Utility functions for Core Erlang case/receive clauses.
Utility functions for Core Erlang case/receive clauses.
Syntax trees are defined in the module cerl.
DATA TYPES
cerl() = cerl() (see module cerl)
Functions
is_catchall(Clause::cerl()) -> boolean()
Returns true
if an abstract clause is a
catch-all, otherwise false
. A clause is a catch-all if
all its patterns are variables, and its guard expression always
evaluates to true
; cf. eval_guard/1
.
Note: Clause
must have type
clause
.
See also: any_catchall/1, eval_guard/1.
any_catchall(Clauses::[cerl()]) -> boolean()
Returns true
if any of the abstract clauses in
the list is a catch-all, otherwise false
. See
is_catchall/1
for details.
Note: each node in Clauses
must have type
clause
.
See also: is_catchall/1.
eval_guard(Expr::cerl()) -> none | {value, term()}
Tries to reduce a guard expression to a single constant value,
if possible. The returned value is {value, Term}
if the
guard expression Expr
always yields the constant value
Term
, and is otherwise none
.
Note that although guard expressions should only yield boolean
values, this function does not guarantee that Term
is
either true
or false
. Also note that only
simple constructs like let-expressions are examined recursively;
general constant folding is not performed.
See also: is_catchall/1.
reduce(Cs::Clauses) -> {true, {Clause, Bindings}} | {false, Clauses}
Equivalent to reduce(Cs, []).
reduce(Clauses::[Clause], Exprs::[Expr]) -> {true, {Clause, Bindings}} | {false, [Clause]}
Clause = cerl()
Expr = any | cerl()
Bindings = [{cerl(), cerl()}]
Selects a single clause, if possible, or otherwise reduces the
list of selectable clauses. The input is a list Clauses
of abstract clauses (i.e., syntax trees of type clause
),
and a list of switch expressions Exprs
. The function
tries to uniquely select a single clause or discard unselectable
clauses, with respect to the switch expressions. All abstract clauses
in the list must have the same number of patterns. If
Exprs
is not the empty list, it must have the same
length as the number of patterns in each clause; see
match_list/2
for details.
A clause can only be selected if its guard expression always
yields the atom true
, and a clause whose guard
expression always yields the atom false
can never be
selected. Other guard expressions are considered to have unknown
value; cf. eval_guard/1
.
If a particular clause can be selected, the function returns
{true, {Clause, Bindings}}
, where Clause
is
the selected clause and Bindings
is a list of pairs
{Var, SubExpr}
associating the variables occurring in
the patterns of Clause
with the corresponding
subexpressions in Exprs
. The list of bindings is given
in innermost-first order; see the match/2
function for
details.
If no clause could be definitely selected, the function returns
{false, NewClauses}
, where NewClauses
is
the list of entries in Clauses
that remain after
eliminating unselectable clauses, preserving the relative order.
See also: eval_guard/1, match/2, match_list/2.
match(Pattern::cerl(), E::Expr) -> none | {true, Bindings} | {false, Bindings}
Expr = any | cerl()
Bindings = [{cerl(), Expr}]
Matches a pattern against an expression. The returned value is
none
if a match is impossible, {true,
Bindings}
if Pattern
definitely matches
Expr
, and {false, Bindings}
if a match is
not definite, but cannot be excluded. Bindings
is then
a list of pairs {Var, SubExpr}
, associating each
variable in the pattern with either the corresponding subexpression
of Expr
, or with the atom any
if no
matching subexpression exists. (Recall that variables may not be
repeated in a Core Erlang pattern.) The list of bindings is given
in innermost-first order; this should only be of interest if
Pattern
contains one or more alias patterns. If the
returned value is {true, []}
, it implies that the
pattern and the expression are syntactically identical.
Instead of a syntax tree, the atom any
can be
passed for Expr
(or, more generally, be used for any
subtree of Expr
, in as much the abstract syntax tree
implementation allows it); this means that it cannot be decided
whether the pattern will match or not, and the corresponding
variable bindings will all map to any
. The typical use
is for producing bindings for receive
clauses.
Note: Binary-syntax patterns are never structurally matched against binary-syntax expressions by this function.
Examples:
Matching a pattern "
{X, Y}
" against the expression "{foo, f(Z)}
" yields{true, Bindings}
whereBindings
associates "X
" with the subtree "foo
" and "Y
" with the subtree "f(Z)
".Matching pattern "
{X, {bar, Y}}
" against expression "{foo, f(Z)}
" yields{false, Bindings}
whereBindings
associates "X
" with the subtree "foo
" and "Y
" withany
(because it is not known if "{foo, Y}
" might match the run-time value of "f(Z)
" or not).Matching pattern "
{foo, bar}
" against expression "{foo, f()}
" yields{false, []}
, telling us that there might be a match, but we cannot deduce any bindings.Matching
{foo, X = {bar, Y}}
against expression "{foo, {bar, baz}}
" yields{true, Bindings}
whereBindings
associates "Y
" with "baz
", and "X
" with "{bar, baz}
".Matching a pattern "
{X, Y}
" againstany
yields{false, Bindings}
whereBindings
associates both "X
" and "Y
" withany
.
match_list(Patterns::[cerl()], Exprs::[Expr]) -> none | {true, Bindings} | {false, Bindings}
Expr = any | cerl()
Bindings = [{cerl(), cerl()}]
Like match/2
, but matching a sequence of patterns
against a sequence of expressions. Passing an empty list for
Exprs
is equivalent to passing a list of
any
atoms of the same length as Patterns
.
See also: match/2.