moduleDDC.Core.Module(-- * ModulesModule(..),isMainModule,moduleKindEnv,moduleTypeEnv,moduleTopBinds,moduleTopBindTypes-- * Module maps,ModuleMap,modulesExportTypes,modulesExportValues-- * Module Names,QualName(..),ModuleName(..),isMainModuleName-- * Export Sources,ExportSource(..),takeTypeOfExportSource,mapTypeOfExportSource-- * Import Sources,ImportSource(..),typeOfImportSource,mapTypeOfImportSource)whereimportDDC.Core.ExpimportDDC.Type.DataDefimportDDC.Type.CompoundsimportData.TypeableimportData.Map.Strict(Map)importData.Set(Set)importDDC.Type.EnvasEnvimportqualifiedData.Map.StrictasMapimportqualifiedData.SetasSetimportControl.DeepSeqimportData.Maybe-- Module ------------------------------------------------------------------------------------------- | A module can be mutually recursive with other modules.dataModulean=ModuleCore{-- | Name of this module.moduleName::!ModuleName-- Exports -------------------- | Kinds of exported types.,moduleExportTypes::![(n,ExportSourcen)]-- | Types of exported values.,moduleExportValues::![(n,ExportSourcen)]-- Imports -------------------- | Kinds of imported types, along with the name of the module they are from.-- These imports come from a Disciple module, that we've compiled ourself.,moduleImportTypes::![(n,ImportSourcen)]-- | Types of imported values, along with the name of the module they are from.-- These imports come from a Disciple module, that we've compiled ourself.,moduleImportValues::![(n,ImportSourcen)]-- Local ---------------------- | Data types defined in this module.,moduleDataDefsLocal::![DataDefn]-- | The module body consists of some let-bindings wrapping a unit-- data constructor. We're only interested in the bindings, with-- the unit being just a place-holder.,moduleBody::!(Expan)}deriving(Show,Typeable)instance(NFDataa,NFDatan)=>NFData(Modulean)wherernf!mm=rnf(moduleNamemm)`seq`rnf(moduleExportTypesmm)`seq`rnf(moduleExportValuesmm)`seq`rnf(moduleImportTypesmm)`seq`rnf(moduleImportValuesmm)`seq`rnf(moduleDataDefsLocalmm)`seq`rnf(moduleBodymm)-- | Check if this is the `Main` module.isMainModule::Modulean->BoolisMainModulemm=isMainModuleName$moduleNamemm-- | Get the top-level kind environment of a module,-- from its imported types.moduleKindEnv::Ordn=>Modulean->KindEnvnmoduleKindEnvmm=Env.fromList$[BNamen(typeOfImportSourceisrc)|(n,isrc)<-moduleImportTypesmm]-- | Get the top-level type environment of a module,-- from its imported values.moduleTypeEnv::Ordn=>Modulean->TypeEnvnmoduleTypeEnvmm=Env.fromList$[BNamen(typeOfImportSourceisrc)|(n,isrc)<-moduleImportValuesmm]-- | Get the set of top-level value bindings in a module.moduleTopBinds::Ordn=>Modulean->SetnmoduleTopBindsmm=go(moduleBodymm)wheregoxx=casexxofXLet_(LLet(BNamen_)_)x2->Set.insertn(gox2)XLet_(LLet__)x2->gox2XLet_(LRecbxs)x2->Set.fromList(mapMaybetakeNameOfBind$mapfstbxs)`Set.union`gox2_->Set.empty-- | Get a map of named top-level bindings to their types.moduleTopBindTypes::Ordn=>Modulean->Mapn(Typen)moduleTopBindTypesmm=goMap.empty(moduleBodymm)wheregoaccxx=casexxofXLet_(LLet(BNament)_)x2->go(Map.insertntacc)x2XLet_(LLet__)x2->goaccx2XLet_(LRecbxs)x2->go(Map.unionacc(Map.fromList[(n,t)|BNament<-mapfstbxs]))x2_->acc-- ModuleMap ---------------------------------------------------------------------------------------- | Map of module names to modules.typeModuleMapan=MapModuleName(Modulean)-- | Add the kind environment exported by all these modules to the given one.modulesExportTypes::Ordn=>ModuleMapan->KindEnvn->KindEnvnmodulesExportTypesmodsbase=letenvOfModulem=Env.fromList$[BNament|(n,Justt)<-map(liftSndtakeTypeOfExportSource)$moduleExportTypesm]liftSndf(x,y)=(x,fy)inEnv.unions$base:(mapenvOfModule$Map.elemsmods)-- | Add the type environment exported by all these modules to the given one.modulesExportValues::Ordn=>ModuleMapan->TypeEnvn->TypeEnvnmodulesExportValuesmodsbase=letenvOfModulem=Env.fromList$[BNament|(n,Justt)<-map(liftSndtakeTypeOfExportSource)$moduleExportValuesm]liftSndf(x,y)=(x,fy)inEnv.unions$base:(mapenvOfModule$Map.elemsmods)-- ModuleName --------------------------------------------------------------------------------------- | A hierarchical module name.dataModuleName=ModuleName[String]deriving(Show,Eq,Ord,Typeable)instanceNFDataModuleNamewherernf(ModuleNamess)=rnfss-- | A fully qualified name, -- including the name of the module it is from.dataQualNamen=QualNameModuleNamenderivingShowinstanceNFDatan=>NFData(QualNamen)wherernf(QualNamemnn)=rnfmn`seq`rnfn-- | Check whether this is the name of the \"Main\" module.isMainModuleName::ModuleName->BoolisMainModuleNamemn=casemnofModuleName["Main"]->True_->False-- ExportSource -----------------------------------------------------------------------------------dataExportSourcen-- | A name defined in this module, with an explicit type.=ExportSourceLocal{exportSourceLocalName::n,exportSourceLocalType::Typen}-- | A named defined in this module, without a type attached.-- We use this version for source language where we infer the type of-- the exported thing.|ExportSourceLocalNoType{exportSourceLocalName::n}deriving(Show,Eq)instanceNFDatan=>NFData(ExportSourcen)wherernfes=caseesofExportSourceLocalnt->rnfn`seq`rnftExportSourceLocalNoTypen->rnfn-- | Take the type of an imported thing, if there is one.takeTypeOfExportSource::ExportSourcen->Maybe(Typen)takeTypeOfExportSourcees=caseesofExportSourceLocal_t->JusttExportSourceLocalNoType{}->Nothing-- | Apply a function to any type in an ExportSource.mapTypeOfExportSource::(Typen->Typen)->ExportSourcen->ExportSourcenmapTypeOfExportSourcefesrc=caseesrcofExportSourceLocalnt->ExportSourceLocaln(ft)ExportSourceLocalNoTypen->ExportSourceLocalNoTypen-- ImportSource ------------------------------------------------------------------------------------- | Source of some imported thing.dataImportSourcen-- | A type imported abstractly.-- It may be defined in a foreign language, but the Disciple program-- treats it abstractly.=ImportSourceAbstract{importSourceAbstractType::Typen}-- | Something imported from a Disciple module that we compiled ourself.|ImportSourceModule{importSourceModuleName::ModuleName,importSourceModuleVar::n,importSourceModuleType::Typen}-- | Something imported via the C calling convention.|ImportSourceSea{importSourceSeaVar::String,importSourceSeaType::Typen}deriving(Show,Eq)instanceNFDatan=>NFData(ImportSourcen)wherernfis=caseisofImportSourceAbstractt->rnftImportSourceModulemnnt->rnfmn`seq`rnfn`seq`rnftImportSourceSeavt->rnfv`seq`rnft-- | Take the type of an imported thing.typeOfImportSource::ImportSourcen->TypentypeOfImportSourcesrc=casesrcofImportSourceAbstractt->tImportSourceModule__t->tImportSourceSea_t->t-- | Apply a function to the type in an ImportSource.mapTypeOfImportSource::(Typen->Typen)->ImportSourcen->ImportSourcenmapTypeOfImportSourcefisrc=caseisrcofImportSourceAbstractt->ImportSourceAbstract(ft)ImportSourceModulemnnt->ImportSourceModulemnn(ft)ImportSourceSeast->ImportSourceSeas(ft)