commit d12ffc4f58768fd226930874edd98e4e4cd7c062 Author: Yann Esposito (Yogsototh) Date: Tue Jul 16 23:04:20 2013 +0200 first commit diff --git a/y.hs b/y.hs new file mode 100644 index 0000000..4343646 --- /dev/null +++ b/y.hs @@ -0,0 +1,114 @@ +module Main where + +import Data.List (foldl') +import Text.ParserCombinators.Parsec hiding (spaces) +import System.Environment (getArgs) + +data LispVal = Atom String + | List [LispVal] + | DottedList [LispVal] LispVal + | Number Integer + | String String + | Bool Bool + deriving (Show) + +symbol :: Parser Char +symbol = oneOf "!#$%&|*+-/:<=>?@^_~" + +spaces :: Parser () +spaces = skipMany1 space + +parseString :: Parser LispVal +parseString = do + char '"' + x <- many ( (char '\\' >> char 'n' >> return '\n') + <|> (char '\\' >> char 'r' >> return '\r') + <|> (char '\\' >> char 't' >> return '\t') + <|> (char '\\' >> anyChar) + <|> noneOf "\"" + ) + char '"' + return $ String x + +parseAtom :: Parser LispVal +parseAtom = do + first <- letter <|> symbol + rest <- many (letter <|> digit <|> symbol) + let atom = first:rest + return $ case atom of + "#vrai" -> Bool True + "#faux" -> Bool False + _ -> Atom atom + +numFromBase n str = foldl' traiteNombre 0 str + where + traiteNombre acc v = acc*n + chiffre + where chiffre = case v of + '0' -> 0 + '1' -> 1 + '2' -> 2 + '3' -> 3 + '4' -> 4 + '5' -> 5 + '6' -> 6 + '7' -> 7 + '8' -> 8 + '9' -> 9 + 'A' -> 10 + 'B' -> 11 + 'C' -> 12 + 'D' -> 13 + 'E' -> 14 + 'F' -> 15 + 'a' -> 10 + 'b' -> 11 + 'c' -> 12 + 'd' -> 13 + 'e' -> 14 + 'f' -> 15 + +parseBaseSpecifiedNumber :: Parser Integer +parseBaseSpecifiedNumber = do + _ <- char '#' + numtype <- oneOf "bdox" + (base,str) <- case numtype of + 'b' -> do + numstr <- many1 (oneOf "01") + return (2,numstr) + 'o' -> do + numstr <- many1 (oneOf "01234567") + return (8,numstr) + 'd' -> do + numstr <- many1 (oneOf "0123456789") + return (10,numstr) + 'x' -> do + numstr <- many1 (oneOf "0123456789ABCDEFabcdef") + return (16,numstr) + return $ numFromBase base str + +parseSimpleNumber :: Parser Integer +parseSimpleNumber = do + numStr <- many1 digit + return (read numStr) + +parseNumber :: Parser LispVal +parseNumber = do + number <- parseSimpleNumber + <|> parseBaseSpecifiedNumber + return (Number number) + +parseExpr :: Parser LispVal +parseExpr = parseString + <|> parseNumber + <|> parseAtom + + +readExpr :: String -> String +readExpr input = case parse parseExpr "lisp" input of + Left err -> "No match: " ++ show err + Right val -> show val + +main :: IO () +main = do + args <- getArgs + putStrLn (readExpr (args !!0))