Static Capturing¶
We know that MacroTools.jl
has brought about a useful macro
@capture
to capture specific structures from a given AST.
As the motivation of some contributors, @capture
of MacroTools.jl
has the following 3 short comings.
An underscore is used to denote the structures which are to be captured, like
struct typename_ field__ end
, which makes you have to manually number the captured variables. This is not very readable or consistent.Causes Side-Effects. The captured variables are entered in current scope.
Lacks functionalities like conditional capturing.
We can implement several new @capture
via MLStyle.jl to get better results in all of these aspects.
Capture
Pattern from MLStyle.Modules.AST
:¶
MLStyle now can collaborate with scope information very well. You can get the captured variables by pattern matching in one point of your program.
using MLStyle.Modules.AST
println(Capture) # => Capture
@match :(a + b + c) begin
:($a + $b + $c) && Capture(scope) => scope
end
# Dict{Symbol,Symbol} with 3 entries:
# :a => :a
# :b => :b
# :c => :c
RAII-Style¶
This implementation prevents scope leaking.
function capture(template, ex, action)
let template = Expr(:quote, template)
quote
@match $ex begin
$template => $action
_ => nothing
end
end
end
end
macro capture(template, ex, action)
capture(template, ex, action) |> esc
end
node = :(f(1))
@capture f($(x :: T where T <: Number)) node begin
@info x + 1
end
# info: 2
node2 = :(f(x))
@capture f($(x :: T where T <: Number)) node2 begin
@info x + 1
end
# do nothing