1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
10import qualified Data.ByteString as B
11import qualified Data.List as List
12import qualified Data.Map as Map
13import qualified Data.Set as Set
14import Data.Word (Word8)
17import qualified AST.Optimized as Opt
18import qualified AST.Source as Src
19import qualified AST.Module.Name as ModuleName
20import qualified Elm.Name as N
21import qualified Elm.Package as Pkg
22import Parse.Primitives (Parser, run)
23import qualified Parse.Primitives.Kernel as K
24import qualified Parse.Primitives.Symbol as Symbol
25import qualified Parse.Module as Module
26import qualified Reporting.Annotation as A
27import qualified Reporting.Error as E
35 Map.Map N.Name [Pkg.Name]
38parse :: ImportDict -> B.ByteString -> Either E.Error Opt.KContent
39parse importDict sourceCode =
40 case run (parser importDict) sourceCode of
48parser :: ImportDict -> Parser Opt.KContent
50 do Symbol.jsMultiCommentOpen
52 imports <- Module.chompImports []
53 Symbol.jsMultiCommentClose
55 let (State vtable deps) = processImports importDict imports
57 chunks <- chompChunks vtable Map.empty Map.empty []
59 return $ Opt.KContent chunks deps
67 Map.Map N.Name Opt.KChunk
71 State VarTable (Set.Set Opt.Global)
74processImports :: ImportDict -> [Src.Import] -> State
75processImports importDict imports =
76 List.foldl' (addImport importDict) (State Map.empty Set.empty) imports
79addImport :: ImportDict -> State -> Src.Import -> State
80addImport importDict state (Src.Import (A.At _ home) maybeAlias exposing) =
81 if ModuleName.isKernel home then
84 error ("Cannot use aliases on kernel import of: " ++ N.toString home)
87 addKernelImport (ModuleName.getKernel home) exposing state
90 case Map.lookup home importDict of
93 canonicalHome = ModuleName.Canonical pkg home
94 prefix = toPrefix home maybeAlias
96 addNormalImport canonicalHome prefix exposing state
99 error ("Cannot find kernel import of: " ++ N.toString home)
102-- INVARIANT: the `home` is the * in `Elm.Kernel.*`
104addKernelImport :: N.Name -> Src.Exposing -> State -> State
105addKernelImport home exposing (State vtable deps) =
108 Map.insert (N.sepBy 0x5F {- _ -} home name) (Opt.JsVar home name) table
111 (List.foldl' addVar vtable (toNames exposing))
112 (Set.insert (Opt.kernel home) deps)
115addNormalImport :: ModuleName.Canonical -> N.Name -> Src.Exposing -> State -> State
116addNormalImport home prefix exposing state =
118 addVar (State vtable deps) name =
120 (Map.insert (N.sepBy 0x5F {- _ -} prefix name) (Opt.ElmVar home name) vtable)
121 (Set.insert (Opt.Global home name) deps)
123 List.foldl' addVar state (toNames exposing)
126toPrefix :: N.Name -> Maybe N.Name -> N.Name
127toPrefix home maybeAlias =
133 if N.contains 0x2E {- . -} home then
134 error ("kernel imports with dots need an alias: " ++ show (N.toString home))
138toNames :: Src.Exposing -> [N.Name]
142 error "Cannot have `exposing (..)` in kernel code."
144 Src.Explicit exposedList ->
145 map toName exposedList
148toName :: A.Located Src.Exposed -> N.Name
149toName (A.At _ exposed) =
154 Src.Upper name Src.Private ->
157 Src.Upper _ Src.Public ->
158 error "cannot have Maybe(..) syntax in kernel code header"
161 error "cannot use binops in kernel code"
168chompChunks :: VarTable -> Enums -> Fields -> [Opt.KChunk] -> Parser [Opt.KChunk]
169chompChunks vtable enums fields chunks =
170 do (javascript, maybeTag) <- K.chunk
173 return (Opt.JS javascript : chunks)
178 chompChunks vtable enums fields $
179 Opt.Prod : Opt.JS javascript : chunks
182 chompChunks vtable enums fields $
183 Opt.Debug : Opt.JS javascript : chunks
186 case Map.lookup var vtable of
188 error ("Bad kernel symbol: " ++ N.toString var)
191 chompChunks vtable enums fields $
192 chunk : Opt.JS javascript : chunks
195 let (enum, newEnums) = lookupEnum n var enums in
196 chompChunks vtable newEnums fields $
197 Opt.JsEnum enum : Opt.JS javascript : chunks
200 chompChunks vtable enums fields $
201 Opt.ElmField name : Opt.JS javascript : chunks
204 let (field, newFields) = lookupField name fields in
205 chompChunks vtable enums newFields $
206 Opt.JsField field : Opt.JS javascript : chunks
217lookupField :: N.Name -> Fields -> (Int, Fields)
218lookupField name fields =
219 case Map.lookup name fields of
224 let n = Map.size fields in
225 ( n, Map.insert name n fields )
233 Map.Map Word8 (Map.Map N.Name Int)
236lookupEnum :: Word8 -> N.Name -> Enums -> (Int, Enums)
237lookupEnum word var allEnums =
240 Map.findWithDefault Map.empty word allEnums
242 case Map.lookup var enums of
247 let n = Map.size enums in
248 ( n, Map.insert word (Map.insert var n enums) allEnums )
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