]> ruin.nu Git - proglang.git/blobdiff - Interpret.hs
initial commit of interpreter
[proglang.git] / Interpret.hs
diff --git a/Interpret.hs b/Interpret.hs
new file mode 100644 (file)
index 0000000..f1c8206
--- /dev/null
@@ -0,0 +1,83 @@
+module Interpret (eval, execute, Value(VInt, VBool)) where
+
+import Abssyntax
+import Control.Monad.State
+import Data.Map as Map
+import Prelude hiding (lookup)
+
+data Value = VInt Integer | VBool Bool deriving Eq
+
+instance Show Value where
+       show (VInt n) = show n
+       show (VBool b) = show b
+
+type Variables = [Map Ident Value]
+
+inList :: Eq a => a -> [a] -> Bool
+inList _ [] = False
+inList a (x:xs) = if a == x then True else inList a xs
+
+--eval :: (MonadState Variables m) => Exp -> m Value
+eval :: Exp -> StateT Variables IO Value
+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
+       (VInt n) <- getVariableValue i
+       setVariableValue i $ EInt $ n+1
+       return $ VInt n
+
+-- op :: Op -> (a -> a -> Value)
+opE Eq = \e e' -> VBool $ e == e'
+opE NEq = \e e' -> VBool $ not (e == e')
+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' 
+
+getVariableValue :: (MonadState Variables m) => Ident -> m Value 
+getVariableValue i = do
+       ms <- get 
+       findVariable i ms
+
+--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'
+
+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
+
+-- execute :: (MonadState Variables m) => Stm -> m ()
+execute :: Stm -> StateT Variables IO ()
+execute (SIf b s s') = do
+       (VBool b') <- eval b
+       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 (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 ()