Skip to content

Commit

Permalink
Merge pull request #132 from serenity4/tryswitch
Browse files Browse the repository at this point in the history
Implement @tryswitch
  • Loading branch information
thautwarm committed Dec 28, 2021
2 parents 7bf8143 + d6b794e commit ebfbeae
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 1 deletion.
32 changes: 31 additions & 1 deletion src/MatchImpl.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module MatchImpl
export is_enum,
pattern_uncall, pattern_unref, pattern_unmacrocall, @switch, @match, Where, gen_match, gen_switch
pattern_uncall, pattern_unref, pattern_unmacrocall, @switch, @tryswitch, @match, Where, gen_match, gen_switch
export Q
import MLStyle
using MLStyle: mlstyle_report_deprecation_msg!
Expand Down Expand Up @@ -384,6 +384,36 @@ macro switch(val, ex)
res = init_cfg(res)
esc(res)
end
"""
@tryswitch <item> begin
@case <pattern>
<action>
end
Very similar to [`@switch`](@ref), except that a failure to match does nothing instead of throwing a "match non-exhaustive" error.
It is equivalent to
```julia
@switch <item> begin
@case <pattern>
<action>
@case _
nothing
end
```
"""
macro tryswitch(val, ex)
@assert Meta.isexpr(ex, :block)
insert_case = length(ex.args) >= 2 || begin
case, line = ex.args[end-2:end]
Meta.isexpr(case, [:macrocall], 3) &&
case.args[1] == Symbol("@case") &&
case.args[3] == :_
end
insert_case && push!(ex.args, Expr(:macrocall, Symbol("@case"), __source__, :_), :nothing)
:($(esc(:($(@__MODULE__).@switch $val $ex))))
end
@specialize
function gen_switch(val, ex, __source__::LineNumberNode, __module__::Module)
@assert Meta.isexpr(ex, :block)
Expand Down
1 change: 1 addition & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ MODULE = TestModule

include("issues/109.jl")
include("when.jl")
include("switch.jl")
include("untyped_lam.jl")
include("active_patterns.jl")
include("uncomp.jl")
Expand Down
49 changes: 49 additions & 0 deletions test/switch.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
@testcase "@switch" begin
flag = Ref(0)
function try_setflag(x)
@switch x begin
@case (::Integer, 2)
flag[] = 1
@case ::Bool
nothing
flag[] = 2
@case ::String
flag[] = 0
end
end

try_setflag((1, 2))
@test flag[] == 1
try_setflag(false)
@test flag[] == 2
try_setflag("")
@test flag[] == 0
# Non-exhaustive matches throw an error.
@test_throws ErrorException try_setflag(:a)

flag2 = Ref(0)
function try_setflag_2(x)
@tryswitch x begin
@case (::Integer, 2)
flag[] = 1
@case ::Bool
flag[] = 2
@tryswitch x begin
@case true
flag2[] = 2
end
end
end

try_setflag_2((1, 2))
@test flag[] == 1
try_setflag_2(false)
@test flag[] == 2
@test flag2[] == 0
try_setflag_2(true)
@test flag[] == 2
@test flag2[] == 2

# Non-exhaustive matches fail silently.
try_setflag_2("")
end

0 comments on commit ebfbeae

Please sign in to comment.