Skip to content

Commit 0cf0f7c

Browse files
authored
Merge pull request #104 from MikeInnes/mji/exceptions
Avoid using exceptions for control flow
2 parents f155c51 + cdbfb0c commit 0cf0f7c

File tree

2 files changed

+24
-23
lines changed

2 files changed

+24
-23
lines changed

src/match/match.jl

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,22 @@
1-
mutable struct MatchError
1+
struct MatchError
22
pat
33
ex
44
end
55

6-
nomatch(pat, ex) = throw(MatchError(pat, ex))
6+
macro nomatch(pat, ex)
7+
:(return MatchError($(esc(pat)), $(esc(ex))))
8+
end
9+
10+
macro trymatch(ex)
11+
quote
12+
r = $(esc(ex))
13+
r isa MatchError && return r
14+
r
15+
end
16+
end
717

818
function store!(env, name, ex)
9-
haskey(env, name) && !(env[name] == ex) && nomatch(name, ex)
19+
haskey(env, name) && !(env[name] == ex) && @nomatch(name, ex)
1020
assoc!(env, name, ex)
1121
end
1222

@@ -18,7 +28,7 @@ function bname(s::Symbol)
1828
end
1929

2030
function match_inner(pat, ex, env)
21-
pat == ex || nomatch(pat, ex)
31+
pat == ex || @nomatch(pat, ex)
2232
return env
2333
end
2434

@@ -43,28 +53,28 @@ inrange(i, range, len) =
4353
range (0,0) && i range[1] && i len+1-range[2]
4454

4555
function match_inner(pat::Expr, ex::Expr, env)
46-
match(pat.head, ex.head, env)
56+
@trymatch match(pat.head, ex.head, env)
4757
pat, ex = rmlines(pat), rmlines(ex)
4858
sr = slurprange(pat.args)
4959
slurp = Any[]
5060
i = 1
5161
for p in pat.args
5262
i > length(ex.args) &&
53-
(isslurp(p) ? store!(env, bname(p), slurp) : nomatch(pat, ex))
63+
(isslurp(p) ? @trymatch(store!(env, bname(p), slurp)) : @nomatch(pat, ex))
5464

5565
while inrange(i, sr, length(ex.args))
5666
push!(slurp, ex.args[i])
5767
i += 1
5868
end
5969

6070
if isslurp(p)
61-
p :__ && store!(env, bname(p), slurp)
71+
p :__ && @trymatch store!(env, bname(p), slurp)
6272
else
63-
match(p, ex.args[i], env)
73+
@trymatch match(p, ex.args[i], env)
6474
i += 1
6575
end
6676
end
67-
i == length(ex.args)+1 || nomatch(pat, ex)
77+
i == length(ex.args)+1 || @nomatch(pat, ex)
6878
return env
6979
end
7080

@@ -96,19 +106,10 @@ end
96106

97107
match(pat, ex) = match(pat, ex, Dict())
98108

99-
function ismatch(pat, ex)
100-
try
101-
match(pat, ex)
102-
return true
103-
catch e
104-
isa(e, MatchError) ? (return false) : rethrow()
105-
end
106-
end
109+
ismatch(pat, ex) = !(match(pat, ex) isa MatchError)
107110

108111
function trymatch(pat, ex)
109-
try
110-
match(pat, ex)
111-
catch e
112-
isa(e, MatchError) ? (return) : rethrow()
113-
end
112+
r = match(pat, ex)
113+
r isa MatchError && return
114+
return r
114115
end

src/match/types.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ function tbnew(s::Symbol)
2222
end
2323

2424
match_inner(b::TypeBind, ex, env) =
25-
isexpr(ex, b.ts...) ? (env[tbname(b)] = ex; env) : nomatch(b, ex)
25+
isexpr(ex, b.ts...) ? (env[tbname(b)] = ex; env) : @nomatch(b, ex)
2626

2727
subtb(s) = s
2828
subtb(s::Symbol) = tbnew(s)

0 commit comments

Comments
 (0)