1{-# OPTIONS_GHC -Wall -fno-warn-unused-do-bind #-}
2{-# LANGUAGE OverloadedStrings #-}
9import Control.Monad (guard)
11import qualified AST.Source as Src
12import qualified Elm.Name as N
13import Parse.Primitives
14import qualified Parse.Primitives.Keyword as Keyword
15import qualified Parse.Primitives.Number as Number
16import qualified Parse.Primitives.Symbol as Symbol
17import qualified Parse.Primitives.Utf8 as Utf8
18import qualified Parse.Primitives.Variable as Var
19import qualified Parse.Primitives.Whitespace as W
20import qualified Parse.Pattern as Pattern
21import qualified Parse.Shader as Shader
22import qualified Parse.Type as Type
23import qualified Reporting.Annotation as A
24import qualified Reporting.Error.Syntax as E
25import qualified Reporting.Region as R
32term :: Parser Src.Expr
35 do start <- getPosition
37 [ variable start >>= accessible start
42 , record start >>= accessible start
43 , tuple start >>= accessible start
49string :: R.Position -> Parser Src.Expr
53 return (A.at start end (Src.Str str))
56character :: R.Position -> Parser Src.Expr
58 do chr <- Utf8.character
60 return (A.at start end (Src.Chr chr))
63number :: R.Position -> Parser Src.Expr
65 do nmbr <- Number.number
67 return $ A.at start end $
76accessor :: R.Position -> Parser Src.Expr
81 return (A.at start end (Src.Accessor field))
84variable :: R.Position -> Parser Src.Expr
86 do var <- Var.foreignAlpha
88 return (A.at start end var)
91accessible :: R.Position -> Src.Expr -> Parser Src.Expr
92accessible start expr =
97 let newExpr = A.at start end (Src.Access expr field)
98 accessible start newExpr
107list :: R.Position -> Parser Src.Expr
110 inContext start E.ExprList $
113 [ do (entry, _, pos) <- expression
115 listHelp start [entry]
116 , do Symbol.rightSquare
118 return (A.at start end (Src.List []))
122listHelp :: R.Position -> [Src.Expr] -> Parser Src.Expr
123listHelp start entries =
127 (entry, _, pos) <- expression
129 listHelp start (entry:entries)
130 , do Symbol.rightSquare
132 return (A.at start end (Src.List (reverse entries)))
140tuple :: R.Position -> Parser Src.Expr
145 inContext start E.ExprTuple $ oneOf $
146 [ do noSpace pos spos
147 try (Symbol.minus >> Symbol.rightParen)
149 return $ A.at start end (Src.Op "-")
152 (entry, _, spos2) <- expression
154 tupleHelp start entry []
156 , do noSpace pos spos
160 return $ A.at start end (Src.Op op)
162 , do noSpace pos spos
165 return (A.at start end Src.Unit)
170tupleHelp :: R.Position -> Src.Expr -> [Src.Expr] -> Parser Src.Expr
171tupleHelp start firstExpr revExprs =
175 (entry, _, pos) <- expression
177 tupleHelp start firstExpr (entry : revExprs)
178 , do Symbol.rightParen
180 case reverse revExprs of
184 secondExpr : others ->
185 return (A.at start end (Src.Tuple firstExpr secondExpr others))
193record :: R.Position -> Parser Src.Expr
196 inContext start E.ExprRecord $
199 [ do Symbol.rightCurly
201 return (A.at start end (Src.Record []))
202 , do starter <- addLocation Var.lower
207 firstField <- chompField
208 fields <- chompFields [firstField]
210 return (A.at start end (Src.Update starter fields))
213 (value, _, nextPos) <- expression
215 fields <- chompFields [(starter, value)]
217 return (A.at start end (Src.Record fields))
222type Field = ( A.Located N.Name, Src.Expr )
225chompFields :: [Field] -> Parser [Field]
231 chompFields (f : fields)
232 , do Symbol.rightCurly
233 return (reverse fields)
237chompField :: Parser Field
239 do key <- addLocation Var.lower
243 (value, _, pos) <- expression
256expression :: ExprParser
259 do start <- getPosition
265 , do expr <- possiblyNegativeTerm start
267 space <- W.whitespace
268 exprHelp start (State [] expr [] end space)
274 { _ops :: ![(Src.Expr, A.Located N.Name)]
276 , _args :: ![Src.Expr]
277 , _end :: !R.Position
282exprHelp :: R.Position -> State -> ExprParser
283exprHelp start (State ops expr args end pos) =
289 newEnd <- getPosition
290 newPos <- W.whitespace
291 exprHelp start (State ops expr (arg:args) newEnd newPos)
295 opStart <- getPosition
296 opName <- Symbol.binop
298 let op = A.at opStart opEnd opName
300 hint (E.AfterOpExpr opName) (checkSpace spos)
301 newStart <- getPosition
302 hint (E.AfterOpExpr opName) $ oneOf $
304 do guard ("-" == opName && end /= opStart && opEnd == newStart)
306 newEnd <- getPosition
307 newPos <- W.whitespace
308 let arg = A.at opStart newEnd (Src.Negate rawTerm)
309 exprHelp start (State ops expr (arg:args) newEnd newPos)
312 do newExpr <- possiblyNegativeTerm newStart
313 newEnd <- getPosition
314 newPos <- W.whitespace
315 let newOps = (toCall expr args, op) : ops
316 exprHelp start (State newOps newExpr [] newEnd newPos)
319 do (newLast, newEnd, newPos) <-
326 let newOps = (toCall expr args, op) : ops
327 let finalExpr = A.at start newEnd (Src.Binops (reverse newOps) newLast)
328 return ( finalExpr, newEnd, newPos )
332 let finalExpr = toCall expr args in
335 return ( finalExpr, end, pos )
338 return ( A.at start end (Src.Binops (reverse ops) finalExpr), end, pos )
342possiblyNegativeTerm :: R.Position -> Parser Src.Expr
343possiblyNegativeTerm start =
348 return (A.at start end (Src.Negate expr))
353toCall :: Src.Expr -> [Src.Expr] -> Src.Expr
360 A.merge func lastArg (Src.Call func (reverse revArgs))
367if_ :: R.Position -> ExprParser
370 inContext start E.ExprIf $ ifHelp start []
373ifHelp :: R.Position -> [(Src.Expr, Src.Expr)] -> ExprParser
374ifHelp start branches =
376 (condition, _, condPos) <- expression
380 (thenBranch, _, thenPos) <- expression
381 hint E.ElseBranch $ checkSpace thenPos
382 hint E.ElseBranch $ Keyword.else_
384 let newBranches = (condition, thenBranch) : branches
387 ifHelp start newBranches
388 , do (elseBranch, elseEnd, elseSpace) <- expression
389 let ifExpr = A.at start elseEnd (Src.If (reverse newBranches) elseBranch)
390 return ( ifExpr, elseEnd, elseSpace )
398function :: R.Position -> ExprParser
401 inContext start E.ExprFunc $
405 revArgs <- gatherArgs [arg]
407 (body, end, space) <- expression
408 let func = A.at start end (Src.Lambda (reverse revArgs) body)
409 return ( func, end, space )
412gatherArgs :: [Src.Pattern] -> Parser [Src.Pattern]
415 [ do arg <- Pattern.term
417 gatherArgs (arg:args)
418 , do Symbol.rightArrow
427case_ :: R.Position -> ExprParser
430 inContext start E.ExprCase $
432 (switcher, _, switcherPos) <- expression
433 checkSpace switcherPos
436 oldIndent <- getIndent
439 (firstBranch, firstEnd, firstPos) <- branchHelp
440 (branches, end, pos) <- caseHelp [firstBranch] firstEnd firstPos
443 ( A.at start end (Src.Case switcher branches)
449branchHelp :: SParser (Src.Pattern, Src.Expr)
451 do (pattern, patternPos) <- Pattern.expression
452 checkSpace patternPos
455 (branchExpr, end, pos) <- expression
456 return ( (pattern, branchExpr), end, pos )
459caseHelp :: [(Src.Pattern, Src.Expr)] -> R.Position -> SPos -> SParser [(Src.Pattern, Src.Expr)]
460caseHelp branches end pos =
462 [ do checkAligned pos
463 (branch, newEnd, newPos) <- branchHelp
464 caseHelp (branch:branches) newEnd newPos
465 , return ( reverse branches, end, pos )
473let_ :: R.Position -> ExprParser
475 do oldIndent <- getIndent
478 pushContext start E.ExprLet
483 (def, end, space) <- letDef
484 letHelp start oldIndent [def] end space
487letHelp :: R.Position -> Int -> [A.Located Src.Def] -> R.Position -> SPos -> ExprParser
488letHelp start oldIndent revDefs end pos =
490 [ do checkAligned pos
491 (def, newEnd, newPos) <- letDef
492 letHelp start oldIndent (def:revDefs) newEnd newPos
494 , do setIndent oldIndent
499 (body, newEnd, newPos) <- expression
500 let letExpr = A.at start end (Src.Let (reverse revDefs) body)
501 return ( letExpr, newEnd, newPos )
509letDef :: SParser (A.Located Src.Def)
521definition :: SParser (A.Located Src.Def)
523 do start <- getPosition
525 nameEnd <- getPosition
529 inContext start (E.Annotation name) $
531 (tipe, end, space) <- Type.expression
532 return ( A.at start end (Src.Annotate name tipe), end, space )
533 , inContext start (E.Definition name) $
534 definitionHelp start (A.at start nameEnd name) []
538definitionHelp :: R.Position -> A.Located N.Name -> [Src.Pattern] -> SParser (A.Located Src.Def)
539definitionHelp start name revArgs =
541 [ do arg <- hint E.Arg Pattern.term
543 definitionHelp start name (arg : revArgs)
546 (body, end, space) <- expression
547 let def = A.at start end (Src.Define name (reverse revArgs) body)
548 return ( def, end, space )
556destructure :: SParser (A.Located Src.Def)
558 do start <- getPosition
559 pattern <- Pattern.term
563 (expr, end, space) <- expression
564 return ( A.at start end (Src.Destruct pattern expr), end, space )
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list