@@ -1,13 +1,16 @@
1{-# OPTIONS_GHC -Wall -fno-warn-unused-do-bind #-}
1{-# OPTIONS_GHC -Wall -fno-warn-unused-do-bind #-}
2{-# LANGUAGE OverloadedStrings #-}
2{-# LANGUAGE OverloadedStrings #-}
3−module Parse.Expression (term, expression, topLevelDef) where
3+module Parse.Expression (term, expression, definition) where
5import Control.Monad (guard)
5import Control.Monad (guard)
6import qualified Data.List as List
6import qualified Data.List as List
7−import qualified Data.Text as Text
8import Data.Text (Text)
7import Data.Text (Text)
10−import Parse.Helpers
9+import Parse.Primitives
10+import qualified Parse.Primitives.Keyword as Keyword
11+import qualified Parse.Primitives.Symbol as Symbol
12+import qualified Parse.Primitives.Variable as Var
13+import qualified Parse.Primitives.Whitespace as W
11import qualified Parse.Literal as Literal
14import qualified Parse.Literal as Literal
12import qualified Parse.Pattern as Pattern
15import qualified Parse.Pattern as Pattern
13import qualified Parse.Type as Type
16import qualified Parse.Type as Type
@@ -47,26 +50,24 @@ literal start =
48accessor :: R.Position -> Parser Src.RawExpr
51accessor :: R.Position -> Parser Src.RawExpr
49accessor start =
52accessor start =
50− do dot
53+ do Symbol.dot
51− field <- lowVar
54+ field <- Var.lower
52 end <- getPosition
55 end <- getPosition
53− let ann x = A.at start end x
56+ return (A.at start end (Src.Accessor field))
54− let body = ann (Src.Access (ann (Src.var "r")) field)
55− return (mkLambda start end "r" body)
58variable :: R.Position -> Parser Src.RawExpr
59variable :: R.Position -> Parser Src.RawExpr
59variable start =
60variable start =
60− do var <- qualifiedVar
61+ do (maybePrefix, name) <- Var.foreignAlpha
61 end <- getPosition
62 end <- getPosition
62− return (A.at start end (Src.var var))
63+ return (A.at start end (Src.Var maybePrefix name))
65accessible :: R.Position -> Src.RawExpr -> Parser Src.RawExpr
66accessible :: R.Position -> Src.RawExpr -> Parser Src.RawExpr
66accessible start expr =
67accessible start expr =
68− [ do dot
69+ [ do Symbol.dot
69− field <- lowVar
70+ field <- Var.lower
70 end <- getPosition
71 end <- getPosition
71 let newExpr = A.at start end (Src.Access expr field)
72 let newExpr = A.at start end (Src.Access expr field)
72 accessible start newExpr
73 accessible start newExpr
@@ -80,14 +81,14 @@ accessible start expr =
81list :: R.Position -> Parser Src.RawExpr
82list :: R.Position -> Parser Src.RawExpr
82list start =
83list start =
83− do leftSquare
84+ do Symbol.leftSquare
84 inContext start E.ExprList $
85 inContext start E.ExprList $
87 [ do (entry, _, pos) <- expression
88 [ do (entry, _, pos) <- expression
88 checkSpace pos
89 checkSpace pos
89 listHelp start [entry]
90 listHelp start [entry]
90− , do rightSquare
91+ , do Symbol.rightSquare
91 end <- getPosition
92 end <- getPosition
92 return (A.at start end (Src.List []))
93 return (A.at start end (Src.List []))
@@ -96,12 +97,12 @@ list start =
96listHelp :: R.Position -> [Src.RawExpr] -> Parser Src.RawExpr
97listHelp :: R.Position -> [Src.RawExpr] -> Parser Src.RawExpr
97listHelp start entries =
98listHelp start entries =
99− [ do comma
100+ [ do Symbol.comma
101 (entry, _, pos) <- expression
102 (entry, _, pos) <- expression
102 checkSpace pos
103 checkSpace pos
103 listHelp start (entry:entries)
104 listHelp start (entry:entries)
104− , do rightSquare
105+ , do Symbol.rightSquare
105 end <- getPosition
106 end <- getPosition
106 return (A.at start end (Src.List (reverse entries)))
107 return (A.at start end (Src.List (reverse entries)))
@@ -113,72 +114,50 @@ listHelp start entries =
114tuple :: R.Position -> Parser Src.RawExpr
115tuple :: R.Position -> Parser Src.RawExpr
115tuple start =
116tuple start =
116− do leftParen
117+ do Symbol.leftParen
117 pos <- getPosition
118 pos <- getPosition
118− spos <- whitespace
119+ spos <- W.whitespace
119 inContext start E.ExprTuple $ oneOf $
120 inContext start E.ExprTuple $ oneOf $
120 [ do noSpace pos spos
121 [ do noSpace pos spos
121− try (minus >> rightParen)
122+ try (Symbol.minus >> Symbol.rightParen)
122 end <- getPosition
123 end <- getPosition
123− return $ A.at start end (Src.var "-")
124+ return $ A.at start end (Src.Op "-")
125 , do checkSpace spos
126 , do checkSpace spos
126 (entry, _, spos2) <- expression
127 (entry, _, spos2) <- expression
127 checkSpace spos2
128 checkSpace spos2
128− tupleHelp start [entry]
129+ tupleHelp start entry []
130 , do noSpace pos spos
131 , do noSpace pos spos
131− op <- infixOp
132+ op <- Symbol.binop
132− rightParen
133+ Symbol.rightParen
133 end <- getPosition
134 end <- getPosition
134− return $ A.at start end (Src.var op)
135+ return $ A.at start end (Src.Op op)
136 , do noSpace pos spos
137 , do noSpace pos spos
137− rightParen
138+ Symbol.rightParen
138 end <- getPosition
139 end <- getPosition
139− return (A.at start end (Src.tuple []))
140+ return (A.at start end Src.Unit)
141− , do noSpace pos spos
143− arity <- chompCommas 2
146− let args = map (\n -> Text.pack ("v" ++ show n)) [ 1 .. arity ]
147− let ann x = A.at start end x
148− let result = ann (Src.tuple (map (ann . Src.var) args))
149− return (foldr (mkLambda start end) result args)
153−mkLambda :: R.Position -> R.Position -> Text -> Src.RawExpr -> Src.RawExpr
154−mkLambda start end arg body =
155− A.at start end (Src.Lambda (A.at start end (P.Var arg)) body)
158−chompCommas :: Int -> Parser Int
161− [ comma >> chompCommas (n + 1)
166−tupleHelp :: R.Position -> [Src.RawExpr] -> Parser Src.RawExpr
145+tupleHelp :: R.Position -> Src.RawExpr -> [Src.RawExpr] -> Parser Src.RawExpr
167−tupleHelp start entries =
146+tupleHelp start firstExpr revExprs =
169− [ do comma
148+ [ do Symbol.comma
171 (entry, _, pos) <- expression
150 (entry, _, pos) <- expression
172 checkSpace pos
151 checkSpace pos
173− tupleHelp start (entry:entries)
152+ tupleHelp start firstExpr (entry : revExprs)
174− , do rightParen
153+ , do Symbol.rightParen
175 end <- getPosition
154 end <- getPosition
176− case entries of
155+ case reverse revExprs of
177− [entry] ->
156+ [] ->
178− return entry
157+ return firstExpr
180− _ ->
159+ secondExpr : others ->
181− return (A.at start end (Src.tuple (reverse entries)))
160+ return (A.at start end (Src.Tuple firstExpr secondExpr others))
@@ -188,23 +167,23 @@ tupleHelp start entries =
189record :: R.Position -> Parser Src.RawExpr
168record :: R.Position -> Parser Src.RawExpr
190record start =
169record start =
191− do leftCurly
170+ do Symbol.leftCurly
192 inContext start E.ExprRecord $
171 inContext start E.ExprRecord $
193 do spaces
172 do spaces
195− [ do rightCurly
174+ [ do Symbol.rightCurly
196 end <- getPosition
175 end <- getPosition
197 return (A.at start end (Src.Record []))
176 return (A.at start end (Src.Record []))
198− , do starter <- addLocation lowVar
177+ , do starter <- addLocation Var.lower
201− [ do pipe
180+ [ do Symbol.pipe
203 firstField <- chompField
182 firstField <- chompField
204 fields <- chompFields [firstField]
183 fields <- chompFields [firstField]
205 end <- getPosition
184 end <- getPosition
206− return (A.at start end (Src.Update (A.map Src.var starter) fields))
185+ return (A.at start end (Src.Update starter fields))
207− , do equals
186+ , do Symbol.equals
209 (value, _, nextPos) <- expression
188 (value, _, nextPos) <- expression
210 checkSpace nextPos
189 checkSpace nextPos
@@ -221,20 +200,20 @@ type Field = ( A.Located Text, Src.RawExpr )
221chompFields :: [Field] -> Parser [Field]
200chompFields :: [Field] -> Parser [Field]
222chompFields fields =
201chompFields fields =
224− [ do comma
203+ [ do Symbol.comma
226 f <- chompField
205 f <- chompField
227 chompFields (f : fields)
206 chompFields (f : fields)
228− , do rightCurly
207+ , do Symbol.rightCurly
229 return (reverse fields)
208 return (reverse fields)
233chompField :: Parser Field
212chompField :: Parser Field
234chompField =
213chompField =
235− do key <- addLocation lowVar
214+ do key <- addLocation Var.lower
237− equals
216+ Symbol.equals
239 (value, _, pos) <- expression
218 (value, _, pos) <- expression
240 checkSpace pos
219 checkSpace pos
@@ -260,7 +239,7 @@ expression =
260 , function start
239 , function start
261 , do starter <- possiblyNegativeTerm start
240 , do starter <- possiblyNegativeTerm start
262 end <- getPosition
241 end <- getPosition
263− space <- whitespace
242+ space <- W.whitespace
264 exprHelp start (State [] starter end space)
243 exprHelp start (State [] starter end space)
@@ -282,17 +261,17 @@ exprHelp start (State ops lastExpr end pos) =
282 do checkSpace pos
261 do checkSpace pos
283 arg <- term
262 arg <- term
284 newEnd <- getPosition
263 newEnd <- getPosition
285− newPos <- whitespace
264+ newPos <- W.whitespace
286 let newLast = A.merge lastExpr arg (Src.App lastExpr arg)
265 let newLast = A.merge lastExpr arg (Src.App lastExpr arg)
287 exprHelp start (State ops newLast newEnd newPos)
266 exprHelp start (State ops newLast newEnd newPos)
289 , -- infix operator
268 , -- infix operator
290 do checkSpace pos
269 do checkSpace pos
291 opStart <- getPosition
270 opStart <- getPosition
292− opName <- infixOp
271+ opName <- Symbol.binop
293 opEnd <- getPosition
272 opEnd <- getPosition
294 let op = A.at opStart opEnd opName
273 let op = A.at opStart opEnd opName
295− spos <- whitespace
274+ spos <- W.whitespace
296 hint (E.AfterOpExpr opName) (checkSpace spos)
275 hint (E.AfterOpExpr opName) (checkSpace spos)
297 newStart <- getPosition
276 newStart <- getPosition
298 hint (E.AfterOpExpr opName) $ oneOf $
277 hint (E.AfterOpExpr opName) $ oneOf $
@@ -300,7 +279,7 @@ exprHelp start (State ops lastExpr end pos) =
300 do guard ("-" == opName && end /= opStart && opEnd == newStart)
279 do guard ("-" == opName && end /= opStart && opEnd == newStart)
301 rawTerm <- term
280 rawTerm <- term
302 newEnd <- getPosition
281 newEnd <- getPosition
303− newPos <- whitespace
282+ newPos <- W.whitespace
305 let ann x = A.merge op rawTerm x
284 let ann x = A.merge op rawTerm x
306 let negatedTerm = ann (Src.Binop [(ann Src.zero, op)] rawTerm)
285 let negatedTerm = ann (Src.Binop [(ann Src.zero, op)] rawTerm)
@@ -311,7 +290,7 @@ exprHelp start (State ops lastExpr end pos) =
311 , -- term
290 , -- term
312 do newLast <- possiblyNegativeTerm newStart
291 do newLast <- possiblyNegativeTerm newStart
313 newEnd <- getPosition
292 newEnd <- getPosition
314− newPos <- whitespace
293+ newPos <- W.whitespace
315 let newOps = (lastExpr, op) : ops
294 let newOps = (lastExpr, op) : ops
316 exprHelp start (State newOps newLast newEnd newPos)
295 exprHelp start (State newOps newLast newEnd newPos)
@@ -345,7 +324,7 @@ exprHelp start (State ops lastExpr end pos) =
345possiblyNegativeTerm :: R.Position -> Parser Src.RawExpr
324possiblyNegativeTerm :: R.Position -> Parser Src.RawExpr
346possiblyNegativeTerm start =
325possiblyNegativeTerm start =
348− [ do minus
327+ [ do Symbol.minus
349 expr <- term
328 expr <- term
350 end <- getPosition
329 end <- getPosition
351 let ann x = A.at start end x
330 let ann x = A.at start end x
@@ -360,7 +339,7 @@ possiblyNegativeTerm start =
361if_ :: R.Position -> ExprParser
340if_ :: R.Position -> ExprParser
362if_ start =
341if_ start =
363− do keyword "if"
342+ do Keyword.if_
364 inContext start E.ExprIf $ ifHelp start []
343 inContext start E.ExprIf $ ifHelp start []
@@ -369,15 +348,15 @@ ifHelp start branches =
369 do spaces
348 do spaces
370 (condition, _, condPos) <- expression
349 (condition, _, condPos) <- expression
371 checkSpace condPos
350 checkSpace condPos
372− keyword "then"
351+ Keyword.then_
374 (thenBranch, _, thenPos) <- expression
353 (thenBranch, _, thenPos) <- expression
375 hint E.ElseBranch $ checkSpace thenPos
354 hint E.ElseBranch $ checkSpace thenPos
376− hint E.ElseBranch $ keyword "else"
355+ hint E.ElseBranch $ Keyword.else_
378 let newBranches = (condition, thenBranch) : branches
357 let newBranches = (condition, thenBranch) : branches
380− [ do keyword "if"
359+ [ do Keyword.if_
381 ifHelp start newBranches
360 ifHelp start newBranches
382 , do (elseBranch, elseEnd, elseSpace) <- expression
361 , do (elseBranch, elseEnd, elseSpace) <- expression
383 let ifExpr = A.at start elseEnd (Src.If (reverse newBranches) elseBranch)
362 let ifExpr = A.at start elseEnd (Src.If (reverse newBranches) elseBranch)
@@ -391,7 +370,7 @@ ifHelp start branches =
392function :: R.Position -> ExprParser
371function :: R.Position -> ExprParser
393function start =
372function start =
394− do lambda
373+ do Symbol.lambda
395 inContext start E.ExprFunc $
374 inContext start E.ExprFunc $
396 do spaces
375 do spaces
397 arg <- Pattern.term
376 arg <- Pattern.term
@@ -409,7 +388,7 @@ gatherArgs args =
409 [ do arg <- Pattern.term
388 [ do arg <- Pattern.term
411 gatherArgs (arg:args)
390 gatherArgs (arg:args)
412− , do rightArrow
391+ , do Symbol.rightArrow
413 return args
392 return args
@@ -420,12 +399,12 @@ gatherArgs args =
421case_ :: R.Position -> ExprParser
400case_ :: R.Position -> ExprParser
422case_ start =
401case_ start =
423− do keyword "case"
402+ do Keyword.case_
424 inContext start E.ExprCase $
403 inContext start E.ExprCase $
425 do spaces
404 do spaces
426 (switcher, _, switcherPos) <- expression
405 (switcher, _, switcherPos) <- expression
427 checkSpace switcherPos
406 checkSpace switcherPos
428− keyword "of"
407+ Keyword.of_
430 oldIndent <- getIndent
409 oldIndent <- getIndent
431 newIndent <- getCol
410 newIndent <- getCol
@@ -444,7 +423,7 @@ branchHelp :: SParser (P.Raw, Src.RawExpr)
444branchHelp =
423branchHelp =
445 do (pattern, patternPos) <- Pattern.expression
424 do (pattern, patternPos) <- Pattern.expression
446 checkSpace patternPos
425 checkSpace patternPos
447− rightArrow
426+ Symbol.rightArrow
449 (branchExpr, end, pos) <- expression
428 (branchExpr, end, pos) <- expression
450 return ( (pattern, branchExpr), end, pos )
429 return ( (pattern, branchExpr), end, pos )
@@ -468,7 +447,7 @@ let_ :: R.Position -> ExprParser
468let_ start =
447let_ start =
469 do oldIndent <- getIndent
448 do oldIndent <- getIndent
470 letIndent <- getCol
449 letIndent <- getCol
471− keyword "let"
450+ Keyword.let_
472 pushContext start E.ExprLet
451 pushContext start E.ExprLet
473 setIndent letIndent
452 setIndent letIndent
@@ -487,7 +466,7 @@ letHelp start oldIndent revDefs end pos =
488 , do setIndent oldIndent
467 , do setIndent oldIndent
489 checkSpace pos
468 checkSpace pos
490− keyword "in"
469+ Keyword.in_
491 popContext ()
470 popContext ()
493 (body, newEnd, newPos) <- expression
472 (body, newEnd, newPos) <- expression
@@ -497,57 +476,62 @@ letHelp start oldIndent revDefs end pos =
500−-- DEFINITIONS
479+-- LET DEFINITIONS
503letDef :: SParser Src.RawDef
482letDef :: SParser Src.RawDef
505− definition $ \_ -> Pattern.term
485+ [ definition
508−topLevelDef :: SParser Src.RawDef
491+-- DEFINITION
510− definition $ \start ->
512− [ do op <- try (leftParen >> infixOp)
515− return (A.at start end (P.Var op))
520−definition :: (R.Position -> Parser P.Raw) -> SParser Src.RawDef
494+definition :: SParser Src.RawDef
521−definition parseRoot =
495+definition =
522 do start <- getPosition
496 do start <- getPosition
523− root <- parseRoot start
497+ name <- Var.lower
528− [ do hasType
500+ [ do Symbol.hasType
529− inContext start (E.Annotation name) $
501+ inContext start (E.Annotation name) $
530− do spaces
502+ do spaces
531− (tipe, end, space) <- Type.expression
503+ (tipe, end, space) <- Type.expression
532− return ( A.at start end (Src.Annotation name tipe), end, space )
504+ return ( A.at start end (Src.Annotation name tipe), end, space )
533− , inContext start (E.Definition name) $
505+ , inContext start (E.Definition name) $
534− definitionHelp start root []
506+ definitionHelp start name []
538− definitionHelp start root []
541−definitionHelp :: R.Position -> P.Raw -> [P.Raw] -> SParser Src.RawDef
510+definitionHelp :: R.Position -> Text -> [P.Raw] -> SParser Src.RawDef
542−definitionHelp start root revArgs =
511+definitionHelp start name revArgs =
544 [ do arg <- hint E.Arg Pattern.term
513 [ do arg <- hint E.Arg Pattern.term
546− definitionHelp start root (arg : revArgs)
515+ definitionHelp start name (arg : revArgs)
547− , do equals
516+ , do Symbol.equals
549− (expr, end, space) <- expression
518+ (body, end, space) <- expression
550− let body = List.foldl' (\e x -> A.at start end (Src.Lambda x e)) expr revArgs
551− let def = A.at start end (Src.Definition root body)
519+ let def = A.at start end (Src.Definition name (reverse revArgs) body)
552 return ( def, end, space )
520 return ( def, end, space )
528+destructure :: SParser Src.RawDef
530+ do start <- getPosition
531+ pattern <- Pattern.term
535+ (expr, end, space) <- expression
536+ let def = A.at start end (Src.Destructure pattern expr)
537+ return ( def, end, space )