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 Data.Monoid ((<>))
14import qualified Data.Set as Set
15import qualified Data.Text as Text
16import Data.Word (Word8)
19import qualified AST.Optimized as Opt
20import qualified AST.Source as Src
21import qualified AST.Module.Name as ModuleName
22import qualified Elm.Name as N
23import qualified Elm.Package as Pkg
24import Parse.Primitives (Parser, run)
25import qualified Parse.Primitives.Kernel as K
26import qualified Parse.Primitives.Symbol as Symbol
27import qualified Parse.Module as Module
28import qualified Reporting.Annotation as A
29import qualified Reporting.Error as E
37 Map.Map N.Name [Pkg.Name]
40parse :: ImportDict -> B.ByteString -> Either E.Error Opt.KContent
41parse importDict sourceCode =
42 case run (parser importDict) sourceCode of
50parser :: ImportDict -> Parser Opt.KContent
52 do Symbol.jsMultiCommentOpen
54 imports <- Module.chompImports []
55 Symbol.jsMultiCommentClose
57 let (State vtable deps) = processImports importDict imports
59 chunks <- chompChunks vtable Map.empty Map.empty []
61 return $ Opt.KContent chunks deps
69 Map.Map Text.Text Opt.KChunk
73 State VarTable (Set.Set Opt.Global)
76processImports :: ImportDict -> [Src.Import] -> State
77processImports importDict imports =
78 List.foldl' (addImport importDict) (State Map.empty Set.empty) imports
81addImport :: ImportDict -> State -> Src.Import -> State
82addImport importDict state (Src.Import (A.At _ home) maybeAlias exposing) =
83 if ModuleName.isKernel home then
86 error ("Cannot use aliases on kernel import of: " ++ show home)
89 addKernelImport (ModuleName.getKernel home) exposing state
92 case Map.lookup home importDict of
95 canonicalHome = ModuleName.Canonical pkg home
96 prefix = toPrefix home maybeAlias
98 addNormalImport canonicalHome prefix exposing state
101 error ("Cannot find kernel import of: " ++ show home)
104-- INVARIANT: the `home` is the * in `Elm.Kernel.*`
106addKernelImport :: N.Name -> Src.Exposing -> State -> State
107addKernelImport home exposing (State vtable deps) =
110 Map.insert (home <> "_" <> name) (Opt.JsVar home name) table
113 (List.foldl' addVar vtable (toNames exposing))
114 (Set.insert (Opt.kernel home) deps)
117addNormalImport :: ModuleName.Canonical -> N.Name -> Src.Exposing -> State -> State
118addNormalImport home prefix exposing state =
120 addVar (State vtable deps) name =
122 (Map.insert (prefix <> "_" <> name) (Opt.ElmVar home name) vtable)
123 (Set.insert (Opt.Global home name) deps)
125 List.foldl' addVar state (toNames exposing)
128toPrefix :: N.Name -> Maybe N.Name -> N.Name
129toPrefix home maybeAlias =
135 if Text.isInfixOf "." home then
136 error ("kernel imports with dots need an alias: " ++ show home)
140toNames :: Src.Exposing -> [N.Name]
144 error "Cannot have `exposing (..)` in kernel code."
146 Src.Explicit exposedList ->
147 map toName exposedList
150toName :: A.Located Src.Exposed -> N.Name
151toName (A.At _ exposed) =
156 Src.Upper name Src.Private ->
159 Src.Upper _ Src.Public ->
160 error "cannot have Maybe(..) syntax in kernel code header"
163 error "cannot use binops in kernel code"
170chompChunks :: VarTable -> Enums -> Fields -> [Opt.KChunk] -> Parser [Opt.KChunk]
171chompChunks vtable enums fields chunks =
172 do (javascript, maybeTag) <- K.chunk
175 return (Opt.JS javascript : chunks)
180 chompChunks vtable enums fields $
181 Opt.Prod : Opt.JS javascript : chunks
184 chompChunks vtable enums fields $
185 Opt.Debug : Opt.JS javascript : chunks
188 case Map.lookup var vtable of
190 error ("Bad kernel symbol: " ++ Text.unpack var)
193 chompChunks vtable enums fields $
194 chunk : Opt.JS javascript : chunks
197 let (enum, newEnums) = lookupEnum n var enums in
198 chompChunks vtable newEnums fields $
199 Opt.Enum enum : Opt.JS javascript : chunks
202 chompChunks vtable enums fields $
203 Opt.ElmField name : Opt.JS javascript : chunks
206 let (field, newFields) = lookupField name fields in
207 chompChunks vtable enums newFields $
208 Opt.JsField field : Opt.JS javascript : chunks
216 Map.Map Text.Text Int
219lookupField :: Text.Text -> Fields -> (Int, Fields)
220lookupField name fields =
221 case Map.lookup name fields of
226 let n = Map.size fields in
227 ( n, Map.insert name n fields )
235 Map.Map Word8 (Map.Map N.Name Int)
238lookupEnum :: Word8 -> N.Name -> Enums -> (Int, Enums)
239lookupEnum word var allEnums =
242 Map.findWithDefault Map.empty word allEnums
244 case Map.lookup var enums of
249 let n = Map.size enums in
250 ( 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