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 -}