1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
14import qualified Data.ByteString as B
15import qualified Data.Name as Name
17import qualified AST.Source as Src
18import qualified Elm.Compiler.Imports as Imports
19import qualified Elm.Package as Pkg
20import qualified Parse.Declaration as Decl
21import qualified Parse.Keyword as Keyword
22import qualified Parse.Symbol as Symbol
23import qualified Parse.Variable as Var
24import qualified Parse.Primitives as P
25import Parse.Primitives hiding (Parser, State, fromByteString)
27import qualified Reporting.Annotation as A
28import qualified Reporting.Error.Syntax as E
29import qualified Reporting.Result as Result
36fromByteString :: Pkg.Name -> B.ByteString -> Result.Result i w E.Error Src.Module
37fromByteString pkg source =
40 | pkg == Pkg.core = core
41 | Pkg.isKernel pkg = platform
44 case P.fromByteString parser source of
47 Right modul -> Result.ok modul
48 Left err -> Result.throw err
50 P.Err row col ctx err ->
51 Result.throw (E.ParseError row col ctx err)
58normal :: Parser (Either E.Error Src.Module)
62 imports <- chompImports []
63 decls <- chompDecls []
65 return (checkModule header (Imports.addDefaults imports) [] decls)
68core :: Parser (Either E.Error Src.Module)
72 imports <- chompImports []
73 binops <- chompBinops []
74 decls <- chompDecls []
76 return (checkModule header imports binops decls)
79platform :: Parser (Either E.Error Src.Module)
83 imports <- chompImports []
84 binops <- chompBinops []
85 decls <- chompDecls []
87 return (checkModule header (Imports.addDefaults imports) binops decls)
94checkModule :: Maybe Header -> [Src.Import] -> [A.Located Src.Binop] -> [Decl.Decl] -> Either E.Error Src.Module
95checkModule maybeHeader imports binops decls =
97 (Header name effects exports) = maybe (Header "Main" NoEffects (A.At A.one Src.Open)) id maybeHeader
98 (values, unions, aliases, ports) = categorizeDecls [] [] [] [] decls
100 Src.Module name exports imports values unions aliases binops
101 <$> checkEffects ports effects
104checkEffects :: [Src.Port] -> Effects -> Either E.Error Src.Effects
105checkEffects ports effects =
109 [] -> Right Src.NoEffects
110 _:_ -> Left (error "TODO no ports")
114 [] -> Left (error "TODO no ports in port module" region)
115 _:_ -> Right (Src.Ports ports)
117 Manager region manager ->
119 [] -> Right (Src.Manager region manager)
120 _:_ -> Left (error "TODO ports in effect manager")
123categorizeDecls :: [A.Located Src.Value] -> [A.Located Src.Union] -> [A.Located Src.Alias] -> [Src.Port] -> [Decl.Decl] -> ( [A.Located Src.Value], [A.Located Src.Union], [A.Located Src.Alias], [Src.Port] )
124categorizeDecls values unions aliases ports decls =
127 (values, unions, aliases, ports)
131 Decl.Value value -> categorizeDecls (value:values) unions aliases ports otherDecls
132 Decl.Union union -> categorizeDecls values (union:unions) aliases ports otherDecls
133 Decl.Alias alias -> categorizeDecls values unions (alias:aliases) ports otherDecls
134 Decl.Port port_ -> categorizeDecls values unions aliases (port_:ports) otherDecls
141freshLine :: Parser ()
143 checkFreshLine =<< whitespace
146endOfFile :: Parser ()
148 P.Parser $ \state@(P.State pos end _ row col ctx) _ eok _ eerr ->
150 eerr row col ctx E.EndOfFile
159chompDecls :: [Decl.Decl] -> Parser [Decl.Decl]
161 do (decl, _, pos) <- Decl.declaration
163 [ do checkFreshLine pos
164 chompDecls (decl:decls)
165 , return (reverse (decl:decls))
169chompBinops :: [A.Located Src.Binop] -> Parser [A.Located Src.Binop]
172 [ do binop <- Decl.infix_
173 chompBinops (binop:binops)
183 Header Name.Name Effects (A.Located Src.Exposing)
189 | Manager A.Region Src.Manager
192chompHeader :: Parser (Maybe Header)
194 do start <- getPosition
197 -- module MyThing exposing (..)
199 pushContext start E.Module
201 name <- Var.moduleName
205 exports <- addLocation exposing
208 return (Just (Header name NoEffects exports))
210 -- port module MyThing exposing (..)
212 pushContext start E.Module
217 name <- Var.moduleName
221 exports <- addLocation exposing
224 return (Just (Header name (Ports (A.Region start end)) exports))
226 -- effect module MyThing where { command = MyCmd } exposing (..)
228 pushContext start E.Module
233 name <- Var.moduleName
237 manager <- chompManager
241 exports <- addLocation exposing
244 return (Just (Header name (Manager (A.Region start end) manager) exports))
251chompManager :: Parser Src.Manager
253 do word1 0x7B {- { -} E.XXX
256 [ do cmd <- chompCommand
259 [ do word1 0x7D {-}-} E.XXX
262 , do word1 0x2C {-,-} E.XXX
264 sub <- chompSubscription
266 word1 0x7D {-}-} E.XXX
268 return (Src.Fx cmd sub)
270 , do sub <- chompSubscription
273 [ do word1 0x7D {-}-} E.XXX
276 , do word1 0x2C {-,-} E.XXX
280 word1 0x7D {-}-} E.XXX
282 return (Src.Fx cmd sub)
287chompCommand :: Parser (A.Located Name.Name)
291 word1 0x3D {-=-} E.XXX
293 addLocation Var.upper
296chompSubscription :: Parser (A.Located Name.Name)
298 do Keyword.subscription_
300 word1 0x3D {-=-} E.XXX
302 addLocation Var.upper
309chompImports :: [Src.Import] -> Parser [Src.Import]
310chompImports imports =
312 [ do start <- getPosition
314 pushContext start E.Import
316 name <- addLocation Var.moduleName
319 [ do checkFreshLine pos
322 Src.Import name Nothing (Src.Explicit []) : imports
325 [ chompAs name imports
326 , chompExposing name Nothing imports
329 , return (reverse imports)
333chompAs :: A.Located Name.Name -> [Src.Import] -> Parser [Src.Import]
334chompAs name imports =
340 [ do checkFreshLine pos
343 Src.Import name (Just alias) (Src.Explicit []) : imports
345 chompExposing name (Just alias) imports
349chompExposing :: A.Located Name.Name -> Maybe Name.Name -> [Src.Import] -> Parser [Src.Import]
350chompExposing name maybeAlias imports =
357 Src.Import name maybeAlias exposed : imports
364exposing :: Parser Src.Exposing
366 do word1 0x28 {-(-} E.XXX
369 [ do word2 0x2E 0x2E {-..-} E.XXX
371 word1 0x29 {-)-} E.XXX
373 , do entry <- addLocation chompEntry
379exposingHelp :: [A.Located Src.Exposed] -> Parser Src.Exposing
380exposingHelp revEntries =
382 [ do word1 0x2C {-,-} E.XXX
384 entry <- addLocation chompEntry
386 exposingHelp (entry:revEntries)
387 , do word1 0x29 {-)-} E.XXX
388 return (Src.Explicit (reverse revEntries))
392chompEntry :: Parser Src.Exposed
395 [ Src.Lower <$> Var.lower
396 , do word1 0x28 {-(-} E.XXX
398 word1 0x29 {-)-} E.XXX
399 return (Src.Operator op)
400 , do name <- Var.upper
402 Src.Upper name <$> privacy
406privacy :: Parser Src.Privacy
409 [ do word1 0x28 {-(-} E.XXX
411 word2 0x2E 0x2E {-..-} E.XXX
413 word1 0x29 {-)-} E.XXX
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