3 import Text.ParserCombinators.Parsec hiding (spaces)
4 import System.Environment
7 data LispVal = Atom String
9 | DottedList [LispVal] LispVal
17 symbol = oneOf "!#$%&|*+-/:<=>?@^_~"
20 spaces = skipMany space
22 nonPrintableChar :: Parser Char
23 nonPrintableChar = do c <- char '\\' >> oneOf "\\nrtf"
24 return $ case c of '\\' -> '\\'
30 parseCharacter :: Parser LispVal
31 parseCharacter = do char '\''
32 c <- noneOf ['\\', '\''] <|> try singleQuote <|> try nonPrintableChar
36 singleQuote = char '\\' >> char '\''
38 parseString :: Parser LispVal
39 parseString = do char '"'
43 where innerChar = noneOf ['\\', '"'] <|> try doubleQuote <|> try nonPrintableChar
44 doubleQuote = char '\\' >> char '"'
46 parseAtom :: Parser LispVal
48 a <- letter <|> symbol
49 b <- many (letter <|> digit <|> symbol)
56 parseNumber :: Parser LispVal
57 parseNumber = do toNum <- radix
59 let ((a,_):_) = toNum ds
61 where radix = do r <- try (char '#' >> oneOf "bodx") <|> return 'd'
66 'b' -> readInt 2 (\x -> elem x "01") (read . (:[]))
68 parseExpr :: Parser LispVal
69 parseExpr = parseString
74 readExpr :: String -> String
75 readExpr input = case parse parseExpr "lisp" input of
76 Left err -> "No match: " ++ show err
77 Right val -> "Found value: " ++ show val
82 putStrLn (readExpr args)