X-Git-Url: https://git.rmz.io/my-scheme.git/blobdiff_plain/d9a59677ebd0595e060978abef79c376c27400eb..refs/heads/master:/app/Main.hs diff --git a/app/Main.hs b/app/Main.hs index 03dbb41..78f37ea 100644 --- a/app/Main.hs +++ b/app/Main.hs @@ -11,7 +11,6 @@ data LispVal = Atom String | String String | Character Char | Bool Bool - deriving Show symbol :: Parser Char symbol = oneOf "!#$%&|*+-/:<=>?@^_~" @@ -65,16 +64,50 @@ parseNumber = do toNum <- radix 'o' -> readOct 'b' -> readInt 2 (\x -> elem x "01") (read . (:[])) +parseList :: Parser LispVal +parseList = liftM List $ sepBy parseExpr spaces + +parseDottedList :: Parser LispVal +parseDottedList = do + head <- endBy parseExpr spaces + tail <- char '.' >> spaces >> parseExpr + return $ DottedList head tail + +parseQuoted :: Parser LispVal +parseQuoted = do + char '\'' + x <- parseExpr + return $ List [Atom "quote", x] + parseExpr :: Parser LispVal parseExpr = parseString - <|> parseCharacter <|> parseNumber <|> parseAtom + <|> try parseCharacter + <|> parseQuoted + <|> do char '(' + x <- try parseList <|> parseDottedList + char ')' + return x readExpr :: String -> String readExpr input = case parse parseExpr "lisp" input of Left err -> "No match: " ++ show err - Right val -> "Found value: " ++ show val + Right val -> "Found value: " ++ showVal val + +instance Show LispVal where show = showVal +showVal :: LispVal -> String +showVal (Atom atom) = atom +showVal (List list) = "(" ++ unwordsList list ++ ")" +showVal (DottedList head tail) = "(" ++ unwordsList head ++ " . " ++ showVal tail ++ ")" +showVal (Number n) = show n +showVal (String str) = "\"" ++ str ++ "\"" +showVal (Character c) = "'" ++ [c] ++ "'" +showVal (Bool True) = "#t" +showVal (Bool False) = "#f" + +unwordsList :: [LispVal] -> String +unwordsList = unwords . map showVal main :: IO () main = do