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