]> git.rmz.io Git - my-scheme.git/blobdiff - app/Main.hs
Support #bodx in number parser
[my-scheme.git] / app / Main.hs
index 67ec8ddde92590ba20d677d2f92b7d59128fd58e..c71126b500c4a581a4e6d2bf61577352bd89cd1b 100644 (file)
@@ -2,6 +2,7 @@ module Main where
 import Control.Monad
 import Text.ParserCombinators.Parsec hiding (spaces)
 import System.Environment
 import Control.Monad
 import Text.ParserCombinators.Parsec hiding (spaces)
 import System.Environment
+import Numeric
 
 data LispVal = Atom String
              | List [LispVal]
 
 data LispVal = Atom String
              | List [LispVal]
@@ -9,6 +10,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 "!#$%&|*+-/:<=>?@^_~"
@@ -17,11 +19,20 @@ 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 ['\"', '\\', 'n', 'r', 't', 'f']
+                                    return $ case c of
+                                                '\"' -> '\"'
+                                                '\\' -> '\\'
+                                                'n'  -> '\n'
+                                                'r'  -> '\r'
+                                                't'  -> '\t'
+                                                'f'  -> '\f'
 
 parseAtom :: Parser LispVal
 parseAtom = do
 
 parseAtom :: Parser LispVal
 parseAtom = do
@@ -34,21 +45,29 @@ parseAtom = do
                 _    -> Atom atom
 
 parseNumber :: Parser LispVal
                 _    -> Atom atom
 
 parseNumber :: Parser LispVal
-parseNumber = do ds <- many1 digit
-                 let a = read ds
+parseNumber = do toNum <- radix
+                 ds <- many1 digit
+                 let ((a,_):_) = toNum ds
                  return $ Number a
                  return $ Number a
+              where radix = do r <- try (char '#' >> oneOf "bodx") <|> return 'd'
+                               return $ case r of
+                                           'd' -> readDec
+                                           'x' -> readHex
+                                           'o' -> readOct
+                                           'b' -> readInt 2 (\x -> elem x "01") (read . (:[]))
 
 parseExpr :: Parser LispVal
 parseExpr = parseString
 
 parseExpr :: Parser LispVal
 parseExpr = parseString
-        <|> parseAtom
         <|> parseNumber
         <|> parseNumber
+        <|> parseAtom
 
 readExpr :: String -> String
 readExpr input = case parse parseExpr "lisp" input of
     Left err -> "No match: " ++ show err
 
 readExpr :: String -> String
 readExpr input = case parse parseExpr "lisp" input of
     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