on master help sign in
Improve parse errors for records
65a825dEvan Czaplicki
src/Parse/Expression.hs+45−27
@@ -132,8 +132,11 @@ parensTerm =
132recordTerm :: IParser Source.Expr
132recordTerm :: IParser Source.Expr
133recordTerm =
133recordTerm =
134 addLocation $
134 addLocation $
135− brackets $ choice [ misc, record ]
135+ brackets (choice [ misc, record ])
136 where
136 where
137+ record =
138+ E.Record <$> commaSep field
139+
137 field =
140 field =
138 do label <- rLabel
141 do label <- rLabel
139 patterns <- spacePrefix Pattern.term
142 patterns <- spacePrefix Pattern.term
@@ -141,38 +144,53 @@ recordTerm =
141 body <- expr
144 body <- expr
142 return (label, makeFunction patterns body)
145 return (label, makeFunction patterns body)
143
146
144− record =
147+ misc =
145− E.Record <$> commaSep field
148+ do nextParser <- try miscStarter
146−
147− change =
148− do lbl <- rLabel
149− padded (string "<-")
150− (,) lbl <$> expr
151−
152− remove r =
153− do string "-"
154 whitespace
149 whitespace
155− E.Remove r <$> rLabel
150+ nextParser
156
151
157− insert r =
152+ miscStarter =
158− do string "|"
153+ do start <- getMyPosition
154+ record <- addLocation (E.rawVar <$> rLabel)
159 whitespace
155 whitespace
160− E.Insert r <$> rLabel <*> (padded equals >> expr)
156+ choice
157+ [ string "-" >> return (afterMinus start record)
158+ , string "|" >> return (afterBar record)
159+ ]
161
160
162− modify r =
161+ afterMinus start record =
163− do string "|"
162+ do field <- rLabel
163+ end <- getMyPosition
164+ let subRecord' = E.Remove record field
165+ maybe <- optionMaybe (try (whitespace >> string "|"))
166+ case maybe of
167+ Nothing ->
168+ return subRecord'
169+ Just _ ->
170+ do whitespace
171+ field <- rLabel
172+ padded equals
173+ E.Insert (A.at start end subRecord') field <$> expr
174+
175+ afterBar record =
176+ do field <- rLabel
164 whitespace
177 whitespace
165− E.Modify r <$> commaSep1 change
178+ choice
179+ [ do equals
180+ whitespace
181+ E.Insert record field <$> expr
182+ , do string "<-"
183+ whitespace
184+ value <- expr
185+ updates <- spaceyPrefixBy comma update
186+ return (E.Modify record ((field,value) : updates))
187+ ]
188+
189+ update =
190+ do lbl <- rLabel
191+ padded (string "<-")
192+ (,) lbl <$> expr
166
193
167− misc =
168− try $ do
169− record <- addLocation (E.rawVar <$> rLabel)
170− opt <- padded (optionMaybe (addLocation (remove record)))
171− case opt of
172− Just e@(A.A _ e') ->
173− try (insert e) <|> return e'
174− Nothing ->
175− try (insert record) <|> try (modify record)
176
194
177
195
178term :: IParser Source.Expr
196term :: IParser Source.Expr
src/Parse/Helpers.hs+8−3
@@ -143,9 +143,14 @@ commitIf check p =
143-- SEPARATORS
143-- SEPARATORS
144
144
145spaceySepBy1 :: IParser b -> IParser a -> IParser [a]
145spaceySepBy1 :: IParser b -> IParser a -> IParser [a]
146−spaceySepBy1 sep p =
146+spaceySepBy1 sep parser =
147− do a <- p
147+ do value <- parser
148+ (value:) <$> spaceyPrefixBy sep parser
149+
150+
151+spaceyPrefixBy :: IParser sep -> IParser a -> IParser [a]
152+spaceyPrefixBy sep parser =
148− (a:) <$> many (commitIf (whitespace >> sep) (padded sep >> p))
153+ many (commitIf (whitespace >> sep) (padded sep >> parser))
149
154
150
155
151comma :: IParser Char
156comma :: IParser Char