ddc-core-0.4.2.1: DDC/Core/Parser/DataDef.hs
module DDC.Core.Parser.DataDef
( DataDef (..)
, pDataDef)
where
import DDC.Core.Exp.Annot
import DDC.Core.Parser.Type
import DDC.Core.Parser.Context
import DDC.Core.Parser.Base
import DDC.Core.Lexer.Tokens
import DDC.Type.DataDef
import Control.Monad
import qualified DDC.Base.Parser as P
pDataDef :: Ord n => Context n -> Parser n (DataDef n)
pDataDef c
= do pTokSP KData
nData <- pName
bsParam <- liftM concat $ P.many (pDataParam c)
P.choice
[ -- Data declaration with constructors that have explicit types.
do pTok KWhere
pTok KBraceBra
ctors <- P.sepEndBy1 (pDataCtor c nData bsParam) (pTok KSemiColon)
let ctors' = [ ctor { dataCtorTag = tag }
| ctor <- ctors
| tag <- [0..] ]
pTok KBraceKet
return $ DataDef
{ dataDefTypeName = nData
, dataDefParams = bsParam
, dataDefCtors = Just ctors'
, dataDefIsAlgebraic = True }
-- Data declaration with no data constructors.
, do return $ DataDef
{ dataDefTypeName = nData
, dataDefParams = bsParam
, dataDefCtors = Just []
, dataDefIsAlgebraic = True }
]
-- | Parse a type parameter to a data type.
pDataParam :: Ord n => Context n -> Parser n [Bind n]
pDataParam c
= do pTok KRoundBra
ns <- P.many1 pName
pTokSP (KOp ":")
k <- pType c
pTok KRoundKet
return [BName n k | n <- ns]
-- | Parse a data constructor declaration.
pDataCtor
:: Ord n
=> Context n
-> n -- ^ Name of data type constructor.
-> [Bind n] -- ^ Type parameters of data type constructor.
-> Parser n (DataCtor n)
pDataCtor c nData bsParam
= do n <- pName
pTokSP (KOp ":")
t <- pType c
let (tsArg, tResult)
= takeTFunArgResult t
return $ DataCtor
{ dataCtorName = n
-- Set tag to 0 for now. We fix this up in pDataDef above.
, dataCtorTag = 0
, dataCtorFieldTypes = tsArg
, dataCtorResultType = tResult
, dataCtorTypeName = nData
, dataCtorTypeParams = bsParam }