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

Plain-text version of PFE3.hs | Valid HTML?