From 4f21d932178a490040cf5e054f3ba9d006579368 Mon Sep 17 00:00:00 2001 From: Michael Andreen Date: Wed, 1 Mar 2006 10:36:39 +0000 Subject: [PATCH] interpreter seems to work --- Interpret.hs | 66 +++++++++++++++++++++++++++++++++++++++++----------- examples/fac | 3 ++- 2 files changed, 54 insertions(+), 15 deletions(-) diff --git a/Interpret.hs b/Interpret.hs index f1c8206..9e4dcff 100644 --- a/Interpret.hs +++ b/Interpret.hs @@ -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 () diff --git a/examples/fac b/examples/fac index 9a941d7..946e847 100644 --- a/examples/fac +++ b/examples/fac @@ -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; -- 2.39.2