]> git.rmz.io Git - my-scheme.git/blobdiff - app/Main.hs
Use `showVal` to print with show rather than the default
[my-scheme.git] / app / Main.hs
index 03dbb41ad56467919b06e5c72b886c640e697253..78f37ea4132604b9ee481dba40f65ab0e5738be3 100644 (file)
@@ -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