mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-04-23 03:32:51 -06:00
improved make facility: remember state if fails; does not need source
This commit is contained in:
@@ -32,7 +32,7 @@
|
|||||||
-- by using, instead of this module, the $reuse$ module which has the name
|
-- by using, instead of this module, the $reuse$ module which has the name
|
||||||
-- $ResourceX$
|
-- $ResourceX$
|
||||||
|
|
||||||
abstract Combinations = PredefAbs ** {
|
abstract Combinations = {
|
||||||
--!
|
--!
|
||||||
--2 Categories
|
--2 Categories
|
||||||
--
|
--
|
||||||
|
|||||||
@@ -125,8 +125,8 @@ string2GFCat = string2CFCat
|
|||||||
|
|
||||||
optFile2grammar :: Options -> FilePath -> IOE GFGrammar
|
optFile2grammar :: Options -> FilePath -> IOE GFGrammar
|
||||||
optFile2grammar os f = do
|
optFile2grammar os f = do
|
||||||
gr <- compileModule os emptyShellState f
|
((_,_,gr),_) <- compileModule os emptyShellState f
|
||||||
ioeErr $ grammar2stateGrammar os (fst gr)
|
ioeErr $ grammar2stateGrammar os gr
|
||||||
|
|
||||||
optFile2grammarE :: Options -> FilePath -> IOE GFGrammar
|
optFile2grammarE :: Options -> FilePath -> IOE GFGrammar
|
||||||
optFile2grammarE = optFile2grammar
|
optFile2grammarE = optFile2grammar
|
||||||
|
|||||||
@@ -39,8 +39,8 @@ string2annotTree gr m = annotate gr . string2absTerm (prt m) ---- prt
|
|||||||
shellStateFromFiles :: Options -> ShellState -> FilePath -> IOE ShellState
|
shellStateFromFiles :: Options -> ShellState -> FilePath -> IOE ShellState
|
||||||
shellStateFromFiles opts st file = case fileSuffix file of
|
shellStateFromFiles opts st file = case fileSuffix file of
|
||||||
"gfcm" -> do
|
"gfcm" -> do
|
||||||
(_,_,cgr) <- compileOne opts (compileEnvShSt st []) file
|
cenv <- compileOne opts (compileEnvShSt st []) file
|
||||||
ioeErr $ updateShellState opts st (cgr,(emptyMGrammar,[]))
|
ioeErr $ updateShellState opts st cenv
|
||||||
s | elem s ["cf","ebnf"] -> do
|
s | elem s ["cf","ebnf"] -> do
|
||||||
let osb = addOptions (options [beVerbose]) opts
|
let osb = addOptions (options [beVerbose]) opts
|
||||||
grts <- compileModule osb st file
|
grts <- compileModule osb st file
|
||||||
|
|||||||
@@ -53,8 +53,8 @@ batchCompileOld f = compileOld defOpts f
|
|||||||
-- As for path: if it is read from file, the file path is prepended to each name.
|
-- As for path: if it is read from file, the file path is prepended to each name.
|
||||||
-- If from command line, it is used as it is.
|
-- If from command line, it is used as it is.
|
||||||
|
|
||||||
compileModule :: Options -> ShellState -> FilePath ->
|
compileModule :: Options -> ShellState -> FilePath -> IOE TimedCompileEnv
|
||||||
IOE (GFC.CanonGrammar, (SourceGrammar,[(FilePath,ModTime)]))
|
---- IOE (GFC.CanonGrammar, (SourceGrammar,[(FilePath,ModTime)]))
|
||||||
|
|
||||||
compileModule opts st0 file |
|
compileModule opts st0 file |
|
||||||
oElem showOld opts ||
|
oElem showOld opts ||
|
||||||
@@ -68,15 +68,17 @@ compileModule opts st0 file |
|
|||||||
else putp ("- parsing old gf" +++ file) $ getOldGrammar opts file
|
else putp ("- parsing old gf" +++ file) $ getOldGrammar opts file
|
||||||
let mods = modules grammar1
|
let mods = modules grammar1
|
||||||
let env = compileEnvShSt st0 []
|
let env = compileEnvShSt st0 []
|
||||||
(_,sgr,cgr) <- foldM (comp putp path) env mods
|
foldM (comp putp path) env mods
|
||||||
return $ (reverseModules cgr, -- to preserve dependency order
|
---- (_,sgr,cgr) <- foldM (comp putp path) env mods
|
||||||
(reverseModules sgr,[]))
|
---- return $ (reverseModules cgr, -- to preserve dependency order
|
||||||
|
---- (reverseModules sgr,[]))
|
||||||
where
|
where
|
||||||
suff = fileSuffix file
|
suff = fileSuffix file
|
||||||
comp putp path env sm0 = do
|
comp putp path env sm0 = do
|
||||||
(k',sm) <- makeSourceModule opts env sm0
|
(k',sm) <- makeSourceModule opts (fst env) sm0
|
||||||
cm <- putp " generating code... " $ generateModuleCode opts path sm
|
cm <- putp " generating code... " $ generateModuleCode opts path sm
|
||||||
extendCompileEnvInt env (k',sm,cm)
|
ft <- getReadTimes file ---
|
||||||
|
extendCompileEnvInt env (k',sm,cm) ft
|
||||||
|
|
||||||
compileModule opts1 st0 file = do
|
compileModule opts1 st0 file = do
|
||||||
opts0 <- ioeIO $ getOptionsFromFile file
|
opts0 <- ioeIO $ getOptionsFromFile file
|
||||||
@@ -98,6 +100,11 @@ compileModule opts1 st0 file = do
|
|||||||
let names = map justModuleName files
|
let names = map justModuleName files
|
||||||
ioeIOIf $ putStrLn $ "modules to include:" +++ show names ----
|
ioeIOIf $ putStrLn $ "modules to include:" +++ show names ----
|
||||||
let env0 = compileEnvShSt st names
|
let env0 = compileEnvShSt st names
|
||||||
|
(e,mm) <- foldIOE (compileOne opts) env0 files
|
||||||
|
maybe (return ()) putStrLnE mm
|
||||||
|
return e
|
||||||
|
|
||||||
|
{- ----
|
||||||
(_,sgr,cgr) <- foldM (compileOne opts) env0 files
|
(_,sgr,cgr) <- foldM (compileOne opts) env0 files
|
||||||
t <- ioeIO getNowTime
|
t <- ioeIO getNowTime
|
||||||
return $ (reverseModules cgr, -- to preserve dependency order
|
return $ (reverseModules cgr, -- to preserve dependency order
|
||||||
@@ -105,12 +112,20 @@ compileModule opts1 st0 file = do
|
|||||||
[(justModuleName f,t) | f <- files] -- pass on the time of reading
|
[(justModuleName f,t) | f <- files] -- pass on the time of reading
|
||||||
++ [(resModName (justModuleName f),t) -- also #file if file.(gf|gfr)
|
++ [(resModName (justModuleName f),t) -- also #file if file.(gf|gfr)
|
||||||
| f <- files, not (isGFC f)]))
|
| f <- files, not (isGFC f)]))
|
||||||
compileEnvShSt :: ShellState -> [ModName] -> CompileEnv
|
-}
|
||||||
compileEnvShSt st fs = (0,sgr,cgr) where
|
|
||||||
|
getReadTimes file = do
|
||||||
|
t <- ioeIO getNowTime
|
||||||
|
let m = justModuleName file
|
||||||
|
return $ (m,t) : [(resModName m,t) | not (isGFC file)]
|
||||||
|
|
||||||
|
compileEnvShSt :: ShellState -> [ModName] -> TimedCompileEnv
|
||||||
|
compileEnvShSt st fs = ((0,sgr,cgr),fts) where
|
||||||
cgr = MGrammar [m | m@(i,_) <- modules (canModules st), notInc i]
|
cgr = MGrammar [m | m@(i,_) <- modules (canModules st), notInc i]
|
||||||
sgr = MGrammar [m | m@(i,_) <- modules (srcModules st), notIns i]
|
sgr = MGrammar [m | m@(i,_) <- modules (srcModules st), notIns i]
|
||||||
notInc i = notElem (prt i) $ map fileBody fs
|
notInc i = notElem (prt i) $ map fileBody fs
|
||||||
notIns i = notElem (prt i) $ map fileBody fs
|
notIns i = notElem (prt i) $ map fileBody fs
|
||||||
|
fts = readFiles st
|
||||||
|
|
||||||
pathListOpts :: Options -> [InitPath]
|
pathListOpts :: Options -> [InitPath]
|
||||||
pathListOpts opts = maybe [""] pFilePaths $ getOptVal opts pathList
|
pathListOpts opts = maybe [""] pFilePaths $ getOptVal opts pathList
|
||||||
@@ -128,18 +143,20 @@ keepResModules opts gr =
|
|||||||
|
|
||||||
type CompileEnv = (Int,SourceGrammar, GFC.CanonGrammar)
|
type CompileEnv = (Int,SourceGrammar, GFC.CanonGrammar)
|
||||||
|
|
||||||
emptyCompileEnv :: CompileEnv
|
emptyCompileEnv :: TimedCompileEnv
|
||||||
emptyCompileEnv = (0,emptyMGrammar,emptyMGrammar)
|
emptyCompileEnv = ((0,emptyMGrammar,emptyMGrammar),[])
|
||||||
|
|
||||||
extendCompileEnvInt (_,MGrammar ss, MGrammar cs) (k,sm,cm) =
|
extendCompileEnvInt ((_,MGrammar ss, MGrammar cs),fts) (k,sm,cm) ft =
|
||||||
return (k,MGrammar (sm:ss), MGrammar (cm:cs)) --- reverse later
|
return ((k,MGrammar (sm:ss), MGrammar (cm:cs)),ft++fts) --- reverse later
|
||||||
|
|
||||||
extendCompileEnv (k,s,c) (sm,cm) = extendCompileEnvInt (k,s,c) (k,sm,cm)
|
extendCompileEnv e@((k,_,_),_) (sm,cm) = extendCompileEnvInt e (k,sm,cm)
|
||||||
|
|
||||||
extendCompileEnvCanon (k,s,c) cgr =
|
extendCompileEnvCanon ((k,s,c),fts) cgr ft =
|
||||||
return (k,s, MGrammar (modules cgr ++ modules c))
|
return ((k,s, MGrammar (modules cgr ++ modules c)),ft++fts)
|
||||||
|
|
||||||
compileOne :: Options -> CompileEnv -> FullPath -> IOE CompileEnv
|
type TimedCompileEnv = (CompileEnv,[(FilePath,ModTime)])
|
||||||
|
|
||||||
|
compileOne :: Options -> TimedCompileEnv -> FullPath -> IOE TimedCompileEnv
|
||||||
compileOne opts env file = do
|
compileOne opts env file = do
|
||||||
|
|
||||||
let putp = putPointE opts
|
let putp = putPointE opts
|
||||||
@@ -151,29 +168,33 @@ compileOne opts env file = do
|
|||||||
-- for multilingual canonical gf, just read the file and update environment
|
-- for multilingual canonical gf, just read the file and update environment
|
||||||
"gfcm" -> do
|
"gfcm" -> do
|
||||||
cgr <- putp ("+ reading" +++ file) $ getCanonGrammar file
|
cgr <- putp ("+ reading" +++ file) $ getCanonGrammar file
|
||||||
extendCompileEnvCanon env cgr
|
ft <- getReadTimes file
|
||||||
|
extendCompileEnvCanon env cgr ft
|
||||||
|
|
||||||
-- for canonical gf, read the file and update environment, also source env
|
-- for canonical gf, read the file and update environment, also source env
|
||||||
"gfc" -> do
|
"gfc" -> do
|
||||||
cm <- putp ("+ reading" +++ file) $ getCanonModule file
|
cm <- putp ("+ reading" +++ file) $ getCanonModule file
|
||||||
sm <- ioeErr $ CG.canon2sourceModule cm
|
sm <- ioeErr $ CG.canon2sourceModule cm
|
||||||
extendCompileEnv env (sm, cm)
|
ft <- getReadTimes file
|
||||||
|
extendCompileEnv env (sm, cm) ft
|
||||||
|
|
||||||
-- for compiled resource, parse and organize, then update environment
|
-- for compiled resource, parse and organize, then update environment
|
||||||
"gfr" -> do
|
"gfr" -> do
|
||||||
sm0 <- putp ("| parsing" +++ file) $ getSourceModule file
|
sm0 <- putp ("| parsing" +++ file) $ getSourceModule file
|
||||||
let mos = case env of (_,gr,_) -> modules gr
|
let mos = case env of ((_,gr,_),_) -> modules gr
|
||||||
sm <- {- putp "creating indirections" $ -} ioeErr $ extendModule mos sm0
|
sm <- {- putp "creating indirections" $ -} ioeErr $ extendModule mos sm0
|
||||||
let gfc = gfcFile name
|
let gfc = gfcFile name
|
||||||
cm <- putp ("+ reading" +++ gfc) $ getCanonModule gfc
|
cm <- putp ("+ reading" +++ gfc) $ getCanonModule gfc
|
||||||
extendCompileEnv env (sm,cm)
|
ft <- getReadTimes file
|
||||||
|
extendCompileEnv env (sm,cm) ft
|
||||||
|
|
||||||
-- for gf source, do full compilation
|
-- for gf source, do full compilation
|
||||||
_ -> do
|
_ -> do
|
||||||
sm0 <- putp ("- parsing" +++ file) $ getSourceModule file
|
sm0 <- putp ("- parsing" +++ file) $ getSourceModule file
|
||||||
(k',sm) <- makeSourceModule opts env sm0
|
(k',sm) <- makeSourceModule opts (fst env) sm0
|
||||||
cm <- putp " generating code... " $ generateModuleCode opts path sm
|
cm <- putp " generating code... " $ generateModuleCode opts path sm
|
||||||
extendCompileEnvInt env (k',sm,cm)
|
ft <- getReadTimes file
|
||||||
|
extendCompileEnvInt env (k',sm,cm) ft
|
||||||
|
|
||||||
-- dispatch reused resource at early stage
|
-- dispatch reused resource at early stage
|
||||||
|
|
||||||
@@ -268,7 +289,7 @@ compileOld opts file = do
|
|||||||
let putp = putPointE opts
|
let putp = putPointE opts
|
||||||
grammar1 <- putp ("- parsing old gf" +++ file) $ getOldGrammar opts file
|
grammar1 <- putp ("- parsing old gf" +++ file) $ getOldGrammar opts file
|
||||||
files <- mapM writeNewGF $ modules grammar1
|
files <- mapM writeNewGF $ modules grammar1
|
||||||
(_,_,grammar) <- foldM (compileOne opts) emptyCompileEnv files
|
((_,_,grammar),_) <- foldM (compileOne opts) emptyCompileEnv files
|
||||||
return grammar
|
return grammar
|
||||||
|
|
||||||
writeNewGF :: SourceModule -> IOE FilePath
|
writeNewGF :: SourceModule -> IOE FilePath
|
||||||
|
|||||||
@@ -107,16 +107,17 @@ cncModuleIdST = stateGrammarST
|
|||||||
|
|
||||||
grammar2shellState :: Options -> (CanonGrammar, G.SourceGrammar) -> Err ShellState
|
grammar2shellState :: Options -> (CanonGrammar, G.SourceGrammar) -> Err ShellState
|
||||||
grammar2shellState opts (gr,sgr) =
|
grammar2shellState opts (gr,sgr) =
|
||||||
updateShellState opts emptyShellState (gr,(sgr,[]))
|
updateShellState opts emptyShellState ((0,sgr,gr),[]) --- is 0 safe?
|
||||||
|
|
||||||
-- update a shell state from a canonical grammar
|
-- update a shell state from a canonical grammar
|
||||||
|
|
||||||
updateShellState :: Options -> ShellState ->
|
updateShellState :: Options -> ShellState ->
|
||||||
(CanonGrammar,(G.SourceGrammar,[(FilePath,ModTime)])) ->
|
((Int,G.SourceGrammar,CanonGrammar),[(FilePath,ModTime)]) ->
|
||||||
|
---- (CanonGrammar,(G.SourceGrammar,[(FilePath,ModTime)])) ->
|
||||||
Err ShellState
|
Err ShellState
|
||||||
updateShellState opts sh (gr,(sgr,rts)) = do
|
updateShellState opts sh ((_,sgr,gr),rts) = do
|
||||||
let cgr0 = M.updateMGrammar (canModules sh) gr
|
let cgr0 = M.updateMGrammar (canModules sh) gr
|
||||||
a' = ifNull Nothing (return . last) $ allAbstracts cgr0
|
a' = ifNull Nothing (return . head) $ allAbstracts cgr0
|
||||||
abstr0 <- case abstract sh of
|
abstr0 <- case abstract sh of
|
||||||
Just a -> do
|
Just a -> do
|
||||||
--- test that abstract is compatible
|
--- test that abstract is compatible
|
||||||
@@ -124,7 +125,7 @@ updateShellState opts sh (gr,(sgr,rts)) = do
|
|||||||
_ -> return a'
|
_ -> return a'
|
||||||
let cgr = filterAbstracts abstr0 cgr0
|
let cgr = filterAbstracts abstr0 cgr0
|
||||||
let concrs = maybe [] (allConcretes cgr) abstr0
|
let concrs = maybe [] (allConcretes cgr) abstr0
|
||||||
concr0 = ifNull Nothing (return . last) concrs
|
concr0 = ifNull Nothing (return . head) concrs
|
||||||
notInrts f = notElem f $ map fst rts
|
notInrts f = notElem f $ map fst rts
|
||||||
cfs <- mapM (canon2cf opts cgr) concrs --- would not need to update all...
|
cfs <- mapM (canon2cf opts cgr) concrs --- would not need to update all...
|
||||||
|
|
||||||
@@ -149,7 +150,7 @@ updateShellState opts sh (gr,(sgr,rts)) = do
|
|||||||
cfs = zip concrs cfs,
|
cfs = zip concrs cfs,
|
||||||
pInfos = pinfos, -- peb 8/6
|
pInfos = pinfos, -- peb 8/6
|
||||||
morphos = zip concrs (map (mkMorpho cgr) concrs),
|
morphos = zip concrs (map (mkMorpho cgr) concrs),
|
||||||
gloptions = opts,
|
gloptions = gloptions sh, --- opts, -- this would be command-line options
|
||||||
readFiles = [ft | ft@(f,_) <- readFiles sh, notInrts f] ++ rts,
|
readFiles = [ft | ft@(f,_) <- readFiles sh, notInrts f] ++ rts,
|
||||||
absCats = csi,
|
absCats = csi,
|
||||||
statistics = [StDepTypes deps,StBoundVars binds]
|
statistics = [StDepTypes deps,StBoundVars binds]
|
||||||
@@ -216,22 +217,22 @@ grammar2stateGrammar opts gr = do
|
|||||||
allAbstracts :: CanonGrammar -> [Ident]
|
allAbstracts :: CanonGrammar -> [Ident]
|
||||||
allAbstracts gr = [i | (i,M.ModMod m) <- M.modules gr, M.mtype m == M.MTAbstract]
|
allAbstracts gr = [i | (i,M.ModMod m) <- M.modules gr, M.mtype m == M.MTAbstract]
|
||||||
|
|
||||||
-- the last abstract in dependency order
|
-- the last abstract in dependency order (head of list)
|
||||||
greatestAbstract :: CanonGrammar -> Maybe Ident
|
greatestAbstract :: CanonGrammar -> Maybe Ident
|
||||||
greatestAbstract gr = case allAbstracts gr of
|
greatestAbstract gr = case allAbstracts gr of
|
||||||
[] -> Nothing
|
[] -> Nothing
|
||||||
a -> return $ last a
|
a -> return $ head a
|
||||||
|
|
||||||
-- all resource modules
|
-- all resource modules
|
||||||
allResources :: G.SourceGrammar -> [Ident]
|
allResources :: G.SourceGrammar -> [Ident]
|
||||||
allResources gr = [i | (i,M.ModMod m) <- M.modules gr, M.mtype m == M.MTResource]
|
allResources gr = [i | (i,M.ModMod m) <- M.modules gr, M.mtype m == M.MTResource]
|
||||||
|
|
||||||
|
|
||||||
-- the last resource in dependency order
|
-- the greatest resource in dependency order
|
||||||
greatestResource :: G.SourceGrammar -> Maybe Ident
|
greatestResource :: G.SourceGrammar -> Maybe Ident
|
||||||
greatestResource gr = case allResources gr of
|
greatestResource gr = case allResources gr of
|
||||||
[] -> Nothing
|
[] -> Nothing
|
||||||
a -> return $ last a
|
a -> return $ head a
|
||||||
|
|
||||||
resourceOfShellState :: ShellState -> Maybe Ident
|
resourceOfShellState :: ShellState -> Maybe Ident
|
||||||
resourceOfShellState = greatestResource . srcModules
|
resourceOfShellState = greatestResource . srcModules
|
||||||
|
|||||||
@@ -122,6 +122,15 @@ mapErrN maxN f xs = Ok (ys, unlines (errHdr : ss2))
|
|||||||
nss = length ss
|
nss = length ss
|
||||||
fxs = map f xs
|
fxs = map f xs
|
||||||
|
|
||||||
|
-- like foldM, but also return the latest value if fails
|
||||||
|
|
||||||
|
foldErr :: (a -> b -> Err a) -> a -> [b] -> Err (a, Maybe String)
|
||||||
|
foldErr f s xs = case xs of
|
||||||
|
[] -> return (s,Nothing)
|
||||||
|
x:xx -> case f s x of
|
||||||
|
Ok v -> foldErr f v xx
|
||||||
|
Bad m -> return $ (s, Just m)
|
||||||
|
|
||||||
-- !! with the error monad
|
-- !! with the error monad
|
||||||
(!?) :: [a] -> Int -> Err a
|
(!?) :: [a] -> Int -> Err a
|
||||||
xs !? i = foldr (const . return) (Bad "too few elements in list") $ drop i xs
|
xs !? i = foldr (const . return) (Bad "too few elements in list") $ drop i xs
|
||||||
|
|||||||
@@ -13,10 +13,12 @@ import Arch (selectLater, modifiedFiles, ModTime, getModTime,laterModTime)
|
|||||||
import Option
|
import Option
|
||||||
import Operations
|
import Operations
|
||||||
import UseIO
|
import UseIO
|
||||||
|
|
||||||
import System
|
import System
|
||||||
import Char
|
import Char
|
||||||
import Monad
|
import Monad
|
||||||
import List
|
import List
|
||||||
|
import Directory
|
||||||
|
|
||||||
-- make analysis for GF grammar modules. AR 11/6/2003--24/2/2004
|
-- make analysis for GF grammar modules. AR 11/6/2003--24/2/2004
|
||||||
|
|
||||||
@@ -76,6 +78,7 @@ selectFormat env (p,f) = do
|
|||||||
(Just tenv,_,_,Just tgf) | laterModTime tenv tgf -> CSEnvR
|
(Just tenv,_,_,Just tgf) | laterModTime tenv tgf -> CSEnvR
|
||||||
(_,Just tenv,_,Just tgf) | laterModTime tenv tgf -> CSEnv
|
(_,Just tenv,_,Just tgf) | laterModTime tenv tgf -> CSEnv
|
||||||
(_,_,Just tgfc,Just tgf) | laterModTime tgfc tgf -> CSRead
|
(_,_,Just tgfc,Just tgf) | laterModTime tgfc tgf -> CSRead
|
||||||
|
(_,_,_, Nothing) -> CSRead -- source does not exist
|
||||||
_ -> CSComp
|
_ -> CSComp
|
||||||
return $ (f, (p,stat))
|
return $ (f, (p,stat))
|
||||||
|
|
||||||
@@ -126,9 +129,9 @@ needCompile opts headers sfiles0 = paths $ res $ mark $ iter changed where
|
|||||||
res cs = map mkRes cs where
|
res cs = map mkRes cs where
|
||||||
mkRes x@(f,(path,st)) | elem st [CSRead,CSEnv] = case typ f of
|
mkRes x@(f,(path,st)) | elem st [CSRead,CSEnv] = case typ f of
|
||||||
t | elem t [MTyResource,MTyIncResource] &&
|
t | elem t [MTyResource,MTyIncResource] &&
|
||||||
not (null [m | (m,(_,CSComp)) <- cs,
|
(not (null [m | (m,(_,CSComp)) <- cs,
|
||||||
Just ms <- [lookup m allDeps], elem f ms])
|
Just ms <- [lookup m allDeps], elem f ms])
|
||||||
|| oElem retainOpers opts
|
|| oElem retainOpers opts)
|
||||||
-> (f,(path,CSRes))
|
-> (f,(path,CSRes))
|
||||||
_ -> x
|
_ -> x
|
||||||
mkRes x = x
|
mkRes x = x
|
||||||
@@ -154,9 +157,9 @@ resModName = ('#':)
|
|||||||
|
|
||||||
getImports :: [InitPath] -> FileName -> IOE [(ModuleHeader,InitPath)]
|
getImports :: [InitPath] -> FileName -> IOE [(ModuleHeader,InitPath)]
|
||||||
getImports ps = get [] where
|
getImports ps = get [] where
|
||||||
get ds file = do
|
get ds file0 = do
|
||||||
let name = fileBody file
|
let name = fileBody file0
|
||||||
(p,s) <- readFileIfPath ps $ file
|
(p,s) <- tryRead name
|
||||||
let ((typ,mname),imps) = importsOfFile s
|
let ((typ,mname),imps) = importsOfFile s
|
||||||
ioeErr $ testErr (mname == name) $
|
ioeErr $ testErr (mname == name) $
|
||||||
"module name differs from file name in" +++ name
|
"module name differs from file name in" +++ name
|
||||||
@@ -164,8 +167,17 @@ getImports ps = get [] where
|
|||||||
_ | elem name (map (snd . fst . fst) ds) -> return ds --- file already read
|
_ | elem name (map (snd . fst . fst) ds) -> return ds --- file already read
|
||||||
[] -> return $ (((typ,name),[]),p):ds
|
[] -> return $ (((typ,name),[]),p):ds
|
||||||
_ -> do
|
_ -> do
|
||||||
let files = map (gfFile . fst) imps --- requires there's always .gf file
|
let files = map (gfFile . fst) imps
|
||||||
foldM get ((((typ,name),imps),p):ds) files
|
foldM get ((((typ,name),imps),p):ds) files
|
||||||
|
tryRead name = do
|
||||||
|
file <- do
|
||||||
|
let file_gf = gfFile name
|
||||||
|
b <- doesFileExistPath ps file_gf -- try gf file first
|
||||||
|
if b then return file_gf else return (gfcFile name) -- gfc next
|
||||||
|
|
||||||
|
readFileIfPath ps $ file
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- internal module dep information
|
-- internal module dep information
|
||||||
|
|
||||||
|
|||||||
@@ -76,6 +76,11 @@ readFileIfPath paths file = do
|
|||||||
return (justInitPath pfile,s)
|
return (justInitPath pfile,s)
|
||||||
_ -> ioeErr $ Bad ("File " ++ file ++ " does not exist.")
|
_ -> ioeErr $ Bad ("File " ++ file ++ " does not exist.")
|
||||||
|
|
||||||
|
doesFileExistPath :: [FilePath] -> String -> IOE Bool
|
||||||
|
doesFileExistPath paths file = do
|
||||||
|
mpfile <- ioeIO $ getFilePath paths file
|
||||||
|
return $ maybe False (const True) mpfile
|
||||||
|
|
||||||
pFilePaths :: String -> [FilePath]
|
pFilePaths :: String -> [FilePath]
|
||||||
pFilePaths s = case span (/=':') s of
|
pFilePaths s = case span (/=':') s of
|
||||||
(f,_:cs) -> f : pFilePaths cs
|
(f,_:cs) -> f : pFilePaths cs
|
||||||
@@ -179,6 +184,15 @@ ioeBad = ioe . return . Bad
|
|||||||
useIOE :: a -> IOE a -> IO a
|
useIOE :: a -> IOE a -> IO a
|
||||||
useIOE a ioe = appIOE ioe >>= err (\s -> putStrLn s >> return a) return
|
useIOE a ioe = appIOE ioe >>= err (\s -> putStrLn s >> return a) return
|
||||||
|
|
||||||
|
foldIOE :: (a -> b -> IOE a) -> a -> [b] -> IOE (a, Maybe String)
|
||||||
|
foldIOE f s xs = case xs of
|
||||||
|
[] -> return (s,Nothing)
|
||||||
|
x:xx -> do
|
||||||
|
ev <- ioeIO $ appIOE (f s x)
|
||||||
|
case ev of
|
||||||
|
Ok v -> foldIOE f v xx
|
||||||
|
Bad m -> return $ (s, Just m)
|
||||||
|
|
||||||
putStrLnE :: String -> IOE ()
|
putStrLnE :: String -> IOE ()
|
||||||
putStrLnE = ioeIO . putStrLnFlush
|
putStrLnE = ioeIO . putStrLnFlush
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
module Today where today = "Thu Jun 10 16:36:31 CEST 2004"
|
module Today where today = "Tue Jun 15 16:37:14 CEST 2004"
|
||||||
|
|||||||
Reference in New Issue
Block a user