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)
show_sexpr(expr)
# (:call, :+, :x, 1)A MExpr can be used to test equality
m_expr = MExpr(:call, :+, Capture(:x), Capture(:n))
m_expr == expr
#trueYou 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)
end
slurp_numbers = Slurp(:numbers) do args::Array
all(map(x -> x isa Number, args))
end
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)))
# nothingTransform 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
end
# :(1 + (1 ^ 1) * 1)For more in-depth examples see the examples folder.
Other packages you may find usefull for handling Exprs
- ExprTools
- MacroTools
- MLStyle