-
Notifications
You must be signed in to change notification settings - Fork 179
Expand file tree
/
Copy pathEvalError.hs
More file actions
161 lines (149 loc) · 6.3 KB
/
EvalError.hs
File metadata and controls
161 lines (149 loc) · 6.3 KB
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
-- | Module EvalError defines errors that may occur during evaluation.
module EvalError
( EvaluationError (..),
throwErr,
defnInvalidArgs,
loadInvalidArgs,
loadOnceInvalidArgs,
withInvalidArgs,
setInvalidArgs,
)
where
import Info
import Obj
import SymPath
import TypeError
import Types
import Util
--------------------------------------------------------------------------------
-- Data (Evaluation Errors)
-- | Errors that occur when evaluating forms.
-- Mostly called from the evaluator.
data EvaluationError
= SymbolNotFound SymPath
| PrivateBinding SymPath
| -- If
IfContainsNonBool XObj
| IfMalformed XObj
| -- Defn
DefnContainsQualifiedArgs XObj
| DefnIdentifierIsQualified XObj
| DefnMalformed XObj
| -- Def
DefIdentifierIsQualified XObj
| -- The
TheMalformed XObj
| -- Let
LetUnevenForms XObj
| LetMalformedIdentifiers [XObj]
| -- Fn
FnContainsQualifiedArgs XObj
| -- Do
DoMissingForms
| -- Unknown Form
UnknownForm XObj
| -- Function/Macro Application
MacroBadArgumentSplit [String]
| -- While
WhileContainsNonBool XObj
| -- Defmodule
ModuleRedefinition String
| DefmoduleContainsNonSymbol XObj
| DefmoduleNoArgs
| LoadFileNotFound String
| LoadGitFailure String String
| LoadRecursiveLoad String
| -- Defndynamic
DefnDynamicInvalidName XObj
| -- Set!
SetVarNotFound XObj
| SetInvalidVarName XObj
| SetTypeMismatch SymPath Ty Ty
| -- Static Call
StaticCall XObj
| -- Invalid Arguments
InvalidArgs String [XObj]
-- Show instance for Evaluation Errors.
instance Show EvaluationError where
show (SymbolNotFound path) = "Can't find symbol '" ++ show path ++ "'"
show (PrivateBinding path) =
"The binding: " ++ show path ++ " is private; it may only be used within the module that defines it."
show (IfContainsNonBool cond) =
"This `if` condition contains the non-boolean value `"
++ pretty cond
++ "`"
show (IfMalformed xobj) =
"I didn’t understand this `if`.\n\n Got:\n```\n" ++ pretty xobj
++ "\n```\n\nExpected the form:\n```\n(if cond then else)\n```\n"
show (DefnContainsQualifiedArgs args) =
"`defn` requires all arguments to be unqualified symbols, but it got `"
++ pretty args
++ "`"
show (DefnIdentifierIsQualified name) =
"`defn` identifiers must be unqualified symbols, but it got `"
++ pretty name
++ "`"
show (DefnMalformed xobj) =
"I didn’t understand the `defn` at " ++ prettyInfoFromXObj xobj
++ ":\n\n"
++ pretty xobj
++ "\n\nIs it valid? Every `defn` needs to follow the form `(defn name [arg] body)`."
show (DefIdentifierIsQualified name) =
"`def` identifiers must be unqualified symbols, but it got `"
++ pretty name
++ "`"
show (TheMalformed xobj) =
"I didn’t understand the `the` at " ++ prettyInfoFromXObj xobj
++ ":\n\n"
++ pretty xobj
++ "\n\nIs it valid? Every `the` needs to follow the form `(the type expression)`."
show (LetUnevenForms xobj) = "Uneven number of forms in `let`: " ++ pretty xobj
show (LetMalformedIdentifiers bindings) =
"`let` identifiers must be symbols, but it got `"
++ joinWithSpace (map pretty bindings)
++ "`"
show (FnContainsQualifiedArgs args) = "`fn` requires all arguments to be unqualified symbols, but it got `" ++ pretty args ++ "`"
show DoMissingForms = "No forms in do"
show (UnknownForm xobj) = "I did not understand the form `" ++ pretty xobj ++ "`"
show (MacroBadArgumentSplit allParams) =
"I didn’t understand this macro’s argument split, got `"
++ joinWith "," allParams
++ "`, but expected exactly one `:rest` separator."
show (WhileContainsNonBool c) =
"This `while` condition contains the non-boolean value '"
++ pretty c
++ "`"
show (ModuleRedefinition name) = "Can't redefine '" ++ name ++ "' as module"
show (DefmoduleContainsNonSymbol x) = "`defmodule` expects a symbol, got '" ++ pretty x ++ "' instead."
show DefmoduleNoArgs = "`defmodule` requires at least a symbol, received none."
show (LoadFileNotFound path) = " I can't find a file named: '" ++ path ++ "'" ++ "\n\nIf you tried loading an external package, try appending a version string (like `@master`)"
show (LoadGitFailure path stderr) =
"I can't find a file named: '" ++ path ++ "'"
++ "\n\nI tried interpreting the statement as a git import, but got: "
++ stderr
show (LoadRecursiveLoad path) = "A file can't load itself: '" ++ path ++ "'"
show (DefnDynamicInvalidName notName) = "`defndynamic` expected a name as first argument, but got " ++ pretty notName
show (SetVarNotFound var) = "I couldn't find the variable " ++ pretty var ++ ", did you define it using `def` or `defdynamic`?"
show (SetInvalidVarName var) = "`set!` expected a name as first argument, but got " ++ pretty var
show (SetTypeMismatch path oldTy newTy) = "can't `set!` " ++ show path ++ " to a value of type " ++ show oldTy ++ ", " ++ show path ++ " has type " ++ show newTy
show (StaticCall x) = "Unexpected static call in " ++ pretty x
show (InvalidArgs expected actual) = expected ++ ", but got: " ++ joinWithComma (map pretty actual)
--------------------------------------------------------------------------------
-- Utilities
-- | Given a Showable error, turn it into an EvalError
-- TODO: Unify this and toEvalError and remove one of these functions.
throwErr :: Show a => a -> Context -> Maybe Info -> (Context, Either EvalError XObj)
throwErr err ctx info =
evalError ctx (show err) info
--------------------------------------------------------------------------------
-- Invalid Argument Helpers
defnInvalidArgs :: [XObj] -> EvaluationError
defnInvalidArgs = InvalidArgs "Invalid args to `defn`, expected an array of symbols as an argument list"
loadInvalidArgs :: [XObj] -> EvaluationError
loadInvalidArgs = InvalidArgs "Invalid args to `load`, expected (load str optional:fileFromRepo)"
loadOnceInvalidArgs :: [XObj] -> EvaluationError
loadOnceInvalidArgs = InvalidArgs "Invalid args to `load-once`, expected `(load-once str optional:fileFromRepo)`"
withInvalidArgs :: [XObj] -> EvaluationError
withInvalidArgs = InvalidArgs "Invalid arguments to `with`, expected a module name"
setInvalidArgs :: [XObj] -> EvaluationError
setInvalidArgs = InvalidArgs "Invalid arguments to `set!`, expected a symbol and a value"