Created
December 18, 2011 21:55
-
-
Save anonymous/1494602 to your computer and use it in GitHub Desktop.
Polish Notation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import qualified Data.Char as Ctype | |
main = do cs <- getContents | |
print $ calculate $ parse cs | |
-- TODO: op n1 n2 以外の式にも対応 | |
calculate :: [Token] -> Int | |
calculate (op:n1:n2:rest) = | |
case [op, n1, n2] of | |
[Add , (TokenNumber i1), (TokenNumber i2)] -> i1 + i2 | |
[Subtract, (TokenNumber i1), (TokenNumber i2)] -> i1 - i2 | |
[Multiply, (TokenNumber i1), (TokenNumber i2)] -> i1 * i2 | |
[Divide , (TokenNumber i1), (TokenNumber i2)] -> i1 `div` i2 | |
otherwise -> error "invalid expression" | |
parse = parse' [getOp, getNum, getNum] | |
parse' :: [(String -> (Token, String))] -> String -> [Token] | |
parse' [] cs = [] | |
parse' (tokenize:ts) cs = | |
let (token, rest) = tokenize cs | |
in token : (parse' ts $ dropWhile Ctype.isSpace rest) | |
data Token = Add | Subtract | Multiply | Divide | |
| TokenNumber Int | |
deriving Show | |
getOp ('+':rest) = (Add, rest) | |
getOp ('-':rest) = (Subtract, rest) | |
getOp ('*':rest) = (Multiply, rest) | |
getOp ('/':rest) = (Divide, rest) | |
getOp (token:rest) = error $ "unknown token '" ++ [token] ++ "'." | |
-- TODO: 2桁以上、単項マイナスに対応 | |
getNum (token:rest) | Ctype.isNumber token = (TokenNumber (read [token] :: Int), rest) | |
getNum (token:_) = error $ "expected number, but got token '" ++ [token] ++ "'." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment