1- mutable struct MatchError
1+ struct MatchError
22 pat
33 ex
44end
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
818function 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)
1121end
1222
@@ -18,7 +28,7 @@ function bname(s::Symbol)
1828end
1929
2030function match_inner (pat, ex, env)
21- pat == ex || nomatch (pat, ex)
31+ pat == ex || @ nomatch (pat, ex)
2232 return env
2333end
2434
@@ -43,28 +53,28 @@ inrange(i, range, len) =
4353 range ≠ (0 ,0 ) && i ≥ range[1 ] && i ≤ len+ 1 - range[2 ]
4454
4555function 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
6979end
7080
96106
97107match (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
108111function 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
114115end
0 commit comments