]> ruin.nu Git - proglang.git/commitdiff
interpreter seems to work
authorMichael Andreen <harv@ruin.nu>
Wed, 1 Mar 2006 10:36:39 +0000 (10:36 +0000)
committerMichael Andreen <harv@ruin.nu>
Wed, 1 Mar 2006 10:36:39 +0000 (10:36 +0000)
Interpret.hs
examples/fac

index f1c820682806950a7912115488eb40be0f5fa4fc..9e4dcff34541b1f180b73b3c12dc15cbcfb3e642 100644 (file)
@@ -23,16 +23,37 @@ 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 EDefault = error "EDefault called from an illegal place"
 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 +62,60 @@ 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 :: Ident -> Exp -> StateT Variables IO Value
-setVariableValue i e = do
+--setVariableValue :: (MonadState Variables m) => Ident -> Exp -> m Value 
+addVariable :: Ident -> Exp -> StateT Variables IO ()
+addVariable 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
+setVariableValue :: Ident -> Exp -> StateT Variables IO Value
+setVariableValue i e = do
+       v <- eval e
+       ms <- get
+       put $ updateVariable i v ms
+       return v
+
+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
+
 
 -- 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'
 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 ()
+       if b then execute s >> 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)
+               TInt -> addVariable i (EInt 0)
+               TBool -> addVariable i (EBool False)
        return ()
-execute (SDecl t i e) = setVariableValue i e >> return ()
+execute (SDecl t i e) = addVariable i e >> return ()
index 9a941d794961ed3519f895f9afb2415f419ab546..946e8474f8f0669015c4d4bf010645767072e828 100644 (file)
@@ -1,4 +1,5 @@
 int fac = 1;
 int n = readInt;
-while( n-- > 0) fac = fac*n;
+n++;
+while( n-- > 1) fac = fac*n;
 print fac;