module DDC.Build.Transform.Resolve
( resolveNamesInModule )
where
import DDC.Core.Module
import DDC.Core.Exp
import DDC.Core.Collect.Support
import DDC.Type.DataDef
import DDC.Type.Env (KindEnv, TypeEnv)
import DDC.Base.Pretty
import DDC.Base.Panic
import Data.Map (Map)
import DDC.Build.Interface.Store (Store)
import DDC.Build.Interface.Base (Interface (..))
import qualified Data.Map as Map
import qualified Data.Set as Set
import qualified DDC.Build.Interface.Store as Store
import qualified DDC.Core.Tetra as E
import Data.List
import Data.Function
resolveNamesInModule
:: KindEnv E.Name
-> TypeEnv E.Name
-> Store
-> Module a E.Name
-> IO (Either [Error] (Module a E.Name))
resolveNamesInModule kenv tenv store mm
= do
let sp = support kenv tenv mm
ints <- Store.getInterfaces store
let deps = Map.fromList
[ ( interfaceModuleName i
, let Just m = interfaceTetraModule i in m)
| i <- ints ]
modNames <- Store.getModuleNames store
let getDaVarImport (UName n) = do
eImport <- findImportSourceForDaVar store modNames n
case eImport of
Left err -> return $ Left err
Right isrc -> return $ Right (n, isrc)
getDaVarImport u = panic "ddc-build" "resolveNamesInModule"
$ text "Cannot resolve anonymous binder:"
<+> ppr u
eimportsDaVar <- mapM getDaVarImport $ Set.toList $ supportDaVar sp
case sequence eimportsDaVar of
Left err -> return $ Left [err]
Right importsDaVar
-> return $ Right $ mm
{ moduleImportTypes
= moduleImportTypes mm
++ importsForTyCons deps (Set.toList $ supportTyCon sp)
, moduleImportDataDefs
= nubBy ((==) `on` dataDefTypeName)
$ moduleImportDataDefs mm
++ importsForDaTyCons deps (Set.toList $ supportTyCon sp)
, moduleImportCaps
= moduleImportCaps mm
++ importsCap deps
, moduleImportValues
= moduleImportValues mm
++ importsDaVar }
importsForTyCons
:: Ord n
=> Map ModuleName (Module b n)
-> [Bound n]
-> [(n, ImportType n)]
importsForTyCons deps _tyCons
= concat
[ [(n, ImportTypeAbstract k)
| (n, k) <- Map.toList $ Map.unions
$ map importedTyConsAbs $ Map.elems deps]
, [(n, ImportTypeAbstract k)
| (n, (_, k)) <- Map.toList $ Map.unions
$ map exportedTyConsLocal $ Map.elems deps]
, [(n, ImportTypeBoxed k)
| (n, k) <- Map.toList $ Map.unions
$ map importedTyConsBoxed $ Map.elems deps] ]
importsCap
:: Ord n
=> Map ModuleName (Module b n)
-> [(n, ImportCap n)]
importsCap deps
= concatMap moduleImportCaps $ Map.elems deps
importsForDaTyCons
:: Ord n
=> Map ModuleName (Module b n)
-> [Bound n]
-> [DataDef n]
importsForDaTyCons deps _tycons
= concat
$ [ moduleImportDataDefs m ++ moduleDataDefsLocal m
| m <- Map.elems deps ]
findImportSourceForDaVar
:: Store
-> [ModuleName]
-> E.Name
-> IO (Either Error (ImportValue E.Name))
findImportSourceForDaVar store modNames nSuper
= do result <- Store.findSuper store nSuper modNames
case result of
[] -> return $ Left $ ErrorNotFound nSuper
[super] -> return $ Right $ Store.superImportValue super
supers -> return $ Left $ ErrorMultiple nSuper (map Store.superModuleName supers)
exportedTyConsLocal :: Ord n => Module b n -> Map n (ModuleName, Kind n)
exportedTyConsLocal mm
= Map.fromList
$ [ (n, (moduleName mm, t))
| (n, ExportSourceLocal _ t) <- moduleExportTypes mm ]
importedTyConsAbs :: Ord n => Module b n -> Map n (Kind n)
importedTyConsAbs mm
= Map.fromList
$ [ (n, k) | (n, ImportTypeAbstract k) <- moduleImportTypes mm ]
importedTyConsBoxed :: Ord n => Module b n -> Map n (Kind n)
importedTyConsBoxed mm
= Map.fromList
$ [ (n, k) | (n, ImportTypeBoxed k) <- moduleImportTypes mm ]
data Error
= ErrorNotFound E.Name
| ErrorMultiple E.Name [ModuleName]
instance Pretty Error where
ppr err
= case err of
ErrorNotFound n
-> vcat [ text "Not in scope: " <> squotes (ppr n) ]
ErrorMultiple n ms
-> vcat $ [ text "Variable" <+> squotes (ppr n) <+> text "defined in multiple modules:" ]
++ (map ppr ms)