working on naming parsers
This commit is contained in:
parent
193210273d
commit
17ed883f96
2
TODO.md
2
TODO.md
|
@ -42,6 +42,8 @@
|
||||||
- [x] Remove all instances of `_ <-`
|
- [x] Remove all instances of `_ <-`
|
||||||
- [ ] Module
|
- [ ] Module
|
||||||
- [ ] Remove weird GHC imports
|
- [ ] Remove weird GHC imports
|
||||||
|
- [ ] Embed locs in AST
|
||||||
|
- [ ] Remove `preProcessDiscardComments` from exports
|
||||||
- [x] Are the `try` statements in `pWireOption` correctly constructed?
|
- [x] Are the `try` statements in `pWireOption` correctly constructed?
|
||||||
- [ ] Consider the very weird case where the process body has nothing,
|
- [ ] Consider the very weird case where the process body has nothing,
|
||||||
thus, `pEolAndAdvanceToNextNonWs` may never get invoked in any of
|
thus, `pEolAndAdvanceToNextNonWs` may never get invoked in any of
|
||||||
|
|
|
@ -18,7 +18,7 @@ main = do
|
||||||
-- Attempt to read the file
|
-- Attempt to read the file
|
||||||
contents <- catch (readFile filePath) handleReadError
|
contents <- catch (readFile filePath) handleReadError
|
||||||
putStrLn "File Contents:"
|
putStrLn "File Contents:"
|
||||||
putStrLn contents
|
putStrLn $ Haskellator.preProcessDiscardComments contents
|
||||||
[] -> putStrLn "cabal run Haskellator -- <file-path>"
|
[] -> putStrLn "cabal run Haskellator -- <file-path>"
|
||||||
putStrLn $ ppShow Haskellator.val
|
putStrLn $ ppShow Haskellator.val
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,11 @@
|
||||||
module Haskellator(val) where
|
module Haskellator(
|
||||||
|
val,
|
||||||
|
preProcessDiscardComments,
|
||||||
|
runParser
|
||||||
|
) where
|
||||||
|
|
||||||
import RTLILParser.Parser(val)
|
import RTLILParser.Parser(
|
||||||
|
val,
|
||||||
|
preProcessDiscardComments,
|
||||||
|
runParser,
|
||||||
|
)
|
|
@ -1,6 +1,6 @@
|
||||||
module RTLILParser.Parser(
|
module RTLILParser.Parser(
|
||||||
preProcessDiscardComments,
|
preProcessDiscardComments,
|
||||||
pFile,
|
RTLILParser.Parser.runParser,
|
||||||
a,
|
a,
|
||||||
val) where
|
val) where
|
||||||
|
|
||||||
|
@ -68,16 +68,24 @@ import RTLILParser.Primitives(
|
||||||
-- taken from: https://yosyshq.readthedocs.io/projects/yosys/en/0.47/appendix/rtlil_text.html
|
-- taken from: https://yosyshq.readthedocs.io/projects/yosys/en/0.47/appendix/rtlil_text.html
|
||||||
-- parsers below are split int sections from the above link
|
-- parsers below are split int sections from the above link
|
||||||
|
|
||||||
|
runParser str = case parse pFile "pFile" preProcessedFile of
|
||||||
|
Left err -> error $ show err
|
||||||
|
Right val -> val
|
||||||
|
where preProcessedFile = preProcessDiscardComments str
|
||||||
|
|
||||||
-- identifiers
|
-- identifiers
|
||||||
pId :: Parser Id
|
pId :: Parser Id
|
||||||
pId = Public <$> pPublicId
|
pId = Public <$> pPublicId
|
||||||
<|> Autogen <$> pAutogenId
|
<|> Autogen <$> pAutogenId
|
||||||
|
<?> "Id"
|
||||||
|
|
||||||
pPublicId :: Parser PublicId
|
pPublicId :: Parser PublicId
|
||||||
pPublicId = PublicId <$> (char '\\' *> many1 pNonWs)
|
pPublicId = PublicId <$> (char '\\' *> many1 pNonWs)
|
||||||
|
<?> "PublicId"
|
||||||
|
|
||||||
pAutogenId :: Parser AutogenId
|
pAutogenId :: Parser AutogenId
|
||||||
pAutogenId = AutogenId <$> (char '$' *> many1 pNonWs)
|
pAutogenId = AutogenId <$> (char '$' *> many1 pNonWs)
|
||||||
|
<?> "AutogenId"
|
||||||
|
|
||||||
-- values
|
-- values
|
||||||
pValue :: Parser Value
|
pValue :: Parser Value
|
||||||
|
@ -86,6 +94,7 @@ pValue = do
|
||||||
char '\''
|
char '\''
|
||||||
value <- many pBinaryDigit
|
value <- many pBinaryDigit
|
||||||
return $ Value (read width) (binaryStringToInt value)
|
return $ Value (read width) (binaryStringToInt value)
|
||||||
|
<?> "Value"
|
||||||
|
|
||||||
pDecimalDigit :: Parser Char
|
pDecimalDigit :: Parser Char
|
||||||
pDecimalDigit = oneOf "0123456789"
|
pDecimalDigit = oneOf "0123456789"
|
||||||
|
@ -93,7 +102,7 @@ pDecimalDigit = oneOf "0123456789"
|
||||||
-- update in the future to support 4 state logic
|
-- update in the future to support 4 state logic
|
||||||
-- by converting x and z to 0 and warning about it.
|
-- by converting x and z to 0 and warning about it.
|
||||||
pBinaryDigit :: Parser Char
|
pBinaryDigit :: Parser Char
|
||||||
pBinaryDigit = oneOf "01"
|
pBinaryDigit = oneOf "01" <?> "BinaryDigit"
|
||||||
|
|
||||||
pInteger :: Parser Int
|
pInteger :: Parser Int
|
||||||
pInteger = do
|
pInteger = do
|
||||||
|
@ -103,37 +112,46 @@ pInteger = do
|
||||||
return $ case sign of
|
return $ case sign of
|
||||||
Just _ -> -value
|
Just _ -> -value
|
||||||
Nothing -> value
|
Nothing -> value
|
||||||
|
<?> "Integer"
|
||||||
|
|
||||||
-- strings
|
-- strings
|
||||||
pString :: Parser String
|
pString :: Parser String
|
||||||
pString =
|
pString =
|
||||||
between delimiter delimiter parseString
|
between delimiter delimiter parseString
|
||||||
|
<?> "String"
|
||||||
where
|
where
|
||||||
delimiter = char '"'
|
delimiter = char '"'
|
||||||
parseString = many (pEscapedChar <|> noneOf "\\\"")
|
parseString = many (pEscapedChar <|> noneOf "\\\"")
|
||||||
|
|
||||||
-- comments
|
-- comments
|
||||||
-- | Removes inline comments starting with '#' while preserving newlines
|
-- | Removes entire comment lines starting with '#' and inline comments
|
||||||
preProcessDiscardComments :: String -> String
|
preProcessDiscardComments :: String -> String
|
||||||
preProcessDiscardComments input = unlines $ map stripComment $ lines input
|
preProcessDiscardComments input =
|
||||||
|
unlines $ map stripComment $ filter (not . isCommentLine) $ lines input
|
||||||
where
|
where
|
||||||
-- Strips comments from a single line
|
-- Checks if a line is a comment line (starts with '#')
|
||||||
|
isCommentLine line = case dropWhile (== ' ') line of
|
||||||
|
('#':_) -> True -- Line starts with '#'
|
||||||
|
_ -> False -- Line does not start with '#'
|
||||||
|
|
||||||
|
-- Strips inline comments from a single line
|
||||||
stripComment line = case break (== '#') line of
|
stripComment line = case break (== '#') line of
|
||||||
(code, "") -> code -- No comment found
|
(code, "") -> code -- No comment found
|
||||||
(code, _) -> code -- Strip everything after '#'
|
(code, _) -> code -- Strip everything after '#'
|
||||||
|
|
||||||
|
|
||||||
-- file
|
-- file
|
||||||
pFile :: Parser File
|
pFile :: Parser File
|
||||||
pFile = File
|
pFile = File
|
||||||
<$> pAutoIdxStmt
|
<$> pAutoIdxStmt
|
||||||
<*> many pModule
|
<*> many pModule
|
||||||
|
<?> "File"
|
||||||
|
|
||||||
-- Autoindex statements
|
-- Autoindex statements
|
||||||
pAutoIdxStmt :: Parser AutoIdxStmt
|
pAutoIdxStmt :: Parser AutoIdxStmt
|
||||||
pAutoIdxStmt = AutoIdxStmt
|
pAutoIdxStmt = AutoIdxStmt
|
||||||
<$> (string "autoidx" *> pWs *>
|
<$> (string "autoidx" *> pWs *>
|
||||||
pInteger <* pEolAndAdvanceToNextNonWs)
|
pInteger <* pEolAndAdvanceToNextNonWs)
|
||||||
|
<?> "AutoIdxStmt"
|
||||||
|
|
||||||
-- Module
|
-- Module
|
||||||
pModule :: Parser Module
|
pModule :: Parser Module
|
||||||
|
@ -143,15 +161,18 @@ pModule = do
|
||||||
moduleBody <- pModuleBody
|
moduleBody <- pModuleBody
|
||||||
pModuleEndStmt
|
pModuleEndStmt
|
||||||
return $ Module moduleStmt attrs moduleBody
|
return $ Module moduleStmt attrs moduleBody
|
||||||
|
<?> "Module"
|
||||||
|
|
||||||
pModuleStmt :: Parser ModuleStmt
|
pModuleStmt :: Parser ModuleStmt
|
||||||
pModuleStmt = ModuleStmt
|
pModuleStmt = ModuleStmt
|
||||||
<$> (string "module" *> pWs *>
|
<$> (string "module" *> pWs *>
|
||||||
pId <* pEolAndAdvanceToNextNonWs)
|
pId <* pEolAndAdvanceToNextNonWs)
|
||||||
|
<?> "ModuleStmt"
|
||||||
|
|
||||||
pModuleBody :: Parser ModuleBody
|
pModuleBody :: Parser ModuleBody
|
||||||
pModuleBody = ModuleBody
|
pModuleBody = ModuleBody
|
||||||
<$> many pModuleBodyVariant
|
<$> many pModuleBodyVariant
|
||||||
|
<?> "ModuleBody"
|
||||||
|
|
||||||
pModuleBodyVariant :: Parser ModuleBodyVariant
|
pModuleBodyVariant :: Parser ModuleBodyVariant
|
||||||
pModuleBodyVariant =
|
pModuleBodyVariant =
|
||||||
|
@ -167,32 +188,45 @@ pModuleBodyVariant =
|
||||||
try (ModuleBodyMemory <$> pMemory ) <|>
|
try (ModuleBodyMemory <$> pMemory ) <|>
|
||||||
try (ModuleBodyCell <$> pCell ) <|>
|
try (ModuleBodyCell <$> pCell ) <|>
|
||||||
(ModuleBodyProcess <$> pProcess )
|
(ModuleBodyProcess <$> pProcess )
|
||||||
|
<?> "ModuleBodyVariant"
|
||||||
|
|
||||||
pParamStmt :: Parser ParamStmt
|
pParamStmt :: Parser ParamStmt
|
||||||
pParamStmt = ParamStmt
|
pParamStmt = ParamStmt
|
||||||
<$> (string "parameter" *> pWs *> pId <* pWs)
|
<$> (string "parameter" *> pWs *> pId <* pWs)
|
||||||
<*> optionMaybe pConstant
|
<*> optionMaybe pConstant
|
||||||
<* pEolAndAdvanceToNextNonWs
|
<* pEolAndAdvanceToNextNonWs
|
||||||
|
<?> "ParamStmt"
|
||||||
|
|
||||||
pConstant :: Parser Constant
|
pConstant :: Parser Constant
|
||||||
pConstant =
|
pConstant = p <?> name where
|
||||||
|
name = "Constant"
|
||||||
|
p =
|
||||||
try (ConstantValue <$> pValue )
|
try (ConstantValue <$> pValue )
|
||||||
<|> (ConstantInteger <$> pInteger)
|
<|> (ConstantInteger <$> pInteger)
|
||||||
<|> (ConstantString <$> pString )
|
<|> (ConstantString <$> pString )
|
||||||
|
|
||||||
pModuleEndStmt :: Parser ()
|
pModuleEndStmt :: Parser ()
|
||||||
pModuleEndStmt = void (string "end")
|
pModuleEndStmt = p <?> name where
|
||||||
|
name = "ModuleEndStmt"
|
||||||
|
p =
|
||||||
|
void (string "end")
|
||||||
|
|
||||||
-- Attribute statements
|
-- Attribute statements
|
||||||
pAttrStmt :: Parser AttrStmt
|
pAttrStmt :: Parser AttrStmt
|
||||||
pAttrStmt = AttrStmt
|
pAttrStmt = p <?> name where
|
||||||
|
name = "AttrStmt"
|
||||||
|
p =
|
||||||
|
AttrStmt
|
||||||
<$> (string "attribute" *> pWs *> pId)
|
<$> (string "attribute" *> pWs *> pId)
|
||||||
<*> (pWs *> pConstant)
|
<*> (pWs *> pConstant)
|
||||||
<* pEolAndAdvanceToNextNonWs
|
<* pEolAndAdvanceToNextNonWs
|
||||||
|
|
||||||
-- Signal Specifications
|
-- Signal Specifications
|
||||||
pSigSpec :: Parser SigSpec
|
pSigSpec :: Parser SigSpec
|
||||||
pSigSpec = do
|
pSigSpec = p <?> name where
|
||||||
|
name = "SigSpec"
|
||||||
|
p =
|
||||||
|
do
|
||||||
baseSigSpec <- (SigSpecConstant <$> pConstant)
|
baseSigSpec <- (SigSpecConstant <$> pConstant)
|
||||||
<|>
|
<|>
|
||||||
(SigSpecWireId <$> pWireId)
|
(SigSpecWireId <$> pWireId)
|
||||||
|
@ -201,51 +235,71 @@ pSigSpec = do
|
||||||
applySlices baseSigSpec
|
applySlices baseSigSpec
|
||||||
|
|
||||||
pSigSpecConcat :: Parser SigSpec
|
pSigSpecConcat :: Parser SigSpec
|
||||||
pSigSpecConcat = do
|
pSigSpecConcat = p <?> name where
|
||||||
|
name = "SigSpecConcat"
|
||||||
|
p =
|
||||||
|
do
|
||||||
char '{' <* pWs
|
char '{' <* pWs
|
||||||
sigspecs <- pSigSpec `sepBy` pWs
|
sigspecs <- pSigSpec `sepBy` pWs
|
||||||
pWs <* char '}'
|
pWs <* char '}'
|
||||||
return $ SigSpecConcat sigspecs
|
return $ SigSpecConcat sigspecs
|
||||||
|
|
||||||
applySlices :: SigSpec -> Parser SigSpec
|
applySlices :: SigSpec -> Parser SigSpec
|
||||||
applySlices base = do
|
applySlices base = p <?> name where
|
||||||
|
name = "ApplySlices"
|
||||||
|
p =
|
||||||
|
do
|
||||||
maybeSlice <- optionMaybe pSlice
|
maybeSlice <- optionMaybe pSlice
|
||||||
case maybeSlice of
|
case maybeSlice of
|
||||||
Nothing -> return base
|
Nothing -> return base
|
||||||
Just slice -> applySlices (SigSpecSlice base slice)
|
Just slice -> applySlices (SigSpecSlice base slice)
|
||||||
|
|
||||||
pSlice :: Parser Slice
|
pSlice :: Parser Slice
|
||||||
pSlice =
|
pSlice = p <?> name where
|
||||||
|
name = "Slice"
|
||||||
|
p =
|
||||||
Slice
|
Slice
|
||||||
<$> (pMaybeWs *> char '[' *> pMaybeWs *> pInteger <* pMaybeWs)
|
<$> (pMaybeWs *> char '[' *> pMaybeWs *> pInteger <* pMaybeWs)
|
||||||
<*> (optionMaybe (char ':' *> pInteger) <* pMaybeWs <* char ']')
|
<*> (optionMaybe (char ':' *> pInteger) <* pMaybeWs <* char ']')
|
||||||
|
|
||||||
-- Connections
|
-- Connections
|
||||||
pConnStmt :: Parser ConnStmt
|
pConnStmt :: Parser ConnStmt
|
||||||
pConnStmt = ConnStmt
|
pConnStmt = p <?> name where
|
||||||
|
name = "ConnStmt"
|
||||||
|
p =
|
||||||
|
ConnStmt
|
||||||
<$> (string "connect" *> pWs *> pSigSpec)
|
<$> (string "connect" *> pWs *> pSigSpec)
|
||||||
<*> (pWs *> pSigSpec)
|
<*> (pWs *> pSigSpec)
|
||||||
<* pEolAndAdvanceToNextNonWs
|
<* pEolAndAdvanceToNextNonWs
|
||||||
|
|
||||||
-- Wires
|
-- Wires
|
||||||
pWire :: Parser Wire
|
pWire :: Parser Wire
|
||||||
pWire = do
|
pWire = p <?> name where
|
||||||
|
name = "Wire"
|
||||||
|
p = do
|
||||||
attrs <- many pAttrStmt
|
attrs <- many pAttrStmt
|
||||||
wireStmt <- pWireStmt
|
wireStmt <- pWireStmt
|
||||||
return $ Wire wireStmt attrs
|
return $ Wire wireStmt attrs
|
||||||
|
|
||||||
pWireStmt :: Parser WireStmt
|
pWireStmt :: Parser WireStmt
|
||||||
pWireStmt = do
|
pWireStmt = p <?> name where
|
||||||
|
name = "WireStmt"
|
||||||
|
p = do
|
||||||
string "wire" <* pWs
|
string "wire" <* pWs
|
||||||
options <- many pWireOption <* pWs
|
options <- many pWireOption <* pWs
|
||||||
wireId <- WireId <$> pId <* pEolAndAdvanceToNextNonWs
|
wireId <- WireId <$> pId <* pEolAndAdvanceToNextNonWs
|
||||||
return $ WireStmt wireId options
|
return $ WireStmt wireId options
|
||||||
|
|
||||||
pWireId :: Parser WireId
|
pWireId :: Parser WireId
|
||||||
pWireId = WireId <$> pId
|
pWireId = p <?> name where
|
||||||
|
name = "WireId"
|
||||||
|
p =
|
||||||
|
WireId <$> pId
|
||||||
|
|
||||||
pWireOption :: Parser WireOption
|
pWireOption :: Parser WireOption
|
||||||
pWireOption =
|
pWireOption = p <?> name where
|
||||||
|
name = "WireOption"
|
||||||
|
p =
|
||||||
try (WireOptionWidth <$> (string "width" *> pWs *> pInteger)) <|>
|
try (WireOptionWidth <$> (string "width" *> pWs *> pInteger)) <|>
|
||||||
try (WireOptionOffset <$> (string "offset" *> pWs *> pInteger)) <|>
|
try (WireOptionOffset <$> (string "offset" *> pWs *> pInteger)) <|>
|
||||||
try (WireOptionInput <$> (string "input" *> pWs *> pInteger)) <|>
|
try (WireOptionInput <$> (string "input" *> pWs *> pInteger)) <|>
|
||||||
|
|
Loading…
Reference in a new issue