module CLaSH.Netlist.BlackBox.Parser
(runParse)
where
import Data.Text.Lazy (Text, pack)
import qualified Data.Text.Lazy as Text
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
<|> C <$> (pack <$> pToken "~ ")
pText :: Parser Text
pText = pack <$> pList1 (pRange ('\000','\125'))
pTagD :: Parser Element
pTagD = IF <$> (pTokenWS "~IF" *> pTagE)
<*> (pSpaces *> (pToken "~THEN" *> pBlackBoxD))
<*> (pToken "~ELSE" *> pBlackBoxD <* pToken "~FI")
<|> D <$> pDecl
<|> pTagE
pDecl :: Parser Decl
pDecl = Decl <$> (pTokenWS "~INST" *> pNatural) <*>
((:) <$> pOutput <*> pList pInput) <* pToken "~INST"
pOutput :: Parser (BlackBoxTemplate,BlackBoxTemplate)
pOutput = pTokenWS "~OUTPUT" *> pTokenWS "<=" *> ((,) <$> (pBlackBoxE <* pTokenWS "~") <*> pBlackBoxE) <* pTokenWS "~"
pInput :: Parser (BlackBoxTemplate,BlackBoxTemplate)
pInput = pTokenWS "~INPUT" *> pTokenWS "<=" *> ((,) <$> (pBlackBoxE <* pTokenWS "~") <*> pBlackBoxE) <* pTokenWS "~"
pTagE :: Parser Element
pTagE = O <$ pToken "~RESULT"
<|> I <$> (pToken "~ARG" *> pBrackets pNatural)
<|> L <$> (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 Text.empty) <$> (pToken "~SYM" *> pBrackets pNatural)
<|> Typ Nothing <$ pToken "~TYPO"
<|> (Typ . Just) <$> (pToken "~TYP" *> pBrackets pNatural)
<|> TypM Nothing <$ pToken "~TYPMO"
<|> (TypM . Just) <$> (pToken "~TYPM" *> pBrackets pNatural)
<|> Err Nothing <$ pToken "~ERRORO"
<|> (Err . Just) <$> (pToken "~ERROR" *> pBrackets pNatural)
<|> TypElem <$> (pToken "~TYPEL" *> pBrackets pTagE)
<|> IndexType <$> (pToken "~INDEXTYPE" *> pBrackets pTagE)
<|> CompName <$ pToken "~COMPNAME"
<|> Size <$> (pToken "~SIZE" *> pBrackets pTagE)
<|> Length <$> (pToken "~LENGTH" *> pBrackets pTagE)
<|> FilePath <$> (pToken "~FILE" *> pBrackets pTagE)
<|> Gen <$> (True <$ pToken "~GENERATE")
<|> Gen <$> (False <$ pToken "~ENDGENERATE")
<|> SigD <$> (pToken "~SIGD" *> pBrackets pSigD) <*> (Just <$> (pBrackets pNatural))
<|> (`SigD` Nothing) <$> (pToken "~SIGDO" *> pBrackets pSigD)
<|> IW64 <$ pToken "~IW64"
<|> (HdlSyn Vivado) <$ pToken "~VIVADO"
<|> (HdlSyn Other) <$ pToken "~OTHERSYN"
<|> (BV True) <$> (pToken "~TOBV" *> pBrackets pSigD) <*> pBrackets pTagE
<|> (BV False) <$> (pToken "~FROMBV" *> pBrackets pSigD) <*> pBrackets pTagE
<|> IsLit <$> (pToken "~ISLIT" *> pBrackets pNatural)
<|> IsVar <$> (pToken "~ISVAR" *> pBrackets pNatural)
<|> GenSym <$> (pToken "~GENSYM" *> pBrackets pSigD) <*> pBrackets pNatural
<|> And <$> (pToken "~AND" *> listParser pTagE)
<|> Vars <$> (pToken "~VARS" *> 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
pSigD :: Parser [Element]
pSigD = pSome (pTagE <|> (C (pack "[") <$ (pack <$> pToken "[\\"))
<|> (C (pack "]") <$ (pack <$> pToken "\\]"))
<|> (C <$> (pack <$> pList1 (pRange ('\000','\90'))))
<|> (C <$> (pack <$> pList1 (pRange ('\94','\125')))))