]> ruin.nu Git - proglang.git/blobdiff - Interpret.hs
replace E with in
[proglang.git] / Interpret.hs
index f1c820682806950a7912115488eb40be0f5fa4fc..fd04dcd722d9e33d8b65a70c292c96bd161e48e4 100644 (file)
@@ -23,16 +23,36 @@ eval (EBool b) = return (VBool b)
 eval (EInt n) = return (VInt n)
 eval (EVar i) = getVariableValue i
 eval (EAss i e) = setVariableValue i e 
-eval EDefault = return (VInt 0) --FIXME!!!
 eval (BiOpExp e o e') = do
        v <- eval e
        v'<- eval e'
        if inList o [Eq,NEq] then return $ opE o v v'
                else let (VInt n1) = v in let (VInt n2) = v' in return $ op o n1 n2
-typeCheckExp (EPost i op) = do
+eval (EPost i o) = do
        (VInt n) <- getVariableValue i
-       setVariableValue i $ EInt $ n+1
+       let (VInt n') = op o n 1 in setVariableValue i $ EInt n'
        return $ VInt n
+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 $ read s
+
+getWord :: IO String
+getWord =  do
+       c <- getChar
+       if inList c ['\n','\r',' ', '\t']
+               then return ""
+               else do
+                       l <- getWord
+                       return (c:l) 
 
 -- op :: Op -> (a -> a -> Value)
 opE Eq = \e e' -> VBool $ e == e'
@@ -41,43 +61,59 @@ op Plus = \e e' -> VInt $ e + e'
 op Minus = \e e' -> VInt $ e - e' 
 op Times = \e e' -> VInt $ e * e' 
 op Div = \e e' -> VInt $ e `div` e' 
+op Lt = \e e' -> VBool $ e < e'
+op ELt = \e e' -> VBool $ e <= e'
+op Gt = \e e' -> VBool $ e > e'
+op EGt = \e e' -> VBool $ e >= e'
 
 getVariableValue :: (MonadState Variables m) => Ident -> m Value 
 getVariableValue i = do
        ms <- get 
        findVariable i ms
 
+findVariable :: (MonadState  Variables m) => Ident -> Variables -> m Value
+findVariable i [] = fail $ "Variable "++show i++" not found in any scope."
+findVariable i (m:ms) = if member i m then lookup i m else findVariable i ms
+
+--setVariableValue :: (MonadState Variables m) => Ident -> Exp -> m Value 
 --setVariableValue :: (MonadState Variables m) => Ident -> Exp -> m Value 
+
 setVariableValue :: Ident -> Exp -> StateT Variables IO Value
 setVariableValue i e = do
-       e' <- eval e
-       (m:ms) <- get
-       put $ (insert i e' m):ms
-       return e'
+       v <- eval e
+       ms <- get
+       put $ updateVariable i v ms
+       return v
 
-findVariable :: (MonadState  Variables m) => Ident -> Variables -> m Value
-findVariable i [] = fail $ "Variable "++show i++" not found in any scope."
-findVariable i (m:ms) = if member i m then lookup i m else findVariable i ms
+updateVariable :: Ident -> Value -> Variables -> Variables 
+updateVariable _ _ [] = []
+updateVariable i v (m:ms) = if member i m then insert i v m:ms else m:updateVariable i v ms
+
+pushAndPop :: (MonadState Variables m) => m a -> m ()
+pushAndPop s = do
+       modify (empty:)
+       s
+       modify tail
 
 -- execute :: (MonadState Variables m) => Stm -> m ()
 execute :: Stm -> StateT Variables IO ()
+execute (SNoop) = return ()
+execute (SExp e) = eval e >> return ()
 execute (SIf b s s') = do
        (VBool b') <- eval b
-       if b' then execute s else execute s'
+       pushAndPop $ if b' then execute s else execute s'
 execute (SPrint e) = do
        e' <- eval e
        lift $ print e'
-execute (SNoop) = return ()
-execute (SBlock ss) = do
-       modify (empty:)
-       mapM execute ss
-       modify tail
+execute (SBlock ss) = pushAndPop $ mapM execute ss
 execute (SWhile e s) = do
        (VBool b) <- eval e
-       if b then execute (SWhile e s) else return ()
-execute (SDecl t i EDefault) = do
-       case t of
-               TInt -> setVariableValue i (EInt 0)
-               TBool -> setVariableValue i (EBool False)
-       return ()
-execute (SDecl t i e) = setVariableValue i e >> return ()
+       if b then pushAndPop (execute s) >> execute (SWhile e s) else return ()
+execute (SDeclD t i) = execute (SDecl t i $ case t of
+       TInt -> EInt 0
+       TBool -> EBool False
+       )
+execute (SDecl t i e) =do
+       e' <- eval e
+       (m:ms) <- get
+       put $ (insert i e' m):ms