on master help sign in
Parse "effect module" and "foreign effect module" headers
50a14caEvan Czaplicki
src/AST/Module.hs+14−6
@@ -3,7 +3,7 @@ module AST.Module
3 , Types, Aliases, Unions
3 , Types, Aliases, Unions
4 , UnionInfo, CanonicalUnion
4 , UnionInfo, CanonicalUnion
5 , SourceModule, ValidModule, CanonicalModule, Optimized
5 , SourceModule, ValidModule, CanonicalModule, Optimized
6− , Module(..), Body(..)
6+ , Module(..), Kind(..), Body(..)
7 , Header(..)
7 , Header(..)
8 , Interface(..), toInterface
8 , Interface(..), toInterface
9 , UserImport, DefaultImport, ImportMethod(..)
9 , UserImport, DefaultImport, ImportMethod(..)
@@ -82,15 +82,22 @@ type Optimized =
82
82
83data Module docs imports exports body =
83data Module docs imports exports body =
84 Module
84 Module
85+ { kind :: Kind
85− { name :: Name.Canonical
86+ , name :: Name.Canonical
86− , path :: FilePath
87+ , path :: FilePath
87− , docs :: A.Located (Maybe docs)
88+ , docs :: A.Located (Maybe docs)
88 , exports :: exports
89 , exports :: exports
89 , imports :: imports
90 , imports :: imports
90− , body :: body
91+ , body :: body
91 }
92 }
92
93
93
94
95+data Kind
96+ = Normal
97+ | Effect
98+ | Foreign
99+
100+
94data Body expr =
101data Body expr =
95 Body
102 Body
96 { program :: expr
103 { program :: expr
@@ -108,7 +115,8 @@ data Body expr =
108{-| Basic info needed to identify modules and determine dependencies. -}
115{-| Basic info needed to identify modules and determine dependencies. -}
109data Header imports =
116data Header imports =
110 Header
117 Header
118+ { _kind :: Kind
111− { _name :: Name.Raw
119+ , _name :: Name.Raw
112 , _docs :: A.Located (Maybe String)
120 , _docs :: A.Located (Maybe String)
113 , _exports :: Var.Listing (A.Located Var.Value)
121 , _exports :: Var.Listing (A.Located Var.Value)
114 , _imports :: imports
122 , _imports :: imports
src/Canonicalize.hs+2−2
@@ -76,7 +76,7 @@ moduleHelp
76 -> Module.Interfaces
76 -> Module.Interfaces
77 -> Module.ValidModule
77 -> Module.ValidModule
78 -> Result.ResultErr (Env.Environment, AlmostCanonicalModule)
78 -> Result.ResultErr (Env.Environment, AlmostCanonicalModule)
79−moduleHelp importDict interfaces modul@(Module.Module _ _ comment exports _ decls) =
79+moduleHelp importDict interfaces modul@(Module.Module _ _ _ comment exports _ decls) =
80 canonicalModule
80 canonicalModule
81 <$> canonicalDeclsResult
81 <$> canonicalDeclsResult
82 <*> resolveExports locals exports
82 <*> resolveExports locals exports
@@ -127,7 +127,7 @@ filterImports
127 :: Set.Set ModuleName.Raw
127 :: Set.Set ModuleName.Raw
128 -> AlmostCanonicalModule
128 -> AlmostCanonicalModule
129 -> R.Result Warning.Warning e Module.CanonicalModule
129 -> R.Result Warning.Warning e Module.CanonicalModule
130−filterImports uses modul@(Module.Module _ _ _ _ (defaults, imports) _) =
130+filterImports uses modul@(Module.Module _ _ _ _ _ (defaults, imports) _) =
131 do reducedImports <-
131 do reducedImports <-
132 Maybe.catMaybes <$> T.traverse checkImport imports
132 Maybe.catMaybes <$> T.traverse checkImport imports
133
133
src/Canonicalize/Setup.hs+1−1
@@ -30,7 +30,7 @@ environment
30 -> Module.Interfaces
30 -> Module.Interfaces
31 -> Module.ValidModule
31 -> Module.ValidModule
32 -> Result.ResultErr Env.Environment
32 -> Result.ResultErr Env.Environment
33−environment importDict interfaces (Module.Module name _ _ _ (defaults, imports) decls) =
33+environment importDict interfaces (Module.Module _ name _ _ _ (defaults, imports) decls) =
34 let
34 let
35 allImports =
35 allImports =
36 imports ++ map (A.A (error "default import not found")) defaults
36 imports ++ map (A.A (error "default import not found")) defaults
src/Elm/Compiler.hs+1−1
@@ -53,7 +53,7 @@ parseDependencies sourceCode =
53 Result.Err msgs ->
53 Result.Err msgs ->
54 Left $ map (Error . A.map Error.Syntax) msgs
54 Left $ map (Error . A.map Error.Syntax) msgs
55
55
56− Result.Ok (Module.Header name _docs _exports imports) ->
56+ Result.Ok (Module.Header _kind name _docs _exports imports) ->
57 Right
57 Right
58 ( PublicModule.Name name
58 ( PublicModule.Name name
59 , map (PublicModule.Name . fst . A.drop) imports
59 , map (PublicModule.Name . fst . A.drop) imports
src/Optimize.hs+1−1
@@ -24,7 +24,7 @@ import qualified Reporting.Region as R
24
24
25
25
26optimize :: DT.VariantDict -> Module.CanonicalModule -> Module.Optimized
26optimize :: DT.VariantDict -> Module.CanonicalModule -> Module.Optimized
27−optimize variantDict module_@(Module.Module home _ _ _ _ body) =
27+optimize variantDict module_@(Module.Module _ home _ _ _ _ body) =
28 let
28 let
29 (defs, _) =
29 (defs, _) =
30 flattenLets [] (Module.program body)
30 flattenLets [] (Module.program body)
src/Parse/Module.hs+39−14
@@ -11,44 +11,69 @@ import Reporting.Annotation as A
11
11
12getModuleName :: String -> Maybe String
12getModuleName :: String -> Maybe String
13getModuleName source =
13getModuleName source =
14− case iParse getModuleName source of
14+ let
15− Right name ->
16− Just name
17−
18− Left _ ->
19− Nothing
20− where
21 getModuleName =
15 getModuleName =
22 do optional freshLine
16 do optional freshLine
23− (names, _) <- moduleDecl
17+ (_, names, _) <- moduleDecl
24 return (ModuleName.toString names)
18 return (ModuleName.toString names)
19+ in
20+ case iParse getModuleName source of
21+ Right name ->
22+ Just name
23+
24+ Left _ ->
25+ Nothing
25
26
26
27
27header :: IParser (Module.Header [Module.UserImport])
28header :: IParser (Module.Header [Module.UserImport])
28header =
29header =
29 do optional freshLine
30 do optional freshLine
30− (names, exports) <-
31+ (kind, names, exports) <-
32+ option
33+ (Module.Normal, ["Main"], Var.openListing)
31− option (["Main"], Var.openListing) (moduleDecl `followedBy` freshLine)
34+ (moduleDecl `followedBy` freshLine)
35+
32 docs <-
36 docs <-
33 choice
37 choice
34 [ addLocation (Just <$> docComment) `followedBy` freshLine
38 [ addLocation (Just <$> docComment) `followedBy` freshLine
35 , addLocation (return Nothing)
39 , addLocation (return Nothing)
36 ]
40 ]
41+
37 imports' <- imports
42 imports' <- imports
43+
38− return (Module.Header names docs exports imports')
44+ return (Module.Header kind names docs exports imports')
39
45
40
46
41−moduleDecl :: IParser ([String], Var.Listing (A.Located Var.Value))
47+moduleDecl :: IParser (Module.Kind, [String], Var.Listing (A.Located Var.Value))
42moduleDecl =
48moduleDecl =
43 expecting "a module declaration" $
49 expecting "a module declaration" $
50+ do
51+ kind <-
52+ choice
44− do try (reserved "module")
53+ [ do try (reserved "module")
54+ return Module.Normal
55+ , do try (reserved "effect")
56+ whitespace
57+ reserved "module"
58+ return Module.Effect
59+ , do reserved "foreign"
60+ whitespace
61+ reserved "effect"
62+ whitespace
63+ reserved "module"
64+ return Module.Foreign
65+ ]
66+
45 whitespace
67 whitespace
46 names <- dotSep1 capVar <?> "the name of this module"
68 names <- dotSep1 capVar <?> "the name of this module"
69+
47 whitespace
70 whitespace
48 exports <- option Var.openListing (listing (addLocation value))
71 exports <- option Var.openListing (listing (addLocation value))
72+
49 whitespace
73 whitespace
50 reserved "where"
74 reserved "where"
75+
51− return (names, exports)
76+ return (kind, names, exports)
52
77
53
78
54imports :: IParser [Module.UserImport]
79imports :: IParser [Module.UserImport]
src/Parse/Parse.hs+11−5
@@ -20,13 +20,14 @@ import qualified Reporting.Result as Result
20import qualified Validate
20import qualified Validate
21
21
22
22
23+
23program
24program
24 :: Package.Name
25 :: Package.Name
25 -> OpTable
26 -> OpTable
26 -> String
27 -> String
27 -> Result.Result wrn Error.Error M.ValidModule
28 -> Result.Result wrn Error.Error M.ValidModule
28program pkgName table src =
29program pkgName table src =
29− do (M.Module name filePath docs exports imports sourceDecls) <-
30+ do (M.Module kind name filePath docs exports imports sourceDecls) <-
30 parseWithTable table src (programParser pkgName)
31 parseWithTable table src (programParser pkgName)
31
32
32 validDecls <- Validate.declarations sourceDecls
33 validDecls <- Validate.declarations sourceDecls
@@ -37,14 +38,16 @@ program pkgName table src =
37 , imports
38 , imports
38 )
39 )
39
40
40− return (M.Module name filePath docs exports ammendedImports validDecls)
41+ return (M.Module kind name filePath docs exports ammendedImports validDecls)
42+
41
43
42
44
43-- HEADERS AND DECLARATIONS
45-- HEADERS AND DECLARATIONS
44
46
47+
45programParser :: Package.Name -> IParser M.SourceModule
48programParser :: Package.Name -> IParser M.SourceModule
46programParser pkgName =
49programParser pkgName =
47− do (M.Header name docs exports imports) <- Module.header
50+ do (M.Header kind name docs exports imports) <- Module.header
48 decls <- declarations
51 decls <- declarations
49 _ <- many (spaces <|> newline)
52 _ <- many (spaces <|> newline)
50 eof
53 eof
@@ -52,7 +55,7 @@ programParser pkgName =
52 let canonicalName =
55 let canonicalName =
53 ModuleName.Canonical pkgName name
56 ModuleName.Canonical pkgName name
54
57
55− return $ M.Module canonicalName "" docs exports imports decls
58+ return $ M.Module kind canonicalName "" docs exports imports decls
56
59
57
60
58declarations :: IParser [D.SourceDecl]
61declarations :: IParser [D.SourceDecl]
@@ -68,8 +71,10 @@ freshDef =
68 Decl.declaration
71 Decl.declaration
69
72
70
73
74+
71-- RUN PARSERS
75-- RUN PARSERS
72
76
77+
73parse :: String -> IParser a -> Result.Result wrn Error.Error a
78parse :: String -> IParser a -> Result.Result wrn Error.Error a
74parse source parser =
79parse source parser =
75 case iParse parser source of
80 case iParse parser source of
@@ -101,6 +106,7 @@ parseWithTable table source parser =
101
106
102-- INFIX INFO
107-- INFIX INFO
103
108
109+
104makeInfixTable
110makeInfixTable
105 :: Map.Map String (Int, D.Assoc)
111 :: Map.Map String (Int, D.Assoc)
106 -> [(String, InfixInfo)]
112 -> [(String, InfixInfo)]
@@ -142,4 +148,4 @@ parseFixities =
142data InfixInfo = InfixInfo
148data InfixInfo = InfixInfo
143 { _region :: R.Region
149 { _region :: R.Region
144 , _info :: (Int, D.Assoc)
150 , _info :: (Int, D.Assoc)
145− }
151+ }