module CLaSH.Netlist.BlackBox.Parser
(runParse)
where
import Data.ListLike.Text.TextLazy ()
import Data.Text.Lazy (Text, pack)
import Text.ParserCombinators.UU
import Text.ParserCombinators.UU.BasicInstances hiding (Parser)
import qualified Text.ParserCombinators.UU.Core as PCC (parse)
import Text.ParserCombinators.UU.Utils hiding (pBrackets)
import CLaSH.Netlist.BlackBox.Types
type Parser a = P (Str Char Text LineColPos) a
runParse :: Text -> (BlackBoxTemplate, [Error LineColPos])
runParse = PCC.parse ((,) <$> pBlackBoxD <*> pEnd)
. createStr (LineColPos 0 0 0)
pBlackBoxD :: Parser BlackBoxTemplate
pBlackBoxD = pSome pElement
pElement :: Parser Element
pElement = pTagD
<|> C <$> pText
pText :: Parser Text
pText = pack <$> pList1 (pRange ('\000','\125'))
pTagD :: Parser Element
pTagD = D <$> pDecl
<|> pTagE
pDecl :: Parser Decl
pDecl = Decl <$> (pTokenWS "~INST" *> pNatural) <*>
((:) <$> pOutput <*> pList pInput) <* pToken "~INST"
pOutput :: Parser BlackBoxTemplate
pOutput = pTokenWS "~OUTPUT" *> pTokenWS "<=" *> pBlackBoxE <* pTokenWS "~"
pInput :: Parser BlackBoxTemplate
pInput = pTokenWS "~INPUT" *> pTokenWS "<=" *> pBlackBoxE <* pTokenWS "~"
pTagE :: Parser Element
pTagE = O <$ pToken "~RESULT"
<|> I <$> (pToken "~ARG" *> pBrackets pNatural)
<|> I <$> (pToken "~LIT" *> pBrackets pNatural)
<|> (Clk . Just) <$> (pToken "~CLK" *> pBrackets pNatural)
<|> Clk Nothing <$ pToken "~CLKO"
<|> (Rst . Just) <$> (pToken "~RST" *> pBrackets pNatural)
<|> Rst Nothing <$ pToken "~RSTO"
<|> Sym <$> (pToken "~SYM" *> pBrackets pNatural)
<|> Typ Nothing <$ pToken "~TYPO"
<|> (Typ . Just) <$> (pToken "~TYP" *> pBrackets pNatural)
<|> TypM Nothing <$ pToken "~TYPMO"
<|> (TypM . Just) <$> (pToken "~TYPM" *> pBrackets pNatural)
<|> Def Nothing <$ pToken "~DEFAULTO"
<|> (Def . Just) <$> (pToken "~DEFAULT" *> pBrackets pNatural)
pBrackets :: Parser a -> Parser a
pBrackets p = pSym '[' *> p <* pSym ']'
pTokenWS :: String -> Parser String
pTokenWS keyw = pToken keyw <* pSpaces
pBlackBoxE :: Parser BlackBoxTemplate
pBlackBoxE = pSome pElemE
pElemE :: Parser Element
pElemE = pTagE
<|> C <$> pText