-- | Parsers for unit/module identifiers
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 :: ReadP Unit
parseUnit = ReadP Unit
parseVirtUnitId forall a. ReadP a -> ReadP a -> ReadP a
<++ ReadP Unit
parseDefUnitId
  where
    parseVirtUnitId :: ReadP Unit
parseVirtUnitId = do
        IndefUnitId
uid   <- ReadP IndefUnitId
parseIndefUnitId
        [(ModuleName, Module)]
insts <- ReadP [(ModuleName, Module)]
parseModSubst
        forall (m :: * -> *) a. Monad m => a -> m a
return (forall u.
IsUnitId u =>
Indefinite u -> [(ModuleName, GenModule (GenUnit u))] -> GenUnit u
mkVirtUnit IndefUnitId
uid [(ModuleName, Module)]
insts)
    parseDefUnitId :: ReadP Unit
parseDefUnitId = do
        UnitId
s <- ReadP UnitId
parseUnitId
        forall (m :: * -> *) a. Monad m => a -> m a
return (forall uid. Definite uid -> GenUnit uid
RealUnit (forall unit. unit -> Definite unit
Definite UnitId
s))

parseUnitId :: ReadP UnitId
parseUnitId :: ReadP UnitId
parseUnitId = do
   String
s <- (Char -> Bool) -> ReadP String
Parse.munch1 (\Char
c -> Char -> Bool
isAlphaNum Char
c Bool -> Bool -> Bool
|| Char
c forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` String
"-_.+")
   forall (m :: * -> *) a. Monad m => a -> m a
return (FastString -> UnitId
UnitId (String -> FastString
mkFastString String
s))

parseIndefUnitId :: ReadP IndefUnitId
parseIndefUnitId :: ReadP IndefUnitId
parseIndefUnitId = do
   UnitId
uid <- ReadP UnitId
parseUnitId
   forall (m :: * -> *) a. Monad m => a -> m a
return (forall unit. unit -> Indefinite unit
Indefinite UnitId
uid)

parseHoleyModule :: ReadP Module
parseHoleyModule :: ReadP Module
parseHoleyModule = forall {uid}. ReadP (GenModule (GenUnit uid))
parseModuleVar forall a. ReadP a -> ReadP a -> ReadP a
<++ ReadP Module
parseModule
    where
      parseModuleVar :: ReadP (GenModule (GenUnit uid))
parseModuleVar = do
        Char
_ <- Char -> ReadP Char
Parse.char Char
'<'
        ModuleName
modname <- ReadP ModuleName
parseModuleName
        Char
_ <- Char -> ReadP Char
Parse.char Char
'>'
        forall (m :: * -> *) a. Monad m => a -> m a
return (forall unit. unit -> ModuleName -> GenModule unit
Module forall uid. GenUnit uid
HoleUnit ModuleName
modname)
      parseModule :: ReadP Module
parseModule = do
        Unit
uid <- ReadP Unit
parseUnit
        Char
_ <- Char -> ReadP Char
Parse.char Char
':'
        ModuleName
modname <- ReadP ModuleName
parseModuleName
        forall (m :: * -> *) a. Monad m => a -> m a
return (forall unit. unit -> ModuleName -> GenModule unit
Module Unit
uid ModuleName
modname)

parseModSubst :: ReadP [(ModuleName, Module)]
parseModSubst :: ReadP [(ModuleName, Module)]
parseModSubst = forall open close a.
ReadP open -> ReadP close -> ReadP a -> ReadP a
Parse.between (Char -> ReadP Char
Parse.char Char
'[') (Char -> ReadP Char
Parse.char Char
']')
      forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a sep. ReadP a -> ReadP sep -> ReadP [a]
Parse.sepBy (Char -> ReadP Char
Parse.char Char
',')
      forall a b. (a -> b) -> a -> b
$ do ModuleName
k <- ReadP ModuleName
parseModuleName
           Char
_ <- Char -> ReadP Char
Parse.char Char
'='
           Module
v <- ReadP Module
parseHoleyModule
           forall (m :: * -> *) a. Monad m => a -> m a
return (ModuleName
k, Module
v)