module DDC.Core.Parser.Param
( ParamSpec (..)
, funTypeOfParams
, expOfParams
, pBindParamSpec)
where
import DDC.Core.Exp
import DDC.Core.Parser.Type
import DDC.Core.Parser.Base (Parser)
import DDC.Core.Lexer.Tokens
import qualified DDC.Base.Parser as P
import qualified DDC.Type.Compounds as T
data ParamSpec n
= ParamType (Bind n)
| ParamWitness (Bind n)
| ParamValue (Bind n) (Type n) (Type n)
funTypeOfParams
:: [ParamSpec n]
-> Type n
-> Type n
funTypeOfParams [] tBody = tBody
funTypeOfParams (p:ps) tBody
= case p of
ParamType b
-> TForall b
$ funTypeOfParams ps tBody
ParamWitness b
-> T.tImpl (T.typeOfBind b)
$ funTypeOfParams ps tBody
ParamValue b eff clo
-> T.tFun (T.typeOfBind b) eff clo
$ funTypeOfParams ps tBody
expOfParams
:: a
-> [ParamSpec n]
-> Exp a n
-> Exp a n
expOfParams _ [] xBody = xBody
expOfParams a (p:ps) xBody
= case p of
ParamType b
-> XLAM a b $ expOfParams a ps xBody
ParamWitness b
-> XLam a b $ expOfParams a ps xBody
ParamValue b _ _
-> XLam a b $ expOfParams a ps xBody
pBindParamSpec :: Ord n => Parser n [ParamSpec n]
pBindParamSpec
= P.choice
[ do pTok KSquareBra
bs <- P.many1 pBinder
pTok KColon
t <- pType
pTok KSquareKet
return [ ParamType b
| b <- zipWith T.makeBindFromBinder bs (repeat t)]
, do pTok KAngleBra
b <- pBinder
pTok KColon
t <- pType
pTok KAngleKet
return [ ParamWitness $ T.makeBindFromBinder b t]
, do pTok KRoundBra
b <- pBinder
pTok KColon
t <- pType
pTok KRoundKet
(eff, clo)
<- P.choice
[ do pTok KBraceBra
eff' <- pType
pTok KBar
clo' <- pType
pTok KBraceKet
return (eff', clo')
, do return (T.tBot T.kEffect, T.tBot T.kClosure) ]
return $ [ParamValue (T.makeBindFromBinder b t) eff clo]
]