summaryrefslogtreecommitdiff
path: root/src/GF/Infra/Modules.hs
diff options
context:
space:
mode:
authoraarne <unknown>2003-09-22 13:16:55 +0000
committeraarne <unknown>2003-09-22 13:16:55 +0000
commitb1402e8bd6a68a891b00a214d6cf184d66defe19 (patch)
tree90372ac4e53dce91cf949dbf8e93be06f1d9e8bd /src/GF/Infra/Modules.hs
Founding the newly structured GF2.0 cvs archive.
Diffstat (limited to 'src/GF/Infra/Modules.hs')
-rw-r--r--src/GF/Infra/Modules.hs181
1 files changed, 181 insertions, 0 deletions
diff --git a/src/GF/Infra/Modules.hs b/src/GF/Infra/Modules.hs
new file mode 100644
index 000000000..01b789f8f
--- /dev/null
+++ b/src/GF/Infra/Modules.hs
@@ -0,0 +1,181 @@
+module Modules where
+
+import Ident
+import Option
+import Operations
+
+import List
+
+
+-- AR 29/4/2003
+
+-- The same structure will be used in both source code and canonical.
+-- The parameters tell what kind of data is involved.
+-- Invariant: modules are stored in dependency order
+
+data MGrammar i f a = MGrammar {modules :: [(i,ModInfo i f a)]}
+ deriving Show
+
+data ModInfo i f a =
+ ModMainGrammar (MainGrammar i)
+ | ModMod (Module i f a)
+ deriving Show
+
+data Module i f a = Module {
+ mtype :: ModuleType i ,
+ flags :: [f] ,
+ extends :: Maybe i ,
+ opens :: [OpenSpec i] ,
+ jments :: BinTree (i,a)
+ }
+ deriving Show
+
+-- destructive update
+
+--- dep order preserved since old cannot depend on new
+updateMGrammar :: Ord i => MGrammar i f a -> MGrammar i f a -> MGrammar i f a
+updateMGrammar old new = MGrammar $
+ [(i,m) | (i,m) <- os, notElem i (map fst ns)] ++ ns
+ where
+ os = modules old
+ ns = modules new
+
+updateModule :: Ord i => Module i f t -> i -> t -> Module i f t
+updateModule (Module mt fs me ops js) i t =
+ Module mt fs me ops (updateTree (i,t) js)
+
+data MainGrammar i = MainGrammar {
+ mainAbstract :: i ,
+ mainConcretes :: [MainConcreteSpec i]
+ }
+ deriving Show
+
+data MainConcreteSpec i = MainConcreteSpec {
+ concretePrintname :: i ,
+ concreteName :: i ,
+ transferIn :: Maybe (OpenSpec i) , -- if there is an in-transfer
+ transferOut :: Maybe (OpenSpec i) -- if there is an out-transfer
+ }
+ deriving Show
+
+data OpenSpec i = OSimple i | OQualif i i
+ deriving (Eq,Show)
+
+openedModule :: OpenSpec i -> i
+openedModule o = case o of
+ OSimple m -> m
+ OQualif _ m -> m
+
+-- initial dependency list
+depPathModule :: Ord i => Module i f a -> [OpenSpec i]
+depPathModule m = fors m ++ exts m ++ opens m where
+ fors m = case mtype m of
+ MTTransfer i j -> [i,j]
+ MTConcrete i -> [OSimple i]
+ _ -> []
+ exts m = map OSimple $ maybe [] return $ extends m
+
+-- all modules that a module extends, directly or indirectly
+allExtends :: (Show i,Ord i) => MGrammar i f a -> i -> [i]
+allExtends gr i = case lookupModule gr i of
+ Ok (ModMod m) -> case extends m of
+ Just i1 -> i : allExtends gr i1
+ _ -> [i]
+ _ -> []
+
+-- initial search path: the nonqualified dependencies
+searchPathModule :: Ord i => Module i f a -> [i]
+searchPathModule m = [i | OSimple i <- depPathModule m]
+
+-- a new module can safely be added to the end, since nothing old can depend on it
+addModule :: Ord i =>
+ MGrammar i f a -> i -> ModInfo i f a -> MGrammar i f a
+addModule gr name mi = MGrammar $ (modules gr ++ [(name,mi)])
+
+emptyMGrammar :: MGrammar i f a
+emptyMGrammar = MGrammar []
+
+
+-- we store the module type with the identifier
+
+data IdentM i = IdentM {
+ identM :: i ,
+ typeM :: ModuleType i
+ }
+ deriving (Eq,Show)
+
+-- encoding the type of the module
+data ModuleType i =
+ MTAbstract
+ | MTTransfer (OpenSpec i) (OpenSpec i)
+ | MTResource
+ | MTResourceInt
+ | MTResourceImpl i
+ | MTConcrete i
+ | MTConcreteInt i i
+ | MTConcreteImpl i i i
+ | MTReuse i
+ deriving (Eq,Show)
+
+typeOfModule mi = case mi of
+ ModMod m -> mtype m
+
+isResourceModule mi = case typeOfModule mi of
+ MTResource -> True
+ MTReuse _ -> True
+ MTResourceInt -> True
+ MTResourceImpl _ -> True
+ _ -> False
+
+abstractOfConcrete :: (Show i, Eq i) => MGrammar i f a -> i -> Err i
+abstractOfConcrete gr c = do
+ m <- lookupModule gr c
+ case m of
+ ModMod n -> case mtype n of
+ MTConcrete a -> return a
+ _ -> Bad $ "expected concrete" +++ show c
+ _ -> Bad $ "expected concrete" +++ show c
+
+abstractModOfConcrete :: (Show i, Eq i) =>
+ MGrammar i f a -> i -> Err (Module i f a)
+abstractModOfConcrete gr c = do
+ a <- abstractOfConcrete gr c
+ m <- lookupModule gr a
+ case m of
+ ModMod n -> return n
+ _ -> Bad $ "expected abstract" +++ show c
+
+
+-- the canonical file name
+
+--- canonFileName s = prt s ++ ".gfc"
+
+lookupModule :: (Show i,Eq i) => MGrammar i f a -> i -> Err (ModInfo i f a)
+lookupModule gr m = case lookup m (modules gr) of
+ Just i -> return i
+ _ -> Bad $ "unknown module" +++ show m
+ +++ "among" +++ unwords (map (show . fst) (modules gr)) ---- debug
+
+lookupModuleType :: (Show i,Eq i) => MGrammar i f a -> i -> Err (ModuleType i)
+lookupModuleType gr m = do
+ mi <- lookupModule gr m
+ return $ typeOfModule mi
+
+lookupInfo :: (Show i, Ord i) => Module i f a -> i -> Err a
+lookupInfo mo i = lookupTree show i (jments mo)
+
+isModAbs m = case mtype m of
+ MTAbstract -> True
+ _ -> False
+
+isModRes m = case mtype m of
+ MTResource -> True
+ _ -> False
+
+isModCnc m = case mtype m of
+ MTConcrete _ -> True
+ _ -> False
+
+sameMType m n = case (m,n) of
+ (MTConcrete _, MTConcrete _) -> True
+ _ -> m == n