Build StatusCoverage Status

ExprManipulation provides tools for manipulating expressions based on the Expr syntax.


The API is small there are only 4 constructs MExpr, Capture, Slurp and transform.


using ExprManipulation
using Base.Meta: show_sexpr

expr = :(x + 1)
# (:call, :+, :x, 1)

A MExpr can be used to test equality

m_expr = MExpr(:call, :+, Capture(:x), Capture(:n))
m_expr == expr


You can extract the the captured arguments with match, if the expressions aren't equal match will return nothing

match(m_expr, expr)
#(x = :x, n = 1)

Slurp allows you to capture a variable number of arguments. It can be used anywhere in the expressions args but only a single Slurp per an MExpr.

m_expr = MExpr(:tuple, Capture(:first_number), Slurp(:args), Capture(:last_number))
match(m_expr, :(1,2,3,4,5))
# (first_number = 1, args = Any[2, 3, 4], last_number = 5)

Both Capture and Slurp can take a function to test equality.

head = Capture(:head) do arg
    arg in (:vect, :tuple)

slurp_numbers = Slurp(:numbers) do args::Array
    all(map(x -> x isa Number, args))

vec_or_tuple = MExpr(head, slurp_numbers)

match(vec_or_tuple, :((1,2,3)))
# (head = :tuple, numbers = [1, 2, 3])

match(vec_or_tuple, :((1,"2",3)))
# nothing


Transform can be used to create a new expression, it applies a function to each node in the Expr tree starting from the leaves. For example to replace all the numbers with 1.

transform(input_expr) do node
    node isa Number ? 1 : node
# :(1 + (1 ^ 1) * 1)


For more in-depth examples see the examples folder.

Related Packages

Other packages you may find usefull for handling Exprs

  • ExprTools
  • MacroTools
  • MLStyle