module GHC.Unit.Parser
( parseUnit
, parseIndefUnitId
, parseHoleyModule
, parseModSubst
)
where
import GHC.Prelude
import GHC.Unit.Types
import GHC.Unit.Module.Name
import GHC.Data.FastString
import qualified Text.ParserCombinators.ReadP as Parse
import Text.ParserCombinators.ReadP (ReadP, (<++))
import Data.Char (isAlphaNum)
parseUnit :: ReadP Unit
parseUnit = parseVirtUnitId <++ parseDefUnitId
where
parseVirtUnitId = do
uid <- parseIndefUnitId
insts <- parseModSubst
return (mkVirtUnit uid insts)
parseDefUnitId = do
s <- parseUnitId
return (RealUnit (Definite s))
parseUnitId :: ReadP UnitId
parseUnitId = do
s <- Parse.munch1 (\c -> isAlphaNum c || c `elem` "-_.+")
return (UnitId (mkFastString s))
parseIndefUnitId :: ReadP IndefUnitId
parseIndefUnitId = do
uid <- parseUnitId
return (Indefinite uid Nothing)
parseHoleyModule :: ReadP Module
parseHoleyModule = parseModuleVar <++ parseModule
where
parseModuleVar = do
_ <- Parse.char '<'
modname <- parseModuleName
_ <- Parse.char '>'
return (Module HoleUnit modname)
parseModule = do
uid <- parseUnit
_ <- Parse.char ':'
modname <- parseModuleName
return (Module uid modname)
parseModSubst :: ReadP [(ModuleName, Module)]
parseModSubst = Parse.between (Parse.char '[') (Parse.char ']')
. flip Parse.sepBy (Parse.char ',')
$ do k <- parseModuleName
_ <- Parse.char '='
v <- parseHoleyModule
return (k, v)