module DDC.Core.Parser.Witness ( pWitness , pWitnessApp , pWitnessAtom) where import DDC.Core.Parser.Type import DDC.Core.Parser.Context import DDC.Core.Parser.Base import DDC.Core.Lexer.Tokens import DDC.Core.Exp import DDC.Base.Parser ((), SourcePos) import qualified DDC.Base.Parser as P import qualified DDC.Type.Compounds as T import Control.Monad -- | Parse a witness expression. pWitness :: Ord n => Context -> Parser n (Witness SourcePos n) pWitness c = pWitnessJoin c -- | Parse a witness join. pWitnessJoin :: Ord n => Context -> Parser n (Witness SourcePos n) pWitnessJoin c -- WITNESS or WITNESS & WITNESS = do w1 <- pWitnessApp c P.choice [ do sp <- pTokSP KAmpersand w2 <- pWitnessJoin c return (WJoin sp w1 w2) , do return w1 ] -- | Parse a witness application. pWitnessApp :: Ord n => Context -> Parser n (Witness SourcePos n) pWitnessApp c = do (x:xs) <- P.many1 (pWitnessArgSP c) let x' = fst x let sp = snd x let xs' = map fst xs return $ foldl (WApp sp) x' xs' "a witness expression or application" -- | Parse a witness argument. pWitnessArgSP :: Ord n => Context -> Parser n (Witness SourcePos n, SourcePos) pWitnessArgSP c = P.choice [ -- [TYPE] do sp <- pTokSP KSquareBra t <- pType c pTok KSquareKet return (WType sp t, sp) -- WITNESS , do pWitnessAtomSP c ] -- | Parse a variable, constructor or parenthesised witness. pWitnessAtom :: Ord n => Context -> Parser n (Witness SourcePos n) pWitnessAtom c = liftM fst (pWitnessAtomSP c) -- | Parse a variable, constructor or parenthesised witness, -- also returning source position. pWitnessAtomSP :: Ord n => Context -> Parser n (Witness SourcePos n, SourcePos) pWitnessAtomSP c = P.choice -- (WITNESS) [ do sp <- pTokSP KRoundBra w <- pWitness c pTok KRoundKet return (w, sp) -- Named constructors , do (con, sp) <- pConSP return (WCon sp (WiConBound (UName con) (T.tBot T.kWitness)), sp) -- Baked-in witness constructors. , do (wb, sp) <- pWbConSP return (WCon sp (WiConBuiltin wb), sp) -- Debruijn indices , do (i, sp) <- pIndexSP return (WVar sp (UIx i), sp) -- Variables , do (var, sp) <- pVarSP return (WVar sp (UName var), sp) ] "a witness"