@@ -1,13 +1,16 @@
11{-# OPTIONS_GHC -Wall -fno-warn-unused-do-bind #-}
22{-# LANGUAGE OverloadedStrings #-}
3−module Parse.Expression (term, expression, topLevelDef) where
3+module Parse.Expression (term, expression, definition) where
44
55import Control.Monad (guard)
66import qualified Data.List as List
7−import qualified Data.Text as Text
87import Data.Text (Text)
98
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
1114import qualified Parse.Literal as Literal
1215import qualified Parse.Pattern as Pattern
1316import qualified Parse.Type as Type
@@ -47,26 +50,24 @@ literal start =
4750
4851accessor :: R.Position -> Parser Src.RawExpr
4952accessor start =
50− do dot
51− field <- lowVar
53+ do Symbol.dot
54+ field <- Var.lower
5255 end <- getPosition
53− let ann x = A.at start end x
54− let body = ann (Src.Access (ann (Src.var "r")) field)
55− return (mkLambda start end "r" body)
56+ return (A.at start end (Src.Accessor field))
5657
5758
5859variable :: R.Position -> Parser Src.RawExpr
5960variable start =
60− do var <- qualifiedVar
61+ do (maybePrefix, name) <- Var.foreignAlpha
6162 end <- getPosition
62− return (A.at start end (Src.var var))
63+ return (A.at start end (Src.Var maybePrefix name))
6364
6465
6566accessible :: R.Position -> Src.RawExpr -> Parser Src.RawExpr
6667accessible start expr =
6768 oneOf
68− [ do dot
69− field <- lowVar
69+ [ do Symbol.dot
70+ field <- Var.lower
7071 end <- getPosition
7172 let newExpr = A.at start end (Src.Access expr field)
7273 accessible start newExpr
@@ -80,14 +81,14 @@ accessible start expr =
8081
8182list :: R.Position -> Parser Src.RawExpr
8283list start =
83− do leftSquare
84+ do Symbol.leftSquare
8485 inContext start E.ExprList $
8586 do spaces
8687 oneOf
8788 [ do (entry, _, pos) <- expression
8889 checkSpace pos
8990 listHelp start [entry]
90− , do rightSquare
91+ , do Symbol.rightSquare
9192 end <- getPosition
9293 return (A.at start end (Src.List []))
9394 ]
@@ -96,12 +97,12 @@ list start =
9697listHelp :: R.Position -> [Src.RawExpr] -> Parser Src.RawExpr
9798listHelp start entries =
9899 oneOf
99− [ do comma
100+ [ do Symbol.comma
100101 spaces
101102 (entry, _, pos) <- expression
102103 checkSpace pos
103104 listHelp start (entry:entries)
104− , do rightSquare
105+ , do Symbol.rightSquare
105106 end <- getPosition
106107 return (A.at start end (Src.List (reverse entries)))
107108 ]
@@ -113,72 +114,50 @@ listHelp start entries =
113114
114115tuple :: R.Position -> Parser Src.RawExpr
115116tuple start =
116− do leftParen
117+ do Symbol.leftParen
117118 pos <- getPosition
118− spos <- whitespace
119+ spos <- W.whitespace
119120 inContext start E.ExprTuple $ oneOf $
120121 [ do noSpace pos spos
121− try (minus >> rightParen)
122+ try (Symbol.minus >> Symbol.rightParen)
122123 end <- getPosition
123− return $ A.at start end (Src.var "-")
124+ return $ A.at start end (Src.Op "-")
124125
125126 , do checkSpace spos
126127 (entry, _, spos2) <- expression
127128 checkSpace spos2
128− tupleHelp start [entry]
129+ tupleHelp start entry []
129130
130131 , do noSpace pos spos
131− op <- infixOp
132− rightParen
132+ op <- Symbol.binop
133+ Symbol.rightParen
133134 end <- getPosition
134− return $ A.at start end (Src.var op)
135+ return $ A.at start end (Src.Op op)
135136
136137 , do noSpace pos spos
137− rightParen
138+ Symbol.rightParen
138139 end <- getPosition
139− return (A.at start end (Src.tuple []))
140+ return (A.at start end Src.Unit)
140141
141− , do noSpace pos spos
142− comma
143− arity <- chompCommas 2
144− rightParen
145− end <- getPosition
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)
150142 ]
151143
152144
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)
156−
157−
158−chompCommas :: Int -> Parser Int
159−chompCommas n =
160− oneOf
161− [ comma >> chompCommas (n + 1)
162− , return n
163− ]
164−
165−
166−tupleHelp :: R.Position -> [Src.RawExpr] -> Parser Src.RawExpr
167−tupleHelp start entries =
145+tupleHelp :: R.Position -> Src.RawExpr -> [Src.RawExpr] -> Parser Src.RawExpr
146+tupleHelp start firstExpr revExprs =
168147 oneOf
169− [ do comma
148+ [ do Symbol.comma
170149 spaces
171150 (entry, _, pos) <- expression
172151 checkSpace pos
173− tupleHelp start (entry:entries)
174− , do rightParen
152+ tupleHelp start firstExpr (entry : revExprs)
153+ , do Symbol.rightParen
175154 end <- getPosition
176− case entries of
177− [entry] ->
178− return entry
155+ case reverse revExprs of
156+ [] ->
157+ return firstExpr
179158
180− _ ->
181− return (A.at start end (Src.tuple (reverse entries)))
159+ secondExpr : others ->
160+ return (A.at start end (Src.Tuple firstExpr secondExpr others))
182161 ]
183162
184163
@@ -188,23 +167,23 @@ tupleHelp start entries =
188167
189168record :: R.Position -> Parser Src.RawExpr
190169record start =
191− do leftCurly
170+ do Symbol.leftCurly
192171 inContext start E.ExprRecord $
193172 do spaces
194173 oneOf
195− [ do rightCurly
174+ [ do Symbol.rightCurly
196175 end <- getPosition
197176 return (A.at start end (Src.Record []))
198− , do starter <- addLocation lowVar
177+ , do starter <- addLocation Var.lower
199178 spaces
200179 oneOf
201− [ do pipe
180+ [ do Symbol.pipe
202181 spaces
203182 firstField <- chompField
204183 fields <- chompFields [firstField]
205184 end <- getPosition
206− return (A.at start end (Src.Update (A.map Src.var starter) fields))
207− , do equals
185+ return (A.at start end (Src.Update starter fields))
186+ , do Symbol.equals
208187 spaces
209188 (value, _, nextPos) <- expression
210189 checkSpace nextPos
@@ -221,20 +200,20 @@ type Field = ( A.Located Text, Src.RawExpr )
221200chompFields :: [Field] -> Parser [Field]
222201chompFields fields =
223202 oneOf
224− [ do comma
203+ [ do Symbol.comma
225204 spaces
226205 f <- chompField
227206 chompFields (f : fields)
228− , do rightCurly
207+ , do Symbol.rightCurly
229208 return (reverse fields)
230209 ]
231210
232211
233212chompField :: Parser Field
234213chompField =
235− do key <- addLocation lowVar
214+ do key <- addLocation Var.lower
236215 spaces
237− equals
216+ Symbol.equals
238217 spaces
239218 (value, _, pos) <- expression
240219 checkSpace pos
@@ -260,7 +239,7 @@ expression =
260239 , function start
261240 , do starter <- possiblyNegativeTerm start
262241 end <- getPosition
263− space <- whitespace
242+ space <- W.whitespace
264243 exprHelp start (State [] starter end space)
265244 ]
266245
@@ -282,17 +261,17 @@ exprHelp start (State ops lastExpr end pos) =
282261 do checkSpace pos
283262 arg <- term
284263 newEnd <- getPosition
285− newPos <- whitespace
264+ newPos <- W.whitespace
286265 let newLast = A.merge lastExpr arg (Src.App lastExpr arg)
287266 exprHelp start (State ops newLast newEnd newPos)
288267
289268 , -- infix operator
290269 do checkSpace pos
291270 opStart <- getPosition
292− opName <- infixOp
271+ opName <- Symbol.binop
293272 opEnd <- getPosition
294273 let op = A.at opStart opEnd opName
295− spos <- whitespace
274+ spos <- W.whitespace
296275 hint (E.AfterOpExpr opName) (checkSpace spos)
297276 newStart <- getPosition
298277 hint (E.AfterOpExpr opName) $ oneOf $
@@ -300,7 +279,7 @@ exprHelp start (State ops lastExpr end pos) =
300279 do guard ("-" == opName && end /= opStart && opEnd == newStart)
301280 rawTerm <- term
302281 newEnd <- getPosition
303− newPos <- whitespace
282+ newPos <- W.whitespace
304283
305284 let ann x = A.merge op rawTerm x
306285 let negatedTerm = ann (Src.Binop [(ann Src.zero, op)] rawTerm)
@@ -311,7 +290,7 @@ exprHelp start (State ops lastExpr end pos) =
311290 , -- term
312291 do newLast <- possiblyNegativeTerm newStart
313292 newEnd <- getPosition
314− newPos <- whitespace
293+ newPos <- W.whitespace
315294 let newOps = (lastExpr, op) : ops
316295 exprHelp start (State newOps newLast newEnd newPos)
317296
@@ -345,7 +324,7 @@ exprHelp start (State ops lastExpr end pos) =
345324possiblyNegativeTerm :: R.Position -> Parser Src.RawExpr
346325possiblyNegativeTerm start =
347326 oneOf
348− [ do minus
327+ [ do Symbol.minus
349328 expr <- term
350329 end <- getPosition
351330 let ann x = A.at start end x
@@ -360,7 +339,7 @@ possiblyNegativeTerm start =
360339
361340if_ :: R.Position -> ExprParser
362341if_ start =
363− do keyword "if"
342+ do Keyword.if_
364343 inContext start E.ExprIf $ ifHelp start []
365344
366345
@@ -369,15 +348,15 @@ ifHelp start branches =
369348 do spaces
370349 (condition, _, condPos) <- expression
371350 checkSpace condPos
372− keyword "then"
351+ Keyword.then_
373352 spaces
374353 (thenBranch, _, thenPos) <- expression
375354 hint E.ElseBranch $ checkSpace thenPos
376− hint E.ElseBranch $ keyword "else"
355+ hint E.ElseBranch $ Keyword.else_
377356 spaces
378357 let newBranches = (condition, thenBranch) : branches
379358 oneOf
380− [ do keyword "if"
359+ [ do Keyword.if_
381360 ifHelp start newBranches
382361 , do (elseBranch, elseEnd, elseSpace) <- expression
383362 let ifExpr = A.at start elseEnd (Src.If (reverse newBranches) elseBranch)
@@ -391,7 +370,7 @@ ifHelp start branches =
391370
392371function :: R.Position -> ExprParser
393372function start =
394− do lambda
373+ do Symbol.lambda
395374 inContext start E.ExprFunc $
396375 do spaces
397376 arg <- Pattern.term
@@ -409,7 +388,7 @@ gatherArgs args =
409388 [ do arg <- Pattern.term
410389 spaces
411390 gatherArgs (arg:args)
412− , do rightArrow
391+ , do Symbol.rightArrow
413392 return args
414393 ]
415394
@@ -420,12 +399,12 @@ gatherArgs args =
420399
421400case_ :: R.Position -> ExprParser
422401case_ start =
423− do keyword "case"
402+ do Keyword.case_
424403 inContext start E.ExprCase $
425404 do spaces
426405 (switcher, _, switcherPos) <- expression
427406 checkSpace switcherPos
428− keyword "of"
407+ Keyword.of_
429408 spaces
430409 oldIndent <- getIndent
431410 newIndent <- getCol
@@ -444,7 +423,7 @@ branchHelp :: SParser (P.Raw, Src.RawExpr)
444423branchHelp =
445424 do (pattern, patternPos) <- Pattern.expression
446425 checkSpace patternPos
447− rightArrow
426+ Symbol.rightArrow
448427 spaces
449428 (branchExpr, end, pos) <- expression
450429 return ( (pattern, branchExpr), end, pos )
@@ -468,7 +447,7 @@ let_ :: R.Position -> ExprParser
468447let_ start =
469448 do oldIndent <- getIndent
470449 letIndent <- getCol
471− keyword "let"
450+ Keyword.let_
472451 pushContext start E.ExprLet
473452 setIndent letIndent
474453 spaces
@@ -487,7 +466,7 @@ letHelp start oldIndent revDefs end pos =
487466
488467 , do setIndent oldIndent
489468 checkSpace pos
490− keyword "in"
469+ Keyword.in_
491470 popContext ()
492471 spaces
493472 (body, newEnd, newPos) <- expression
@@ -497,57 +476,62 @@ letHelp start oldIndent revDefs end pos =
497476
498477
499478
500−-- DEFINITIONS
479+-- LET DEFINITIONS
501480
502481
503482letDef :: SParser Src.RawDef
504483letDef =
505− definition $ \_ -> Pattern.term
484+ oneOf
485+ [ definition
486+ , destructure
487+ ]
488+
506489
507490
508−topLevelDef :: SParser Src.RawDef
509−topLevelDef =
510− definition $ \start ->
511− oneOf
512− [ do op <- try (leftParen >> infixOp)
513− rightParen
514− end <- getPosition
515− return (A.at start end (P.Var op))
516− , Pattern.term
517− ]
491+-- DEFINITION
518492
519493
520−definition :: (R.Position -> Parser P.Raw) -> SParser Src.RawDef
521−definition parseRoot =
494+definition :: SParser Src.RawDef
495+definition =
522496 do start <- getPosition
523− root <- parseRoot start
497+ name <- Var.lower
524498 spaces
525− case A.drop root of
526− P.Var name ->
527− oneOf
528− [ do hasType
529− inContext start (E.Annotation name) $
530− do spaces
531− (tipe, end, space) <- Type.expression
532− return ( A.at start end (Src.Annotation name tipe), end, space )
533− , inContext start (E.Definition name) $
534− definitionHelp start root []
535− ]
536−
537− _ ->
538− definitionHelp start root []
499+ oneOf
500+ [ do Symbol.hasType
501+ inContext start (E.Annotation name) $
502+ do spaces
503+ (tipe, end, space) <- Type.expression
504+ return ( A.at start end (Src.Annotation name tipe), end, space )
505+ , inContext start (E.Definition name) $
506+ definitionHelp start name []
507+ ]
539508
540509
541−definitionHelp :: R.Position -> P.Raw -> [P.Raw] -> SParser Src.RawDef
542−definitionHelp start root revArgs =
510+definitionHelp :: R.Position -> Text -> [P.Raw] -> SParser Src.RawDef
511+definitionHelp start name revArgs =
543512 oneOf
544513 [ do arg <- hint E.Arg Pattern.term
545514 spaces
546− definitionHelp start root (arg : revArgs)
547− , do equals
515+ definitionHelp start name (arg : revArgs)
516+ , do Symbol.equals
548517 spaces
549− (expr, 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)
518+ (body, end, space) <- expression
519+ let def = A.at start end (Src.Definition name (reverse revArgs) body)
552520 return ( def, end, space )
553521 ]
522+
523+
524+
525+-- DESTRUCTURE
526+
527+
528+destructure :: SParser Src.RawDef
529+destructure =
530+ do start <- getPosition
531+ pattern <- Pattern.term
532+ spaces
533+ Symbol.equals
534+ spaces
535+ (expr, end, space) <- expression
536+ let def = A.at start end (Src.Destructure pattern expr)
537+ return ( def, end, space )