Skip to content

Commit

Permalink
add AST pattern as builtin feature
Browse files Browse the repository at this point in the history
  • Loading branch information
thautwarm committed Aug 28, 2018
1 parent db5986b commit 0798df6
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 5 deletions.
23 changes: 21 additions & 2 deletions src/MatchExt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,19 @@ pattern_match(num :: Number, guard, tag, mod :: Module) =
end

pattern_match(str :: AbstractString, guard, tag, mod :: Module) =

if guard === nothing
:($tag == $str)
else
:($tag == $str && $guard)
end

pattern_match(quoted :: QuoteNode, guard, tag, mod :: Module) =
if guard === nothing
:($tag == $quoted)
else
:($tag == $quoted && $guard)
end

pattern_match(sym :: Symbol, guard, tag, mod :: Module) =

if sym === :_
Expand All @@ -57,11 +63,24 @@ pattern_match(sym :: Symbol, guard, tag, mod :: Module) =
end
end
end
# """
# @match :(x + 1) begin
# :(x + 1) => 1
# end
# """
PatternDef.Meta(expr :: Expr -> expr.head === :quote) do expr, guard, tag, mod
if guard === nothing
:($tag == $expr)
else
:($tag == $expr && $guard)
end
end


# """
# like ^ in Erlang/Elixir
# """
PatternDef.Meta((expr :: Expr) -> expr.head == :&) do expr, guard, tag, mod
PatternDef.Meta(expr :: Expr -> expr.head == :&) do expr, guard, tag, mod
value = expr.args[1]
if guard === nothing
:($tag === $value)
Expand Down
18 changes: 15 additions & 3 deletions test/match.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,16 @@
@testset "match" begin
@testset "AST match" begin
@def ast_match begin
:x => 0
:(x + 1) => 1
:(x + 2) => 2
_ => 3
end
@test ast_match(:(x + 1)) === 1
@test ast_match(:(x + 2)) === 2
@test ast_match(:x) === 0
@test ast_match(:(x + 5)) === 3
end
@testset "literal match" begin
simple_match(x) = @match x {
1 => "wrong!"
Expand Down Expand Up @@ -70,14 +82,14 @@
# TODO: custom pattern is not fully understood yet...
@testset "dict match" begin
dict_match(dict) = @match dict begin
Dict("3" => four::Int,
Dict("3" => four::Int,
5 => Dict(6 => sev)){four < sev} => sev
end
@test dict_match(Dict(1 => 2, "3" => 4, 5 => Dict(6 => 7))) == 7
end
@testset "tuple match" begin
@test (1, 2, 3, 4) == @match (1, 2, (3, 4, (5, ))) begin
(a, b, (c, d, (5, ))) => (a, b, c, d)
(a, b, (c, d, (5, ))) => (a, b, c, d)
end
end
@testset "array match" begin
Expand All @@ -91,4 +103,4 @@
[1, pack..., a] => (pack, a)
end
end
end
end

0 comments on commit 0798df6

Please sign in to comment.