packages feed

ddc-core-0.4.3.1: DDC/Core/Parser/Base.hs

module DDC.Core.Parser.Base
        ( Parser
        , pModuleName
        , pQualName
        , pName
        , pCon,         pConSP
        , pLit,         pLitSP
        , pIndex,       pIndexSP
        , pVar,         pVarSP,         pVarNamedSP
        , pKey,         pSym
        , pTok,         pTokSP
        , pTokAs,       pTokAsSP
        , pOpSP
        , pOpVarSP
        , pPragmaSP)
where
import DDC.Data.Pretty
import DDC.Core.Module
import DDC.Core.Lexer.Tokens
import DDC.Control.Parser               ((<?>), SourcePos)
import Data.Text                        (Text)
import qualified DDC.Control.Parser     as P

-- | A parser of core language tokens.
type Parser n a
        = P.Parser (Token n) a


-- | Parse a module name.                               
pModuleName :: Pretty n => Parser n ModuleName
pModuleName 
 = do   ms      <- P.sepBy1 pModuleName1 (pTok (KSymbol SDot))
        return  $  ModuleName 
                $  concat
                $  map (\(ModuleName ss) -> ss) ms


-- | Parse a single component module name.
pModuleName1 :: Pretty n => Parser n ModuleName
pModuleName1 = P.pTokMaybe f
 where  f (KN (KCon n))           = Just $ ModuleName [ renderPlain $ ppr n ]

        -- These names are lexed as constructors
        -- but can be part of a module name.
        f (KA (KBuiltin (BSoCon c)))  = Just $ ModuleName [ renderPlain $ ppr c ]
        f (KA (KBuiltin (BKiCon c)))  = Just $ ModuleName [ renderPlain $ ppr c ]
        f (KA (KBuiltin (BTwCon c)))  = Just $ ModuleName [ renderPlain $ ppr c ]
        f (KA (KBuiltin (BTcCon c)))  = Just $ ModuleName [ renderPlain $ ppr c ]
        f _                       = Nothing


-- | Parse a qualified variable or constructor name.
pQualName :: Pretty n => Parser n (QualName n)
pQualName
 = do   mn      <- pModuleName
        pTok    (KSymbol SDot)
        n       <- pName
        return  $ QualName mn n


-- | Parse a constructor or variable name.
pName :: Parser n n
pName   = P.choice [pCon, pVar]


-- | Parse a constructor name.
pCon    :: Parser n n
pCon    = P.pTokMaybe f
 where  f (KN (KCon n)) = Just n
        f _             = Nothing


-- | Parse a constructor name.
pConSP    :: Parser n (n, SourcePos)
pConSP    = P.pTokMaybeSP f
 where  f (KN (KCon n)) = Just n
        f _             = Nothing


-- | Parse a literal.
pLit :: Parser n (Literal, Bool)
pLit    = P.pTokMaybe f
 where  f (KA (KLiteral l b)) = Just (l, b)
        f _                   = Nothing


-- | Parse a numeric literal, with source position.
pLitSP :: Parser n ((Literal, Bool), SourcePos)
pLitSP  = P.pTokMaybeSP f
 where  f (KA (KLiteral l b)) = Just (l, b)
        f _                   = Nothing


-- | Parse a variable.
pVar :: Parser n n
pVar    =   P.pTokMaybe f
        <?> "a variable"
 where  f (KN (KVar n))         = Just n
        f _                     = Nothing


-- | Parse a variable, with source position.
pVarSP :: Parser n (n, SourcePos)
pVarSP  =   P.pTokMaybeSP f
        <?> "a variable"
 where  f (KN (KVar n))         = Just n
        f _                     = Nothing


-- | Parse a variable of a specific name, with its source position.
pVarNamedSP :: String -> Parser String SourcePos
pVarNamedSP str 
        = fmap snd (P.pTokMaybeSP f <?> "a variable")
 where  f (KN (KVar n)) | n == str = Just n
        f _                        = Nothing


-- | Parse a deBruijn index.
pIndex :: Parser n Int
pIndex  =   P.pTokMaybe f
        <?> "an index"
 where  f (KA (KIndex i))       = Just i
        f _                     = Nothing


-- | Parse a deBruijn index, with source position.
pIndexSP :: Parser n (Int, SourcePos)
pIndexSP  =   P.pTokMaybeSP f
        <?> "an index"
 where  f (KA (KIndex i))       = Just i
        f _                     = Nothing


-- | Parse an infix operator.
pOpSP    :: Parser n (String, SourcePos)
pOpSP    = P.pTokMaybeSP f
 where  f (KA (KOp str))  = Just str
        f _               = Nothing


-- | Parse an infix operator used as a variable.
pOpVarSP :: Parser n (String, SourcePos)
pOpVarSP = P.pTokMaybeSP f
 where  f (KA (KOpVar str))  = Just str
        f _                  = Nothing


-- | Parse a pragma.
pPragmaSP :: Parser n (Text, SourcePos)
pPragmaSP = P.pTokMaybeSP f
 where  f (KA (KPragma txt))  = Just txt
        f _                   = Nothing

-------------------------------------------------------------------------------
-- | Parse a `Symbol`.
pSym :: Symbol  -> Parser n SourcePos
pSym ss = P.pTokSP (KA (KSymbol ss))


-- | Parse a `Keyword`.
pKey :: Keyword -> Parser n SourcePos
pKey kw = P.pTokSP (KA (KKeyword kw))


-------------------------------------------------------------------------------
-- | Parse an atomic token.
pTok   :: TokenAtom -> Parser n ()
pTok k     = P.pTok (KA k)


-- | Parse an atomic token, yielding its source position.
pTokSP :: TokenAtom -> Parser n SourcePos
pTokSP k   = P.pTokSP (KA k)


-- | Parse an atomic token and return some value.
pTokAs :: TokenAtom -> a -> Parser n a
pTokAs k x = P.pTokAs (KA k) x


-- | Parse an atomic token and return source position and value.
pTokAsSP :: TokenAtom -> a -> Parser n (a, SourcePos)
pTokAsSP k x = P.pTokAsSP (KA k) x