+parseNumber :: Parser LispVal
+parseNumber = do toNum <- radix
+ ds <- many1 digit
+ let ((a,_):_) = toNum ds
+ 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 . (:[]))
+
+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
+ <|> parseNumber
+ <|> parseAtom
+ <|> try parseCharacter
+ <|> parseQuoted
+ <|> do char '('
+ x <- try parseList <|> parseDottedList
+ char ')'
+ return x
+