-
Notifications
You must be signed in to change notification settings - Fork 1
/
Error.hs
66 lines (51 loc) · 2.19 KB
/
Error.hs
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
module Error
( LispError(..),
ThrowsError,
trapError,
extractValue,
throwError,
catchError,
IOThrowsError,
liftThrows,
runIOThrows
) where
import Control.Monad.Except
import Text.ParserCombinators.Parsec (ParseError)
import AST
------------------------------------------------------------------------
-- Error stuff
------------------------------------------------------------------------
data LispError = NumArgs Integer [LispVal]
| TypeMismatch String LispVal
| Parser ParseError
| BadSpecialForm String LispVal
| NotFunction String String
| UnboundVar String String
| UnendedExpr String
| BadIndex LispVal LispVal
| Default String
showError :: LispError -> String
showError (UnboundVar message varname) = message ++ ": " ++ varname
showError (BadSpecialForm message form) = message ++ ": " ++ show form
showError (NotFunction message func) = message ++ ": " ++ show func
showError (NumArgs expected found) = "Expected " ++ show expected
++ " args; found values " ++ unwordsList found
showError (TypeMismatch expected found) = "Invalid type: expected " ++ expected
++ ", found " ++ show found
showError (Parser parseErr) = "Parse error at " ++ show parseErr
showError (UnendedExpr message) = "No else found; " ++ message
showError (BadIndex string index) = "Bad index " ++ show index ++ " for "
++ show string
instance Show LispError where show = showError
-- AFAIK to convert this just change import to Control.Monad.Except and
-- delete the following three lines
type ThrowsError = Either LispError
trapError action = catchError action (return . show)
extractValue :: ThrowsError a -> a
extractValue (Right val) = val
type IOThrowsError = ExceptT LispError IO
liftThrows :: ThrowsError a -> IOThrowsError a
liftThrows (Left err) = throwError err
liftThrows (Right val) = return val
runIOThrows :: IOThrowsError String -> IO String
runIOThrows action = runExceptT (trapError action) >>= return . extractValue