1
- mutable struct MatchError
1
+ struct MatchError
2
2
pat
3
3
ex
4
4
end
5
5
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
7
17
8
18
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)
10
20
assoc! (env, name, ex)
11
21
end
12
22
@@ -18,7 +28,7 @@ function bname(s::Symbol)
18
28
end
19
29
20
30
function match_inner (pat, ex, env)
21
- pat == ex || nomatch (pat, ex)
31
+ pat == ex || @ nomatch (pat, ex)
22
32
return env
23
33
end
24
34
@@ -43,28 +53,28 @@ inrange(i, range, len) =
43
53
range ≠ (0 ,0 ) && i ≥ range[1 ] && i ≤ len+ 1 - range[2 ]
44
54
45
55
function match_inner (pat:: Expr , ex:: Expr , env)
46
- match (pat. head, ex. head, env)
56
+ @trymatch match (pat. head, ex. head, env)
47
57
pat, ex = rmlines (pat), rmlines (ex)
48
58
sr = slurprange (pat. args)
49
59
slurp = Any[]
50
60
i = 1
51
61
for p in pat. args
52
62
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))
54
64
55
65
while inrange (i, sr, length (ex. args))
56
66
push! (slurp, ex. args[i])
57
67
i += 1
58
68
end
59
69
60
70
if isslurp (p)
61
- p ≠ :__ && store! (env, bname (p), slurp)
71
+ p ≠ :__ && @trymatch store! (env, bname (p), slurp)
62
72
else
63
- match (p, ex. args[i], env)
73
+ @trymatch match (p, ex. args[i], env)
64
74
i += 1
65
75
end
66
76
end
67
- i == length (ex. args)+ 1 || nomatch (pat, ex)
77
+ i == length (ex. args)+ 1 || @ nomatch (pat, ex)
68
78
return env
69
79
end
70
80
96
106
97
107
match (pat, ex) = match (pat, ex, Dict ())
98
108
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)
107
110
108
111
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
114
115
end
0 commit comments