Modules.lhs

  module Modules(computeInsOuts,inscope) where
 
  import Relations
  import NamesEntities
  import ModSysAST
  import Maybe (isNothing)
  import Sets




































  mEntSpec :: (Ord j,ToSimple j) => 
    Bool ->           -- is it a hiding import?
    Rel j Entity ->   -- the original relation
    EntSpec j         -- the specification
      -> Rel j Entity -- the subset satisfying the specification
 
  mEntSpec isHiding rel (Ent x subspec) =
    unionRels [mSpec, mSub]
    where
    mSpec   = restrictRng consider (restrictDom (== x) rel)
    allSubs = owns `unionMapSet` rng mSpec
    subs    = restrictRng (`elementOf` allSubs) rel
    mSub    = 
      case subspec of
        Nothing        -> emptyRel
        Just AllSubs   -> subs
        Just (Subs xs) -> 
          restrictDom ((`elem` xs) . toSimple) subs
 
    consider
      | isHiding && isNothing subspec = const True
      | otherwise                     = not . isCon



















































































































































  exports :: Module -> Rel QName Entity -> Rel Name Entity
  exports mod inscp = 
    case modExpList mod of
      Nothing -> modDefines mod
      Just es -> getQualified `mapDom` unionRels exps
        where
        exps = mExpListEntry inscp `map` es
























  mExpListEntry :: 
    Rel QName Entity -> ExpListEntry -> Rel QName Entity
  mExpListEntry inscp (EntExp it) = mEntSpec False inscp it
  mExpListEntry inscp (ModuleExp m) = 
    (qual m `mapDom` unqs) `intersectRel` qs
    where
    (qs,unqs) = partitionDom isQual inscp








  inscope :: Module -> (ModName -> Rel Name Entity) 
                          -> Rel QName Entity
  inscope m expsOf = unionRels [imports, locals]
    where
    defEnts = modDefines m
    locals  = unionRels 
                [mkUnqual `mapDom` defEnts,
                 mkQual (modName m) `mapDom` defEnts]
 
    imports = 
      unionRels $ map (mImp expsOf) (modImports m)





























  mImp :: (ModName -> Rel Name Entity) -> Import ->
           Rel QName Entity 
  mImp expsOf imp
    | impQualified imp  = qs
    | otherwise         = unionRels [unqs, qs]
    where
    qs      = mkQual (impAs imp) `mapDom` incoming
    unqs    = mkUnqual `mapDom` incoming
 
    listed  = unionRels $
                map (mEntSpec isHiding exps) 
                    (impList imp)
    incoming
      | isHiding  = exps `minusRel` listed
      | otherwise = listed
 
    isHiding  = impHiding imp
    exps      = expsOf (impSource imp)












































  computeInsOuts :: 
    (ModName -> Rel Name Entity) -> [Module] ->
     [(Rel QName Entity, Rel Name Entity)]
  computeInsOuts otherExps mods = inscps `zip` exps
    where
    inscps = computeIs exps
    exps   = lfpAfter nextExps $ 
              replicate (length mods) emptyRel
 
    nextExps = computeEs . computeIs
 
    computeEs is = zipWith exports mods is
    computeIs es = map (`inscope` toFun es) mods
 
    toFun es m   = maybe (otherExps m) (es !!) 
                         (lookup m mod_ixs)
    mod_ixs      = map modName mods `zip` [0..]
 
  lfpAfter f x = if fx == x then fx else lfpAfter f fx
    where 
    fx = f x


























































































































Plain-text version of Modules.lhs | Valid HTML?