X-Git-Url: https://ruin.nu/git/?p=proglang.git;a=blobdiff_plain;f=Interpret.hs;h=5afcefb10b28cd6ac4a390e71958499b5cfdc956;hp=b82398d22bc63b114eb0d5c6f7f344f80cd34c31;hb=cdcd3b92ee3145e646634d428b02118238d47f33;hpb=8fdc0177fdf518f63819e5b98dd0368fccca6175 diff --git a/Interpret.hs b/Interpret.hs index b82398d..5afcefb 100644 --- a/Interpret.hs +++ b/Interpret.hs @@ -1,7 +1,9 @@ -module Interpret (eval, execute,addFunction, emptyState, Value(..), State(..)) where +module Interpret (interpret, eval, execute,addFunction, emptyState, Value(..), State(..)) where import Abssyntax import Control.Monad.State hiding (State) +import Control.Monad.Error +import Control.Concurrent.MVar import Data.Map as Map import Prelude hiding (lookup) @@ -17,11 +19,13 @@ instance Show Value where type Variables = [Map Ident Value] type Function = ([Decl],[Stm]) -data State = State {variables::Variables,functions::(Map Ident Function)} +data State = State {variables::Variables,functions::(Map Ident Function),ret::(MVar Value)} -inList :: Eq a => a -> [a] -> Bool -inList _ [] = False -inList a (x:xs) = if a == x then True else inList a xs +interpret :: [Func] -> [Stm] -> IO () +interpret fun st = do + mv <- newEmptyMVar + runStateT (do mapM Interpret.addFunction fun; mapM execute st) emptyState{ret=mv} + return () --eval :: (MonadState Variables m) => Exp -> m Value eval :: Exp -> StateT State IO Value @@ -32,7 +36,7 @@ eval (EAss i e) = setVariableValue i e eval (BiOpExp e o e') = do v <- eval e v'<- eval e' - if inList o [Eq,NEq] then return $ opE o v v' + if elem 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 eval (EPost i o) = do (VInt n) <- getVariableValue i @@ -50,11 +54,21 @@ eval EReadI = do 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 + let m = foldr (\((Decl t i),v) m -> insert i v m) empty $ zip ds vs + in modify (\s -> s{variables=[m]}) + mapM_ execute ss `catchError` (\_ -> return ()) + v <- lift $ takeMVar $ ret state + put state + return v getWord :: IO String getWord = do c <- getChar - if inList c [' ', '\n', '\t', '\r'] + if elem c [' ', '\n', '\t', '\r'] then return "" else do l <- getWord @@ -122,6 +136,11 @@ execute (SDecl t i e) =do v <- eval e state <- get let (m:ms) = variables state in modify (\s -> s{variables=insert i v m:ms }) +execute (SReturn e) = do + v <- eval e + s <- get + lift $ putMVar (ret s) v + throwError $ userError "Returning.." addFunction :: (MonadState State m) => Func -> m () addFunction (Func _ i d ss) = modify (\s -> s{functions=insert i (d,ss) (functions s) })