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] ++ "'."