From: Samir Benmendil Date: Sun, 21 Jan 2018 12:06:07 +0000 (+0000) Subject: Add Character parser X-Git-Url: https://git.rmz.io/my-scheme.git/commitdiff_plain/d9a59677ebd0595e060978abef79c376c27400eb Add Character parser Refactor `nonPrintableChar` into its own Parser type to be reused in `parseCharacter` and `parseString` --- diff --git a/app/Main.hs b/app/Main.hs index c71126b..03dbb41 100644 --- a/app/Main.hs +++ b/app/Main.hs @@ -9,6 +9,7 @@ data LispVal = Atom String | DottedList [LispVal] LispVal | Number Integer | String String + | Character Char | Bool Bool deriving Show @@ -18,21 +19,29 @@ symbol = oneOf "!#$%&|*+-/:<=>?@^_~" spaces :: Parser () spaces = skipMany space +nonPrintableChar :: Parser Char +nonPrintableChar = do c <- char '\\' >> oneOf "\\nrtf" + return $ case c of '\\' -> '\\' + 'n' -> '\n' + 'r' -> '\r' + 't' -> '\t' + 'f' -> '\f' + +parseCharacter :: Parser LispVal +parseCharacter = do char '\'' + c <- noneOf ['\\', '\''] <|> try singleQuote <|> try nonPrintableChar + char '\'' + return $ Character c + where + singleQuote = char '\\' >> char '\'' + parseString :: Parser LispVal parseString = do char '"' x <- many innerChar char '"' return $ String x - where innerChar = noneOf ['\\', '\"'] <|> escapeChar - escapeChar = do char '\\' - c <- oneOf ['\"', '\\', 'n', 'r', 't', 'f'] - return $ case c of - '\"' -> '\"' - '\\' -> '\\' - 'n' -> '\n' - 'r' -> '\r' - 't' -> '\t' - 'f' -> '\f' + where innerChar = noneOf ['\\', '"'] <|> try doubleQuote <|> try nonPrintableChar + doubleQuote = char '\\' >> char '"' parseAtom :: Parser LispVal parseAtom = do @@ -58,6 +67,7 @@ parseNumber = do toNum <- radix parseExpr :: Parser LispVal parseExpr = parseString + <|> parseCharacter <|> parseNumber <|> parseAtom