]> git.rmz.io Git - my-scheme.git/blobdiff - app/Main.hs
Support escaped quotes
[my-scheme.git] / app / Main.hs
index 7c987cee50d96d97e445cc1b18756f845a47a24f..0c0d29c7a4acf3351624522b2e96080c4b4c1fc5 100644 (file)
@@ -1,4 +1,5 @@
 module Main where
 module Main where
+import Control.Monad
 import Text.ParserCombinators.Parsec hiding (spaces)
 import System.Environment
 
 import Text.ParserCombinators.Parsec hiding (spaces)
 import System.Environment
 
@@ -8,6 +9,7 @@ data LispVal = Atom String
              | Number Integer
              | String String
              | Bool Bool
              | Number Integer
              | String String
              | Bool Bool
+             deriving Show
 
 symbol :: Parser Char
 symbol = oneOf "!#$%&|*+-/:<=>?@^_~"
 
 symbol :: Parser Char
 symbol = oneOf "!#$%&|*+-/:<=>?@^_~"
@@ -16,24 +18,42 @@ spaces :: Parser ()
 spaces = skipMany space
 
 parseString :: Parser LispVal
 spaces = skipMany space
 
 parseString :: Parser LispVal
-parseString = do
-    char '"'
-    x <- many (noneOf "\"")
-    char '"'
-    return $ String x
+parseString = do char '"'
+                 x <- many innerChar
+                 char '"'
+                 return $ String x
+              where innerChar = noneOf ['\\', '\"'] <|> escapeChar
+                    escapeChar = do char '\\'
+                                    c <- oneOf "\""
+                                    return $ '\"'
 
 parseAtom :: Parser LispVal
 parseAtom = do
     a <- letter <|> symbol
     b <- many (letter <|> digit <|> symbol)
 
 parseAtom :: Parser LispVal
 parseAtom = do
     a <- letter <|> symbol
     b <- many (letter <|> digit <|> symbol)
-    return $ Atom (a:b)
+    let atom = a:b
+    return $ case atom of
+                "#t" -> Bool True
+                "#f" -> Bool False
+                _    -> Atom atom
+
+parseNumber :: Parser LispVal
+parseNumber = do ds <- many1 digit
+                 let a = read ds
+                 return $ Number a
+
+parseExpr :: Parser LispVal
+parseExpr = parseString
+        <|> parseAtom
+        <|> parseNumber
 
 readExpr :: String -> String
 
 readExpr :: String -> String
-readExpr input = case parse (spaces >> symbol) "lisp" input of
+readExpr input = case parse parseExpr "lisp" input of
     Left err -> "No match: " ++ show err
     Left err -> "No match: " ++ show err
-    Right val -> "Found value"
+    Right val -> "Found value: " ++ show val
 
 main :: IO ()
 main = do
     args <- getLine
     putStrLn (readExpr args)
 
 main :: IO ()
 main = do
     args <- getLine
     putStrLn (readExpr args)
+    main