HaRe-0.6: tools/pfe/PFE3.hs
{-+
PFE level 3: proper parsing of Haskell modules.
-}
module PFE3(module PFE3,XRefInfo) where
import ReAssocModule(reAssocModule)
import ScopeModule(scopeModule,XRefInfo,checkRefs)
import AST4ModSys(toMod)
import Modules(inscope)
import WorkModule(mkWM)
import Relations(emptyRel)
import PrettyPrint(pp,vcat,($$),(<>),(<+>))
import PFE0(Upd,moduleNode,findFile,lexAndPreparseSourceFile,getModuleInfixes,
getModuleImports,updateModuleGraph,batchMode)
import PFE2--(getExports,getModuleExports)
import MUtils
import Monad(when)
--------------------------------------------------------------------------------
type PFE3MT n i ds ext m = PFE2MT n i ds ext m
runPFE3 ext = runPFE2 ext
clean3 = clean2
--getSt3 :: Monad m => PFE3MT n i ds ext m (PFE3Info n)
--updSt3 :: Monad m => Upd (PFE3Info n)->PFE3MT n i ds ext m ()
getSt3ext :: Monad m => PFE3MT n i ds ext m ext
updSt3ext :: Monad m => Upd ext->PFE3MT n i ds ext m ()
--getSt3 = fst # getSt0ext
--updSt3 = updSt0ext . apFst
--setSt3 = updSt3 . const
getSt3ext = getSt2ext
updSt3ext = updSt2ext
setSt3ext = updSt3ext . const
--------------------------------------------------------------------------------
--parseModule :: ... => ModuleName -> m (WorkModule ..,HsModule ...)
--parseSourceFile :: ... => FilePath -> m (WorkModule ..,HsModule ...)
parseModule = parseSourceFile @@ findFile
parseSourceFile f = fst . snd # parseSourceFile' f
refsModule = refsSourceFile @@ findFile
refsSourceFile f = snd . snd # parseSourceFile'' f
parseModule' = parseSourceFile' @@ findFile
-- Parse, rewrite infix applications, check identifiers
parseScopeSourceFile = checkScope . snd @@ parseSourceFile'
where
checkScope (m,refs) = check (checkRefs refs) >> return m
check [] = done
check errs =
fail $ pp $ "Scoping errors" $$ vcat [loc<>":"<+>err|(loc,err)<-errs]
-- Parse and rewrite infix applications according to their fixities
parseSourceFile' path =
do infixes <- getModuleInfixes
let re wm = reAssocModule wm infixes
parseSourceFile''' re path
-- Parse *without* rewriting infixes
parseSourceFile'' = parseSourceFile''' (const id)
-- rewrite: does the rewriting to fix the parse tree when the
-- fixities of operators are known
-- filepath: the file to be parsed
parseSourceFile''' rewrite filepath =
do (ts,mod) <- lexAndPreparseSourceFile filepath
let n@(m,imports) = moduleNode mod
unlessM batchMode $
do oldimports <- getModuleImports m
when (imports/=oldimports) updateModuleGraph
exp <- snd # getModuleExports m
exports <- getExports (Just imports)
let insc = inscope (toMod mod) (expOf exports)
wm = mkWM (insc,exp)
ex = mapSnd snd exports -- drop datestamp
(mod',refs) = scopeModule (wm,ex) (rewrite wm mod)
return (ts,(((wm,ex),mod'),refs))
where
{-+
To prevent pfebrower from crashing if the module graph is inconsistent,
expOf does not fail on references to unknown modules. Instead it returns
an empty export relation...
-}
expOf exports m = maybe emptyRel snd (lookup m exports)
{-
-- For debugging:
expOf exports m =
case lookup m exports of
Just (_,es) -> es
_ -> error $ "PFE3: Didn't find export relation for: "++show m
-}