@@ -2,8 +2,6 @@
2module Transform.Canonicalize (module', filterExports) where
2module Transform.Canonicalize (module', filterExports) where
4import Control.Applicative ((<$>),(<*>))
4import Control.Applicative ((<$>),(<*>))
5−import Control.Arrow (first)
6−import Control.Monad (foldM)
7import qualified Data.Either as Either
5import qualified Data.Either as Either
8import qualified Data.List as List
6import qualified Data.List as List
9import qualified Data.Map as Map
7import qualified Data.Map as Map
@@ -13,7 +11,7 @@ import AST.Expression.General (Expr'(..), dummyLet)
13import qualified AST.Expression.Valid as Valid
11import qualified AST.Expression.Valid as Valid
14import qualified AST.Expression.Canonical as Canonical
12import qualified AST.Expression.Canonical as Canonical
16−import AST.Module (Interface(iAdts, iTypes, iAliases), CanonicalBody(..))
14+import AST.Module (CanonicalBody(..))
17import qualified AST.Module as Module
15import qualified AST.Module as Module
18import qualified AST.Type as Type
16import qualified AST.Type as Type
19import qualified AST.Variable as Var
17import qualified AST.Variable as Var
@@ -24,137 +22,15 @@ import qualified AST.Pattern as P
24import Text.PrettyPrint as P
22import Text.PrettyPrint as P
26import Transform.Canonicalize.Environment as Env
24import Transform.Canonicalize.Environment as Env
25+import qualified Transform.Canonicalize.Setup as Setup
27import qualified Transform.Canonicalize.Type as Canonicalize
26import qualified Transform.Canonicalize.Type as Canonicalize
28import qualified Transform.Canonicalize.Variable as Canonicalize
27import qualified Transform.Canonicalize.Variable as Canonicalize
29import qualified Transform.SortDefinitions as Transform
28import qualified Transform.SortDefinitions as Transform
30import qualified Transform.Declaration as Transform
29import qualified Transform.Declaration as Transform
32−environment :: Module.Interfaces -> Module.ValidModule -> Either [Doc] Environment
33−environment interfaces m@(Module.Module _ _ _ ims decls) =
34− do () <- allImportsAvailable interfaces ims
35− nonLocalEnv <- foldM (toEnv interfaces) Env.builtIns ims
36− let moduleName = Module.getName m
37− foldM (addDecl moduleName) nonLocalEnv decls
39−toEnv :: Module.Interfaces -> Environment -> (String, Module.ImportMethod)
40− -> Either [Doc] Environment
41−toEnv interfaces environ (name,method)
42− | List.isPrefixOf "Native." name = return environ
46− return (updateEnviron (name' ++ "."))
48− Module.Open (Var.Listing vs open)
49− | open -> return (updateEnviron "")
50− | otherwise -> foldM (addValue name interface) environ vs
52− interface = (Map.!) interfaces name
54− updateEnviron prefix =
55− let dict' = dict . map (first (prefix++)) in
57− Env { _values = dict' $ map pair (Map.keys (iTypes interface)) ++ ctors
58− , _adts = dict' $ map pair (Map.keys (iAdts interface))
59− , _aliases = dict' $ map alias (Map.toList (iAliases interface))
60− , _patterns = dict' $ ctors
63− canonical :: String -> Var.Canonical
64− canonical = Var.Canonical (Var.Module name)
66− pair :: String -> (String, Var.Canonical)
67− pair key = (key, canonical key)
69− alias (x,(tvars,tipe)) = (x, (canonical x, tvars, tipe))
71− ctors = concatMap (map (pair . fst) . snd . snd) (Map.toList (iAdts interface))
73−addValue :: String -> Module.Interface -> Environment -> Var.Value
74− -> Either [Doc] Environment
75−addValue name interface env value =
76− let insert' x = Env.insert x (Var.Canonical (Var.Module name) x)
77− msg x = "Import Error: Could not import value '" ++ name ++ "." ++ x ++
78− "'.\n It is not exported by module " ++ name ++ "."
79− notFound x = Left [ P.text (msg x) ]
83− | Map.notMember x (iTypes interface) -> notFound x
85− return $ env { _values = insert' x (_values env) }
88− case Map.lookup x (iAliases interface) of
90− let v = (Var.Canonical (Var.Module name) x, tvars, t) in
91− return $ env { _aliases = Env.insert x v (_aliases env) }
93− case Map.lookup x (iAdts interface) of
94− Nothing -> notFound x
96− return $ env { _adts = insert' x (_adts env) }
98− Var.ADT x (Var.Listing xs open) ->
99− case Map.lookup x (iAdts interface) of
100− Nothing -> notFound x
101− Just (_tvars, ctors) ->
102− do ctors <- filterNames (map fst ctors)
103− return $ env { _adts = insert' x (_adts env)
104− , _values = foldr insert' (_values env) ctors
105− , _patterns = foldr insert' (_patterns env) ctors
109− | open = return names
111− case filter (`notElem` names) xs of
115−-- When canonicalizing, all _values should be Local, but all _adts and _patterns
116−-- should be fully namespaced. With _adts, they may appear in types that can
117−-- escape the module.
118−addDecl :: String -> Environment -> D.ValidDecl -> Either [Doc] Environment
119−addDecl moduleName env decl =
120− let namespacedVar = Var.Canonical (Var.Module moduleName)
121− addLocal x e = Env.insert x (Var.local x) e
122− addNamespaced x e = Env.insert x (namespacedVar x) e
125− D.Definition (Valid.Definition pattern _ _) ->
127− { _values = foldr addLocal (_values env) (P.boundVarList pattern) }
129− D.Datatype name _ ctors ->
131− { _values = addCtors addLocal (_values env)
132− , _adts = addNamespaced name (_adts env)
133− , _patterns = addCtors addNamespaced (_patterns env)
136− addCtors how e = foldr how e (map fst ctors)
138− D.TypeAlias name tvars alias ->
139− do alias' <- Either.either throw return (Canonicalize.tipe env alias)
141− { _aliases = Env.insert name (namespacedVar name, tvars, alias') (_aliases env)
142− , _values = case alias of
143− Type.Record _ _ -> addLocal name (_values env)
148− let msg = "Error in type alias '" ++ name ++ "':"
149− in Left [ P.vcat [ P.text msg, P.text err ] ]
151− D.Port _ -> return env
153− D.Fixity _ _ _ -> return env
155module' :: Module.Interfaces -> Module.ValidModule -> Either [Doc] Module.CanonicalModule
31module' :: Module.Interfaces -> Module.ValidModule -> Either [Doc] Module.CanonicalModule
156module' interfaces modul@(Module.Module _ _ exs _ decls) =
32module' interfaces modul@(Module.Module _ _ exs _ decls) =
157− do env <- environment interfaces modul
33+ do env <- Setup.environment interfaces modul
158 canonicalDecls <- mapM (declaration env) decls
34 canonicalDecls <- mapM (declaration env) decls
159 exports' <- delist locals exs
35 exports' <- delist locals exs
160 return $ modul { Module.exports = exports'
36 return $ modul { Module.exports = exports'
@@ -285,24 +161,6 @@ declaration env decl =
285 D.Fixity assoc prec op -> return $ D.Fixity assoc prec op
161 D.Fixity assoc prec op -> return $ D.Fixity assoc prec op
288−allImportsAvailable :: Module.Interfaces
289− -> [(String, Module.ImportMethod)]
291−allImportsAvailable interfaces imports =
292− case filter (not . found) modules of
294− missings -> Left [ P.text (missingModuleError missings) ]
296− modules = map fst imports
298− found m = Map.member m interfaces || List.isPrefixOf "Native." m
300− missingModuleError missings =
301− concat [ "The following imports were not found: "
302− , List.intercalate ", " missings
303− , "\n You may need to compile with the --make "
304− , "flag to detect modules you have written." ]
306expression :: Environment -> Valid.Expr -> Either [Doc] Canonical.Expr
164expression :: Environment -> Valid.Expr -> Either [Doc] Canonical.Expr
307expression env (A.A ann expr) =
165expression env (A.A ann expr) =
308 let go = expression env
166 let go = expression env