diff --git a/src/macro.jl b/src/macro.jl index 9545107..a9c389c 100644 --- a/src/macro.jl +++ b/src/macro.jl @@ -19,11 +19,14 @@ function bindinglet(bs, body) return ex end +ensurequoted(x) = x +ensurequoted(x::Union{Expr, Symbol}) = Expr(:quote, x) + function makeclause(pat, yes, els = nothing) bs = allbindings(pat) - pat = subtb(subor(pat)) + pat = ensurequoted(subtb(subor(pat))) quote - env = trymatch($(Expr(:quote, pat)), ex) + env = trymatch($(pat), ex) if env != nothing $(bindinglet(bs, esc(yes))) else diff --git a/src/types.jl b/src/types.jl index 524bc6c..b85050d 100644 --- a/src/types.jl +++ b/src/types.jl @@ -9,14 +9,14 @@ istb(s::Symbol) = !(endswith(string(s), "_") || endswith(string(s), "_str")) && tbname(s::Symbol) = Symbol(split(string(s), "_")[1]) tbname(s::TypeBind) = s.name -totype(s::Symbol) = string(s)[1] in 'A':'Z' ? s : Expr(:quote, s) +totype(s::Symbol) = string(s)[1] in 'A':'Z' ? eval(s) : s function tbnew(s::Symbol) istb(s) || return s ts = map(Symbol, split(string(s), "_")) name = shift!(ts) ts = map(totype, ts) - Expr(:$, :(MacroTools.TypeBind($(Expr(:quote, name)), Set{Any}([$(ts...)])))) + MacroTools.TypeBind(name, Set{Any}([ts...])) end match_inner(b::TypeBind, ex, env) = diff --git a/src/union.jl b/src/union.jl index 370a27b..27fad6a 100644 --- a/src/union.jl +++ b/src/union.jl @@ -22,3 +22,4 @@ subor(s) = s subor(s::Symbol) = s subor(s::Expr) = isor(s) ? subor(ornew(s)) : Expr(s.head, map(subor, s.args)...) subor(s::OrBind) = OrBind(subor(s.pat1), subor(s.pat2)) +subtb(s::OrBind) = OrBind(subtb(s.pat1), subtb(s.pat2)) diff --git a/test/runtests.jl b/test/runtests.jl index de85d31..dc2f944 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -82,4 +82,48 @@ let @test isexpr(x, :kw) end +let + ex = :(x[1]) + @test @match(ex, begin + v_ref => v + end) == ex + + @test @match(ex, begin + v_call => v + end) === nothing + + @test @match(:(x(1)), begin + v_call => v + end) == :(x(1)) + + @test @match(:(x(1)), begin + v_ref => v + end) === nothing + + @test @match(ex, begin + (v_ref | + (v_ref <= ub_)) => (v, ub) + end) == (ex, nothing) + + @test @match(:(x <= 2), begin + (v_ref | + (v_ref <= ub_)) => (v, ub) + end) == nothing + + @test @match(:(x(3) <= 2), begin + (v_call | + (v_ref <= ub_)) => (v, ub) + end) == (:(x(3) <= 2), nothing) # only the first pattern matches + + @test @match(:(x(3) <= 2), begin + ((v_ref <= ub_) | + v_call ) => (v, ub) + end) == (:(x(3) <= 2), nothing) + + @test @match(:(x[1] <= 2), begin + (v_ref | + (v_ref <= ub_)) => (v, ub) + end) == (:(x[1]), :(2)) +end + include("destruct.jl")