@@ -20,6 +20,7 @@ import qualified AST.Literal as L
2020import qualified AST.Variable as Variable
2121import Elm.Utils ((|>))
2222import qualified Reporting.Annotation as A
23+import qualified Reporting.Error.Syntax as Syntax
2324import qualified Reporting.Region as R
2425
2526
@@ -37,9 +38,13 @@ reserveds =
3738 ]
3839
3940
41+-- ERROR HELP
42+
4043expecting = flip (<?>)
4144
4245
46+-- SETUP
47+
4348type OpTable = Map.Map String (Int, Decl.Assoc)
4449type SourceM = State SourcePos
4550type IParser a = ParsecT String OpTable SourceM a
@@ -59,17 +64,17 @@ iParseWithTable sourceName table aParser input =
5964
6065var :: IParser String
6166var =
62− makeVar (letter <|> char '_' <?> "variable")
67+ makeVar (letter <|> char '_') <?> "a variable"
6368
6469
6570lowVar :: IParser String
6671lowVar =
67− makeVar (lower <?> "lower case variable")
72+ makeVar lower <?> "a lower case variable"
6873
6974
7075capVar :: IParser String
7176capVar =
72− makeVar (upper <?> "upper case variable")
77+ makeVar upper <?> "an upper case variable"
7378
7479
7580qualifiedVar :: IParser String
@@ -84,15 +89,15 @@ rLabel = lowVar
8489
8590innerVarChar :: IParser Char
8691innerVarChar =
87− alphaNum <|> char '_' <|> char '\'' <?> ""
92+ alphaNum <|> char '_' <|> char '\'' <?> "more letters in this variable"
8893
8994
9095makeVar :: IParser Char -> IParser String
91−makeVar p =
92− do v <- (:) <$> p <*> many innerVarChar
93− if v `elem` reserveds
94− then fail $ "unexpected keyword '" ++ v ++ "', variables cannot be keywords"
95− else return v
96+makeVar firstChar =
97+ do variable <- (:) <$> firstChar <*> many innerVarChar
98+ if variable `elem` reserveds
99+ then fail (Syntax.keyword variable)
100+ else return variable
96101
97102
98103reserved :: String -> IParser String
@@ -109,7 +114,7 @@ anyOp :: IParser String
109114anyOp =
110115 betwixt '`' '`' qualifiedVar
111116 <|> symOp
112− <?> "infix operator"
117+ <?> "an infix operator like (+)"
113118
114119
115120symOp :: IParser String
@@ -124,13 +129,23 @@ symOp =
124129-- COMMON SYMBOLS
125130
126131equals :: IParser String
127−equals = string "="
132+equals =
133+ string "=" <?> "="
134+
135+
136+rightArrow :: IParser String
137+rightArrow =
138+ string "->" <|> string "\8594" <?> "->"
139+
140+
141+leftArrow :: IParser String
142+leftArrow =
143+ string "<-" <?> "<- for a record update"
128144
129−arrow :: IParser String
130−arrow = string "->" <|> string "\8594" <?> "arrow (->)"
131145
132146hasType :: IParser String
133−hasType = string ":" <?> "':' (a type annotation)'"
147+hasType =
148+ string ":" <?> "the \"has type\" symbol ':'"
134149
135150
136151commitIf check p =
@@ -155,7 +170,7 @@ spaceyPrefixBy sep parser =
155170
156171comma :: IParser Char
157172comma =
158− char ',' <?> "comma ','"
173+ char ',' <?> "a comma ','"
159174
160175
161176commaSep1 :: IParser a -> IParser [a]
@@ -170,17 +185,17 @@ commaSep =
170185
171186semiSep1 :: IParser a -> IParser [a]
172187semiSep1 =
173− spaceySepBy1 (char ';' <?> "semicolon ';'")
188+ spaceySepBy1 (char ';' <?> "a semicolon ';'")
174189
175190
176191pipeSep1 :: IParser a -> IParser [a]
177192pipeSep1 =
178− spaceySepBy1 (char '|' <?> "type divider '|'")
193+ spaceySepBy1 (char '|' <?> "a vertical bar '|'")
179194
180195
181196consSep1 :: IParser a -> IParser [a]
182197consSep1 =
183− spaceySepBy1 (string "::" <?> "cons operator '::'")
198+ spaceySepBy1 (string "::" <?> "a cons operator '::'")
184199
185200
186201dotSep1 :: IParser a -> IParser [a]
@@ -197,15 +212,15 @@ spacePrefix p =
197212 constrainedSpacePrefix p (\_ -> return ())
198213
199214
200−constrainedSpacePrefix p constraint =
215+constrainedSpacePrefix parser constraint =
201216 many $ choice
202− [ try (spacing >> lookAhead (oneOf "[({")) >> p
203− , try (spacing >> p)
217+ [ try (spacing >> lookAhead (oneOf "[({")) >> parser
218+ , try (spacing >> parser)
204219 ]
205220 where
206221 spacing = do
207222 n <- whitespace
208− constraint n
223+ constraint n <?> Syntax.whitespace
209224 indented
210225
211226
@@ -220,14 +235,14 @@ followedBy a b =
220235betwixt a b c =
221236 do char a
222237 out <- c
223− char b <?> "closing '" ++ [b] ++ "'"
238+ char b <?> "a closing '" ++ [b] ++ "'"
224239 return out
225240
226241
227242surround a z name p = do
228243 char a
229244 v <- padded p
230− char z <?> unwords ["closing", name, show z]
245+ char z <?> unwords ["a closing", name, show z]
231246 return v
232247
233248
@@ -273,7 +288,7 @@ accessible exprParser =
273288
274289 annotatedRootExpr@(A.A _ rootExpr) <- exprParser
275290
276− access <- optionMaybe (try dot <?> "field access (e.g. List.map)")
291+ access <- optionMaybe (try dot <?> "a field access like .name")
277292
278293 case access of
279294 Nothing ->
@@ -281,7 +296,7 @@ accessible exprParser =
281296
282297 Just _ ->
283298 accessible $
284− do v <- var <?> "field access (e.g. List.map)"
299+ do v <- var
285300 end <- getMyPosition
286301 return . A.at start end $
287302 case rootExpr of
@@ -294,7 +309,8 @@ accessible exprParser =
294309
295310dot :: IParser ()
296311dot =
297− char '.' >> notFollowedBy (char '.')
312+ do char '.'
313+ notFollowedBy (char '.')
298314
299315
300316-- WHITESPACE
@@ -309,7 +325,7 @@ padded p =
309325
310326spaces :: IParser String
311327spaces =
312− let space = string " " <|> multiComment <?> "whitespace"
328+ let space = string " " <|> multiComment <?> Syntax.whitespace
313329 in
314330 concat <$> many1 space
315331
@@ -338,14 +354,14 @@ whitespace =
338354
339355freshLine :: IParser [[String]]
340356freshLine =
341− try (many1 newline >> many space_nl) <|> try (many1 space_nl) <?> ""
357+ try (many1 newline >> many space_nl) <|> try (many1 space_nl) <?> Syntax.freshLine
342358 where
343359 space_nl = try $ spaces >> many1 newline
344360
345361
346362newline :: IParser String
347363newline =
348− simpleNewline <|> lineComment <?> "a newline"
364+ simpleNewline <|> lineComment <?> Syntax.newline
349365
350366
351367simpleNewline :: IParser String
@@ -369,7 +385,7 @@ closeComment :: IParser String
369385closeComment =
370386 anyUntil $
371387 choice $
372− [ try (string "-}") <?> "close comment"
388+ [ try (string "-}") <?> "the end of a comment -}"
373389 , concat <$> sequence [ try (string "{-"), closeComment, closeComment ]
374390 ]
375391
@@ -518,9 +534,10 @@ glSource src =
518534
519535
520536str :: IParser String
521−str = expecting "String" $ do
522− s <- choice [ multiStr, singleStr ]
523− processAs T.stringLiteral . sandwich '\"' $ concat s
537+str =
538+ expecting "a string" $
539+ do s <- choice [ multiStr, singleStr ]
540+ processAs T.stringLiteral . sandwich '\"' $ concat s
524541 where
525542 rawString quote insides =
526543 quote >> manyTill insides quote
@@ -560,7 +577,7 @@ escaped delim =
560577
561578chr :: IParser Char
562579chr =
563− betwixt '\'' '\'' character <?> "character"
580+ betwixt '\'' '\'' character <?> "a character"
564581 where
565582 nonQuote = satisfy (/='\'')
566583