morloc-0.33.0: library/Morloc/CodeGenerator/Grammars/Macro.hs
{-|
Module : Morloc.CodeGenerator.Grammars.Macro
Description : Expand parameters in concrete types
Copyright : (c) Zebulun Arendsee, 2020
License : GPL-3
Maintainer : zbwrnz@gmail.com
Stability : experimental
-}
module Morloc.CodeGenerator.Grammars.Macro
( expandMacro
, expandType
) where
import Morloc.CodeGenerator.Namespace
import Morloc.Data.Doc
import qualified Morloc.Data.Text as MT
import qualified Control.Monad.State as CMS
import Text.Megaparsec
import Text.Megaparsec.Char
import Data.Void (Void)
import qualified Text.Megaparsec.Char.Lexer as L
type Parser a = CMS.StateT ParserState (Parsec Void MT.Text) a
data ParserState = ParserState {
stateParameters :: [MT.Text]
}
expandType
:: (MDoc -> [MDoc] -> MDoc) -- ^ make function type
-> (PVar -> [(PVar, MDoc)] -> MDoc) -- ^ make record type
-> TypeP
-> MDoc
expandType mkfun mkrec t0 = f t0 where
f :: TypeP -> MDoc
f (VarP (PV _ _ v)) = pretty v
f t@(FunP t1 _) = mkfun (f t1) (map f (decomposeFull t))
f (ArrP (PV _ _ v) ts) = pretty $ expandMacro v (map (render . f) ts)
f (NamP _ v _ entries) = mkrec v [(k, f t) | (k, t) <- entries]
f (UnkP _) = error "Cannot build unsolved type"
expandMacro :: MT.Text -> [MT.Text] -> MT.Text
expandMacro t [] = t
expandMacro t ps =
case runParser
(CMS.runStateT (pBase <* eof) (ParserState ps))
"typemacro"
t of
Left err -> error (show err)
Right (es, _) -> es
many1 :: Parser a -> Parser [a]
many1 p = do
x <- p
xs <- many p
return (x : xs)
pBase :: Parser MT.Text
pBase = MT.concat <$> many1 (pChar <|> pMacro)
pChar :: Parser MT.Text
pChar = MT.pack <$> many1 (noneOf ['$'])
pMacro :: Parser MT.Text
pMacro = do
xs <- CMS.gets stateParameters
_ <- string "$"
n <- L.decimal
-- index is 1-based
let i = n - 1
return (xs !! i)