Refactor to note TODO centrally and avoid `where` more.
Chris Pressey
5 years ago
27 | 27 | |
28 | 28 | Opaque type might also be useful for internals, e.g. signaling |
29 | 29 | to runtime system that an error occurred. |
30 | ||
31 | Exceptions | |
32 | ---------- | |
33 | ||
34 | Raising a list that looks like `(uncaught-exception ...)`, and | |
35 | then catching anything that looks like that, is less than fantastic. | |
36 | (We do this in `display` and in reactors). Should we have a | |
37 | dedicated `error` type Expr? | |
30 | 38 | |
31 | 39 | Stdlib |
32 | 40 | ------ |
14 | 14 | body :: Expr -- body takes three arguments: event state |
15 | 15 | } deriving (Show, Eq) |
16 | 16 | |
17 | ||
18 | 17 | update :: Reactor -> Expr -> (Reactor, [Expr]) |
19 | 18 | update reactor@Reactor{rid=rid, env=env, state=state, body=body} event = |
20 | 19 | let |
21 | 20 | env' = setExceptionHandler (Intrinsic "(exception-handler)" catchException) env |
22 | in | |
23 | case eval env' (List [body, event, state]) id of | |
24 | command@(List [(Symbol "uncaught-exception"), expr]) -> | |
25 | (reactor, [command]) | |
26 | (List (state':commands)) -> | |
27 | (reactor{ state=state' }, applyStop commands) | |
28 | expr -> | |
29 | (reactor, [List [(Symbol "malformed-response"), expr]]) | |
30 | where | |
31 | 21 | catchException env expr k = List [(Symbol "uncaught-exception"), expr] |
32 | 22 | |
33 | 23 | -- If the reactor issued a 'stop' command, decorate that command |
38 | 28 | (List [Symbol "stop", Number rid]:applyStop commands) |
39 | 29 | applyStop (command:commands) = |
40 | 30 | (command:applyStop commands) |
31 | in | |
32 | case eval env' (List [body, event, state]) id of | |
33 | command@(List [(Symbol "uncaught-exception"), expr]) -> | |
34 | (reactor, [command]) | |
35 | (List (state':commands)) -> | |
36 | (reactor{ state=state' }, applyStop commands) | |
37 | expr -> | |
38 | (reactor, [List [(Symbol "malformed-response"), expr]]) | |
41 | 39 | |
42 | 40 | |
43 | 41 | updateMany :: [Reactor] -> Expr -> ([Reactor], [Expr]) |
10 | 10 | |
11 | 11 | collect ((List [Symbol "display", expr]):rest) env reactors results = |
12 | 12 | let |
13 | catchException env expr k = List [(Symbol "uncaught-exception"), expr] | |
13 | 14 | env' = setExceptionHandler (Intrinsic "(exception-handler)" catchException) env |
14 | 15 | result = case eval env' expr id of |
15 | -- TODO This is less than fantastic. Should we have a dedicated error Expr? | |
16 | e@(List [(Symbol "uncaught-exception"), expr]) -> Left expr | |
16 | (List [(Symbol "uncaught-exception"), expr]) -> Left expr | |
17 | 17 | other -> Right other |
18 | 18 | in |
19 | 19 | collect rest env reactors (result:results) |
20 | where | |
21 | catchException env expr k = List [(Symbol "uncaught-exception"), expr] | |
22 | 20 | |
23 | 21 | collect ((List [Symbol "assert", expr]):rest) env reactors results = |
24 | 22 | case eval env expr id of |