+eval (ENeg e) = do
+ (VInt n) <- eval e
+ return $ VInt $ -n
+eval (ENot e) = do
+ (VBool b) <- eval e
+ return $ VBool $ not b
+eval EReadI = do
+ s <- lift $ getWord
+ return $ VInt $ read s
+eval EReadB = do
+ s <- lift $ getWord
+ return $ VBool $ if (read s == 0) then False else True
+eval (EFunc i as) = do
+ vs <- mapM eval as
+ state <- get
+ (ds,ss) <- lookup i $ functions state
+ modify (\s -> s{variables=[empty]})
+ addParams vs ds
+ mapM_ execute ss `catchError` (\_ -> return ())
+ put state
+ v <- lift $ takeMVar $ ret state
+ return v
+
+addParams :: [Value] -> [Decl] -> StateT State IO ()
+addParams [] [] = return ()
+addParams (v:vs) ((Decl t i):ds) = do
+ state <- get
+ let (m:ms) = variables state in modify (\s -> s{variables=insert i v m:ms })
+ addParams vs ds
+
+
+getWord :: IO String
+getWord = do
+ c <- getChar
+ if elem c [' ', '\n', '\t', '\r']
+ then return ""
+ else do
+ l <- getWord
+ return (c:l)