cerl_clauses
(compiler)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()) -> bool()
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()]) -> bool()
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, {Clauses, 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}whereBindingsassociates "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}whereBindingsassociates "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}whereBindingsassociates "Y" with "baz", and "X" with "{bar, baz}".Matching a pattern "
{X, Y}" againstanyyields{false, Bindings}whereBindingsassociates 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.