From 3082f3409f4500b061b72e16d891a2d929ad02d5 Mon Sep 17 00:00:00 2001 From: Yehowshua Immanuel Date: Mon, 25 Nov 2024 18:42:03 -0500 Subject: [PATCH] guess I'm done with re-org --- haskellator.cabal | 11 ++- src/Haskellator.hs | 87 +------------------- src/{RtlilAstTypes.hs => RTLILParser/AST.hs} | 2 +- src/RTLILParser/Parser.hs | 85 +++++++++++++++++++ src/RTLILParser/Primitives.hs | 29 +++++++ src/Util.hs | 21 +---- 6 files changed, 126 insertions(+), 109 deletions(-) rename src/{RtlilAstTypes.hs => RTLILParser/AST.hs} (96%) create mode 100644 src/RTLILParser/Parser.hs create mode 100644 src/RTLILParser/Primitives.hs diff --git a/haskellator.cabal b/haskellator.cabal index 1cad66d..470317b 100644 --- a/haskellator.cabal +++ b/haskellator.cabal @@ -57,9 +57,14 @@ common warnings library exposed-modules: Haskellator, - RtlilAstTypes - other-modules: - hs-source-dirs: src + -- RtlilAstTypes + other-modules: + RTLILParser.AST, + RTLILParser.Primitives, + RTLILParser.Parser, + Util + hs-source-dirs: + src, build-depends: base ^>=4.17.2.1, parsec >=3.1 diff --git a/src/Haskellator.hs b/src/Haskellator.hs index 487de0c..028936d 100644 --- a/src/Haskellator.hs +++ b/src/Haskellator.hs @@ -1,86 +1,3 @@ --- this parser largely references: --- https://github.com/YosysHQ/yosys/blob/111b747d2797238eadf541879848492a9d34909a/docs/source/yosys_internals/formats/rtlil_text.rst -module Haskellator(a, val) where +module Haskellator(val) where - -import Control.Monad (void) -import Text.Parsec -import Text.Parsec.String (Parser) -import RtlilAstTypes( - PublicId(..), - Id(..), - AutogenId(..), - AutoIdxStmt(..), - Value(..) - ) -import Util( - binaryStringToInt, - pEscapedChar) - --- https://github.com/YosysHQ/yosys/blob/111b747d2797238eadf541879848492a9d34909a/frontends/rtlil/rtlil_lexer.l#L88C1-L88C17 -nonws :: Parser Char -nonws = noneOf " \t\r\n" - -pWs :: Parser String -pWs = many1 (oneOf " \t") - -pEol :: Parser String -pEol = many1 (oneOf "\r\n") - -pPublicId :: Parser PublicId -pPublicId = PublicId <$> (char '\\' *> many1 nonws) - -pAutogenId :: Parser AutogenId -pAutogenId = AutogenId <$> (char '$' *> many1 nonws) - -pId :: Parser Id -pId = Public <$> pPublicId - <|> Autogen <$> pAutogenId - -decimalDigit :: Parser Char -decimalDigit = oneOf "0123456789" - --- update in the future to support 4 state logic --- by converting x and z to 0 and warning about it. -pBinaryDigit :: Parser Char -pBinaryDigit = oneOf "01" - -pString :: Parser String -pString = - between delimiter delimiter parseString - where - delimiter = char '"' - parseString = many (pEscapedChar <|> noneOf "\\\"") - - -pValue :: Parser Value -pValue = Value <$> pInteger - <*> (binaryStringToInt <$> many1 pBinaryDigit) - -pInteger :: Parser Int -pInteger = do - sign <- optionMaybe (char '-') - digits <- many1 digit - let value = read digits - return $ case sign of - Just _ -> -value - Nothing -> value - - -pAutoIdxStmt :: Parser AutoIdxStmt -pAutoIdxStmt = AutoIdxStmt <$> (string "autoidx" *> pWs *> pInteger <* pEol) - -pModuleStmt :: Parser Id -pModuleStmt = string "module" *> pWs *> pId <* pEol - -pModuleEndStmt :: Parser () -pModuleEndStmt = void (string "end") - --- pModuleStmt :: Parser () --- pModuleStmt = - --- val = parse pInteger "pInteger" "721" -val = parse pModuleStmt "pModuleStmt" "module \\top\n" - -a :: Int -a = 3 \ No newline at end of file + import RTLILParser.Parser(val) \ No newline at end of file diff --git a/src/RtlilAstTypes.hs b/src/RTLILParser/AST.hs similarity index 96% rename from src/RtlilAstTypes.hs rename to src/RTLILParser/AST.hs index 889d414..3244f81 100644 --- a/src/RtlilAstTypes.hs +++ b/src/RTLILParser/AST.hs @@ -1,4 +1,4 @@ -module RtlilAstTypes( +module RTLILParser.AST( PublicId(..), AutogenId(..), AutoIdxStmt(..), diff --git a/src/RTLILParser/Parser.hs b/src/RTLILParser/Parser.hs new file mode 100644 index 0000000..d13c199 --- /dev/null +++ b/src/RTLILParser/Parser.hs @@ -0,0 +1,85 @@ +-- this parser largely references: +-- https://github.com/YosysHQ/yosys/blob/111b747d2797238eadf541879848492a9d34909a/docs/source/yosys_internals/formats/rtlil_text.rst +module RTLILParser.Parser(a, val) where + + +import Control.Monad (void) +import Text.Parsec +import Text.Parsec.String (Parser) +import RTLILParser.AST( + PublicId(..), + Id(..), + AutogenId(..), + AutoIdxStmt(..), + Value(..) + ) +import Util(binaryStringToInt) +import RTLILParser.Primitives(pEscapedChar) + +-- https://github.com/YosysHQ/yosys/blob/111b747d2797238eadf541879848492a9d34909a/frontends/rtlil/rtlil_lexer.l#L88C1-L88C17 +nonws :: Parser Char +nonws = noneOf " \t\r\n" + +pWs :: Parser String +pWs = many1 (oneOf " \t") + +pEol :: Parser String +pEol = many1 (oneOf "\r\n") + +pPublicId :: Parser PublicId +pPublicId = PublicId <$> (char '\\' *> many1 nonws) + +pAutogenId :: Parser AutogenId +pAutogenId = AutogenId <$> (char '$' *> many1 nonws) + +pId :: Parser Id +pId = Public <$> pPublicId + <|> Autogen <$> pAutogenId + +decimalDigit :: Parser Char +decimalDigit = oneOf "0123456789" + +-- update in the future to support 4 state logic +-- by converting x and z to 0 and warning about it. +pBinaryDigit :: Parser Char +pBinaryDigit = oneOf "01" + +pString :: Parser String +pString = + between delimiter delimiter parseString + where + delimiter = char '"' + parseString = many (pEscapedChar <|> noneOf "\\\"") + + +pValue :: Parser Value +pValue = Value <$> pInteger + <*> (binaryStringToInt <$> many1 pBinaryDigit) + +pInteger :: Parser Int +pInteger = do + sign <- optionMaybe (char '-') + digits <- many1 digit + let value = read digits + return $ case sign of + Just _ -> -value + Nothing -> value + + +pAutoIdxStmt :: Parser AutoIdxStmt +pAutoIdxStmt = AutoIdxStmt <$> (string "autoidx" *> pWs *> pInteger <* pEol) + +pModuleStmt :: Parser Id +pModuleStmt = string "module" *> pWs *> pId <* pEol + +pModuleEndStmt :: Parser () +pModuleEndStmt = void (string "end") + +-- pModuleStmt :: Parser () +-- pModuleStmt = + +-- val = parse pInteger "pInteger" "721" +val = parse pModuleStmt "pModuleStmt" "module \\top\n" + +a :: Int +a = 3 \ No newline at end of file diff --git a/src/RTLILParser/Primitives.hs b/src/RTLILParser/Primitives.hs new file mode 100644 index 0000000..b3403ce --- /dev/null +++ b/src/RTLILParser/Primitives.hs @@ -0,0 +1,29 @@ +module RTLILParser.Primitives( + pOctal, + pEscapedChar +) where + +import Control.Monad (void) +import Text.Parsec +import Text.Parsec.String (Parser) +import Data.Char (digitToInt) +import Util(binaryStringToInt, octalStringToInt) + + +pOctal :: Parser Char +pOctal = do + digits <- count 1 digit -- At least 1 digit + moreDigits <- option "" (count 2 digit) -- Up to 3 digits total + case octalStringToInt (digits ++ moreDigits) of + Just value -> return $ toEnum value -- Convert integer to a Char + Nothing -> fail "Invalid octal escape sequence" + +pEscapedChar :: Parser Char +pEscapedChar = do + char '\\' -- Match the backslash + choice + [ char 'n' >> return '\n' + , char 't' >> return '\t' + , try pOctal + , anyChar + ] \ No newline at end of file diff --git a/src/Util.hs b/src/Util.hs index 43bb020..707826b 100644 --- a/src/Util.hs +++ b/src/Util.hs @@ -1,7 +1,6 @@ module Util( binaryStringToInt, - pEscapedChar, - pEscapedChar + octalStringToInt, ) where import Control.Monad (void) @@ -17,21 +16,3 @@ octalStringToInt :: String -> Maybe Int octalStringToInt str | all (`elem` ['0'..'7']) str = Just $ foldl' (\acc x -> acc * 8 + digitToInt x) 0 str | otherwise = Nothing - -pOctal :: Parser Char -pOctal = do - digits <- count 1 digit -- At least 1 digit - moreDigits <- option "" (count 2 digit) -- Up to 3 digits total - case octalStringToInt (digits ++ moreDigits) of - Just value -> return $ toEnum value -- Convert integer to a Char - Nothing -> fail "Invalid octal escape sequence" - -pEscapedChar :: Parser Char -pEscapedChar = do - char '\\' -- Match the backslash - choice - [ char 'n' >> return '\n' -- \n → newline - , char 't' >> return '\t' -- \t → tab - , try pOctal -- \123 → octal escape - , anyChar -- Any other escaped char (e.g., \\) - ]