git @ Cat's Eye Technologies Robin / 0bfcf5c
Restore `catch`. Chris Pressey 5 years ago
3 changed file(s) with 96 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
33
44 mkdir -p pkg
55
6 cat stdlib/equal-p.robin stdlib/eval.robin stdlib/head.robin \
6 cat stdlib/catch.robin stdlib/equal-p.robin stdlib/eval.robin stdlib/head.robin \
77 stdlib/if.robin stdlib/list-p.robin stdlib/macro-p.robin stdlib/macro.robin \
88 stdlib/number-p.robin stdlib/prepend.robin stdlib/raise.robin stdlib/sign.robin \
99 stdlib/subtract.robin stdlib/symbol-p.robin stdlib/tail.robin \
8787 eval env expr (\v -> cc $ Error v)
8888 robinRaise env other cc = errMsg "illegal-arguments" other
8989
90 robinCatch :: Evaluable
91 robinCatch env (List [(Symbol s), handler, body]) cc =
92 eval env body (\result ->
93 case result of
94 e@(Error contents) ->
95 eval (insert s contents env) handler cc
96 _ ->
97 cc result)
98 robinCatch env other cc = errMsg "illegal-arguments" other
99
90100 robinIntrinsics :: Env
91101 robinIntrinsics = fromList $ map (\(name,bif) -> (name, Intrinsic name bif))
92102 [
103113 ("macro", robinMacro),
104114 ("eval", robinEval),
105115 ("if", robinIf),
106 ("raise", robinRaise)
116 ("raise", robinRaise),
117 ("catch", robinCatch)
107118 ]
0 ;'<<SPEC'
1
2 ### `catch` ###
3
4 -> Tests for functionality "Evaluate Robin Expression (with literal and list)"
5
6 `catch` handles error values.
7
8 TODO: this is written as if catch handles exceptions, but it doesn't anymore.
9
10 If an exception is raised when evaluating the final argument of
11 `catch`, the exception value is bound to the symbol given as the
12 first argument of `catch`, and the second argument of `catch` is
13 evaluated in that new environment.
14
15 | (catch error (list error #f)
16 | (raise (literal (nasty-value 999999))))
17 = ((nasty-value 999999) #f)
18
19 If an exception is raised in the body of a macro that is applied
20 in the context of a `catch`, it will still be catched.
21
22 | (catch error (list error #f)
23 | ((macro (self args env) (raise (literal (nasty-value 1111)))) joe))
24 = ((nasty-value 1111) #f)
25
26 If nothing is raised, `catch` will evaluate to whatever its body
27 evaluated to.
28
29 | (catch error (list error #f) 42)
30 = 42
31
32 The innermost `catch` will catch the exception.
33
34 | (catch error (list error 5)
35 | (catch error (list error 9)
36 | (raise (literal derpy-value))))
37 = (derpy-value 9)
38
39 An exception raised from within an exception handler is
40 caught by the next innermost exception handler.
41
42 | (catch error (list error 5)
43 | (catch error (list error 9)
44 | (catch error (raise (list error error))
45 | (raise 7))))
46 = ((7 7) 9)
47
48 `catch` expects its first argument to be a symbol.
49
50 | (catch (3 4) (list error #f) 42)
51 ? uncaught exception: (illegal-arguments ((3 4) (list error #f) 42))
52
53 `catch` expects exactly three arguments.
54
55 | (catch error (list error #f))
56 ? uncaught exception: (illegal-arguments (error (list error #f)))
57
58 | (catch error (list error #f) 42 43)
59 ? uncaught exception: (illegal-arguments (error (list error #f) 42 43))
60
61 -> Tests for functionality "Evaluate Robin Expression (with Small)"
62
63 `catch` handles error values, and this does not include the environment
64 in which the error value was produced.
65
66 | (catch error (list flop error)
67 | (bind flop 1
68 | (raise 2)))
69 ? uncaught exception: (unbound-identifier flop)
70
71 `catch` handles error values, and this does not include the environment
72 in which the error value was produced.
73
74 | (bind flop (fun (x) (raise x))
75 | (list
76 | (catch error (list 55 error) (flop 44))
77 | (catch error (list 66 error) (flop 44))))
78 = ((55 44) (66 44))
79
80 '<<SPEC'
81
82 (require catch)