-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathcatch-any.r
100 lines (96 loc) · 2.13 KB
/
catch-any.r
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
Rebol [
Title: "Catch-any"
File: %catch-any.r
Copyright: [2012 "Saphirion AG"]
License: {
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
}
Author: "Ladislav Mecir"
Purpose: "Catch any REBOL exception"
]
make object! [
do-block: func [
; helper for catching BREAK, CONTINUE, THROW or QUIT
block [block!]
exception [word!]
/local result
] [
; TRY wraps CATCH/QUIT to circumvent bug#851
try [
catch/quit [
catch [
loop 1 [
try [
set exception 'return
set/any 'result do block
set exception none
return :result
]
; an error was triggered
set exception 'error
exit
]
; BREAK or CONTINUE
set exception 'break
exit
]
; THROW
set exception 'throw
exit
]
; QUIT
set exception 'quit
exit
]
]
set 'catch-any func [
{catches any REBOL exception}
block [block!] {block to evaluate}
exception [word!] {used to return the exception type}
/local result
] either rebol/version >= 2.100.0 [[
; catch RETURN, EXIT and RETURN/REDO
; using the DO-BLOCK helper call
; the helper call is enclosed in a block
; not containing any additional values
; to not give REDO any "excess arguments"
; also, it is necessary to catch all above exceptions again
; in case they are triggered by REDO
; TRY wraps CATCH/QUIT to circumvent bug#851
try [
catch/quit [
try [
catch [
loop 1 [set/any 'result do-block block exception]
]
]
]
]
either get exception [#[unset!]] [:result]
]] [[
error? set/any 'result catch [
error? set/any 'result loop 1 [
error? result: try [
; RETURN or EXIT
set exception 'return
set/any 'result do block
; no exception
set exception none
return get/any 'result
]
; an error was triggered
set exception 'error
return result
]
; BREAK
set exception 'break
return get/any 'result
]
; THROW
set exception 'throw
return get/any 'result
]]
]