Plan 9 from Bell Labs’s /usr/web/sources/contrib/fernan/nhc98/src/compiler98/NeedLib.hs

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


{- ---------------------------------------------------------------------------
Basic data type and functions for "need" analysis
-}
module NeedLib(initNeed,needit,NeedLib,pushNeed,popNeed,bindTid,needTid
              ,NeedTable,needQualify) where
--            ,TokenId,IdKind,Memo(..),Tree) where

import TokenId(TokenId(..))
import TokenInt(tokenAllways,tokenMain)
import IdKind
import qualified Data.Map as Map
import qualified Data.Set as Set
import Overlap (Overlap,addOverlap)
import Syntax hiding (TokenId)

-- Added in H98: the overlap table, which allows for later resolution of
-- shared module aliases.

type NeedTable = Map.Map (TokenId,IdKind) [Pos]

data NeedLib = NeedLib (TokenId -> [TokenId])   -- qualified renaming
                       (Set.Set (TokenId,IdKind))  -- tids already seen
                       [Set.Set (TokenId,IdKind)]  -- stack of memos
                    -- (Map.Map (TokenId,IdKind) (Bool,TokenId,[TokenId])) 
                    -- overlap table
                       Overlap     -- overlaps for later resolution
                       NeedTable   -- final need-table


initNeed :: Bool -> NeedTable
initNeed b = foldr (\(k,t) a -> Map.insert (t,k) [] a) Map.empty initNeed'
  where initNeed' = tokenAllways ++ (if b then tokenMain else [])

needit :: (NeedLib -> NeedLib) 
       -> (TokenId -> [TokenId]) 
       -> NeedTable
       -> (NeedTable,Overlap)

needit n r iNeed =
  case n (NeedLib r Set.empty [] Map.empty iNeed) of
    (NeedLib r m [] o n) -> (n,o)


pushNeed :: NeedLib -> NeedLib
pushNeed (NeedLib r m ms o n) = NeedLib r m (m:ms) o n

popNeed :: NeedLib -> NeedLib
popNeed  (NeedLib r _ (m:ms) o n) = NeedLib r m ms o n

-- This version of bindTid was for Haskell 1.3, before the introduction
-- of overlapping import renamings.
--
--bindTid idKind tid (NeedLib r m ms o n) = NeedLib r (addM m (r tid,idKind)) ms o n

{-
memoise identifier together with its kind
-}
bindTid :: IdKind -> TokenId -> NeedLib -> NeedLib
bindTid idKind tid (NeedLib r m ms o n) =
  NeedLib r (foldr memoise m (r tid)) ms o n
  where
  memoise :: TokenId -> Set.Set (TokenId,IdKind) -> Set.Set (TokenId,IdKind)
  memoise tid m = Set.insert (tid,idKind) m

-- This version of needTid was for Haskell 1.3, before the introduction
-- of overlapping import renamings.
--
--needTid pos idKind tid needlib@(NeedLib r m ms o n) =
--  case r tid of
--    [tid] ->
--      case lookupM m (tid,idKind) of
--      Just _ -> needlib
--      Nothing ->
--        case lookupAT n (tid,idKind) of -- mostly to evaluate n now and then :-)
--          Just _ ->  NeedLib r (addM m (tid,idKind)) ms o (updateAT n (tid,idKind) (pos:))
--          Nothing -> NeedLib r (addM m (tid,idKind)) ms o (addAT n undefined (tid,idKind) [pos])
----  tids -> 
----    case lookupM m (tids,idKind) of
----    Just _ -> needlib
----    Nothing ->
----      case lookupAT n (tids,idKind) of -- mostly to evaluate n now and then :-)
----        Just _ ->  NeedLib r (addM m (tids,idKind)) ms (updateAT n (tids,idKind) (pos:))
----        Nothing -> NeedLib r (addM m (tids,idKind)) ms (addAT n undefined (tids,idKind) [pos])

needTid :: Pos -> IdKind -> TokenId -> NeedLib -> NeedLib

needTid pos idKind tid needlib@(NeedLib r m ms o n) =
  case r tid of
    []    -> error ("qualified renaming of "++show tid++" produced no results!")
    [tid] -> record tid needlib
    tids  -> foldr record (NeedLib r m ms (addOverlap tid idKind o tids) n) tids
 where
  record tid needlib@(NeedLib r m ms o n) =
    case (tid,idKind) `Set.member` m of 
      True -> needlib
      False ->
        case Map.lookup (tid,idKind) n of -- mostly to evaluate n now and then :-)
          Just _ -> NeedLib r (Set.insert (tid,idKind) m) ms o
                                         (Map.update (Just . (pos:)) (tid,idKind) n)
          Nothing -> NeedLib r (Set.insert (tid,idKind) m) ms o
                                         (Map.insertWith undefined (tid,idKind) [pos] n)

-- push qualification of identifiers from instance head into method decls
needQualify :: TokenId -> Decl TokenId -> Decl TokenId
needQualify (Visible _) decl       = decl
needQualify (Qualified mod _) decl = q decl
  where
    q (DeclFun pos (Visible fun) funs) =
       DeclFun pos (Qualified mod fun) funs
    q (DeclPat (Alt (ExpVar pos (Visible fun)) rhs decls)) =
       DeclPat (Alt (ExpVar pos (Qualified mod fun)) rhs decls)
    q decl = decl

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.