Advertisement
Guest User

Untitled

a guest
Dec 15th, 2019
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.78 KB | None | 0 0
  1. module Interpreter where
  2.  
  3. import Control.Monad
  4. import Control.Exception
  5. import System.Exit
  6.  
  7. import Data.Map (Map)
  8. import qualified Data.Map.Strict as Map
  9. import Data.List
  10. import Data.Maybe
  11.  
  12. import CMM.Abs
  13. import CMM.Print
  14. import CMM.ErrM
  15.  
  16. data Val = D Double | I Integer | B Bool | Void deriving (Eq)
  17. instance Show Val where
  18. show (D n) = show n
  19. show (I n) = show n
  20. show (B n) = show n
  21. show Void = "void"
  22.  
  23. type Env = (Fns, [Context]) -- functions and context stack
  24. type Fns = Map Id Def
  25. type Context = Map Id (Maybe Val) -- variables with their values
  26.  
  27. printEnv :: Env -> String
  28. printEnv (_, ctx) = show ctx
  29.  
  30. emptyEnv :: Env
  31. emptyEnv = (Map.empty, [Map.empty])
  32.  
  33. extendFn :: Env -> Def -> Env
  34. extendFn env (DFun t ident args stms) = (Map.insert ident (DFun t ident args stms) (fst env), snd env)
  35.  
  36. lookupFn :: Env -> Id -> Maybe Def
  37. lookupFn (fns, _) ident = Map.lookup ident fns
  38.  
  39. newBlock :: Env -> Env
  40. newBlock env = (fst env, Map.empty:snd env)
  41.  
  42. exitBlock :: Env -> Env
  43. exitBlock env = (fst env, tail $ snd env)
  44.  
  45. clean :: Env -> Env
  46. clean (fns, _) = (fns, [Map.empty])
  47.  
  48. extendVar :: Env -> Id -> Maybe Val -> Env
  49. extendVar (fns, ctxs) i v = (fns, Map.insert i v (head ctxs):tail ctxs)
  50.  
  51. modifyVar :: Env -> Id -> Maybe Val -> Env
  52. modifyVar (fns, ctxs) i v = case findIndex (Map.member i) ctxs of
  53. Nothing -> (fns, ctxs) -- this should never happen due to type checker
  54. Just idx -> (fns, modifyNth ctxs idx (Map.insert i v))
  55.  
  56. modifyNth :: [a] -> Int -> (a -> a) -> [a]
  57. modifyNth (x:xs) 0 fn = (fn x):xs
  58. modifyNth (x:xs) n fn = x:(modifyNth xs (n-1) fn)
  59.  
  60. lookupVar :: Env -> Id -> Maybe Val
  61. lookupVar e i = case find (Map.member i) (snd e) of
  62. Nothing -> Nothing
  63. Just ctx -> fromJust $ Map.lookup i ctx
  64.  
  65. interpret :: Program -> IO ()
  66. interpret (PDefs defs) = do
  67. -- print defs -- uncomment to print AST
  68. let env = foldl extendFn emptyEnv defs
  69. case lookupFn env (Id "main") of
  70. Nothing -> interpreterErr env "no main function"
  71. Just (DFun _ _ _ stms) -> do
  72. evalStms env stms
  73. return ()
  74.  
  75. evalStms :: Env -> [Stm] -> IO (Val, Env)
  76. evalStms env [] = return (Void, env)
  77. evalStms env (s:ss) = do
  78. -- putStrLn $ printTree s
  79. case s of
  80. SDecl _ iden -> evalStms (extendVar env iden Nothing) ss
  81. SDecls _ iden idens -> do
  82. let env' = foldl (\e i -> extendVar e i Nothing) env (iden:idens)
  83. evalStms env' ss
  84. SInit _ ident exp -> do
  85. (v, env') <- evalExp env exp
  86. evalStms (extendVar env' ident (Just v)) ss
  87. SReturn exp -> evalExp env exp
  88. SBlock stms -> do
  89. (v, env') <- evalStms (newBlock env) stms
  90. if v == Void
  91. then evalStms (exitBlock env') ss
  92. else return (v, exitBlock env')
  93. SWhile exp stm -> do
  94. (v, env') <- evalExp env exp
  95. case v of
  96. B False -> evalStms env' ss
  97. B True -> do
  98. (v, env'') <- evalStms (newBlock env') [stm]
  99. if v == Void
  100. then evalStms (exitBlock env'') (s:ss)
  101. else return (v, env'')
  102. SIfElse exp stm1 stm2 -> do
  103. (v, env') <- evalExp env exp
  104. case v of
  105. B True -> do
  106. (v', env'') <- evalStms (newBlock env') [stm1]
  107. if v' == Void
  108. then evalStms (exitBlock env'') ss
  109. else return (v', env'')
  110. B False -> do
  111. (v', env'') <- evalStms (newBlock env') [stm2]
  112. if v' == Void
  113. then evalStms (exitBlock env'') ss
  114. else return (v', env'')
  115. SExp exp -> do
  116. (v, env') <- evalExp env exp
  117. evalStms env' ss
  118.  
  119. evalExp :: Env -> Exp -> IO (Val, Env)
  120. evalExp env exp = do
  121. -- putStrLn $ show exp
  122. case exp of
  123. EInt n -> return (I n, env)
  124. EDouble n -> return (D n, env)
  125. ETrue -> return (B True, env)
  126. EFalse -> return (B False, env)
  127. EId ident -> case lookupVar env ident of
  128. Nothing -> interpreterErr env $ "uninitialized variable " ++ show exp
  129. Just v -> do
  130. -- putStrLn $ show v
  131. return (v, env)
  132. ECall (Id "printInt") [exp] -> do
  133. (v, env') <- evalExp env exp
  134. print $ v
  135. return (Void, env')
  136. ECall (Id "printDouble") [exp] -> do
  137. (v, env') <- evalExp env exp
  138. print $ v
  139. return (Void, env')
  140. ECall (Id "readInt") [] -> do
  141. line <- getLine
  142. let v = (read :: String -> Integer) line
  143. return (I v, env)
  144. ECall (Id "readDouble") [] -> do
  145. line <- getLine
  146. let v = (read :: String -> Double) line
  147. return (D v, env)
  148. ECall iden exps -> do
  149. (vs, env') <- evalExps env exps
  150. case lookupFn env iden of
  151. Nothing -> interpreterErr env $ "uninitialized func " ++ printTree iden
  152. Just (DFun _ _ args stms) -> do
  153. let env'' = foldl bindArg (clean env) (zip vs args)
  154. (v, _) <- evalStms env'' stms
  155. return (v, env')
  156. EPIncr ident ->
  157. case lookupVar env ident of
  158. Nothing -> interpreterErr env $ "uninitialized variable " ++ printTree ident
  159. Just v -> do
  160. let env2 = modifyVar env ident (Just (inc v))
  161. return (v, env2)
  162. EPDecr ident ->
  163. case lookupVar env ident of
  164. Nothing -> interpreterErr env $ "uninitialized variable " ++ printTree ident
  165. Just v -> do
  166. let env2 = modifyVar env ident (Just (dec v))
  167. return (v, env2)
  168. EIncr ident ->
  169. case lookupVar env ident of
  170. Nothing -> interpreterErr env $ "uninitialized variable " ++ printTree ident
  171. Just v -> do
  172. let v2 = inc v
  173. let env2 = modifyVar env ident (Just v2)
  174. return (v2, env2)
  175. EDecr ident ->
  176. case lookupVar env ident of
  177. Nothing -> interpreterErr env $ "uninitialized variable " ++ printTree ident
  178. Just v -> do
  179. let v2 = dec v
  180. let env2 = modifyVar env ident (Just v2)
  181. return (v2, env2)
  182. EMul exp1 exp2 -> do
  183. (v1, env') <- evalExp env exp1
  184. (v2, env'') <- evalExp env' exp2
  185. return (mul v1 v2, env'')
  186. EDiv exp1 exp2 -> do
  187. (v1, env') <- evalExp env exp1
  188. (v2, env'') <- evalExp env' exp2
  189. return (divide v1 v2, env'')
  190. EAdd exp1 exp2 -> do
  191. (v1, env') <- evalExp env exp1
  192. (v2, env'') <- evalExp env' exp2
  193. return (add v1 v2, env'')
  194. ESub exp1 exp2 -> do
  195. (v1, env') <- evalExp env exp1
  196. (v2, env'') <- evalExp env' exp2
  197. return (sub v1 v2, env'')
  198. ELt exp1 exp2 -> do
  199. (v1, env') <- evalExp env exp1
  200. (v2, env'') <- evalExp env' exp2
  201. return (less v1 v2, env'')
  202. ELEq exp1 exp2 -> do
  203. (v1, env') <- evalExp env exp1
  204. (v2, env'') <- evalExp env' exp2
  205. return (leq v1 v2, env'')
  206. EGt exp1 exp2 -> do
  207. (v1, env') <- evalExp env exp1
  208. (v2, env'') <- evalExp env' exp2
  209. return (greater v1 v2, env'')
  210. EGEq exp1 exp2 -> do
  211. (v1, env') <- evalExp env exp1
  212. (v2, env'') <- evalExp env' exp2
  213. return (geq v1 v2, env'')
  214. EEq exp1 exp2 -> do
  215. (v1, env') <- evalExp env exp1
  216. (v2, env'') <- evalExp env' exp2
  217. return (B (v1 == v2), env'')
  218. ENEq exp1 exp2 -> do
  219. (v1, env') <- evalExp env exp1
  220. (v2, env'') <- evalExp env' exp2
  221. return (B (not (v1 == v2)), env'')
  222. EAnd exp1 exp2 -> do
  223. (v1, env') <- evalExp env exp1
  224. if v1 == B False
  225. then return (v1, env')
  226. else evalExp env' exp2
  227. EOr exp1 exp2 -> do
  228. (v1, env') <- evalExp env exp1
  229. if v1 == B True
  230. then return (v1, env')
  231. else evalExp env' exp2
  232. EAss iden exp -> do
  233. (v, env') <- evalExp env exp
  234. return (v, modifyVar env' iden (Just v))
  235.  
  236. bindArg :: Env -> (Val, Arg) -> Env
  237. bindArg env (v, (ADecl _ iden)) = extendVar env iden (Just v)
  238.  
  239. evalExps :: Env -> [Exp] -> IO ([Val], Env)
  240. evalExps env [] = return ([], env)
  241. evalExps env (e:es) = do
  242. (v, env') <- evalExp env e
  243. (vs, env'') <- evalExps env' es
  244. return (v:vs, env'')
  245.  
  246. interpreterErr :: Env -> String -> IO a
  247. interpreterErr env s = do
  248. putStrLn "INTERPRETER ERROR"
  249. putStrLn $ printEnv env
  250. putStrLn s
  251. exitFailure
  252.  
  253. conj :: Val -> Val -> Val
  254. conj (B n1) (B n2) = B (n1 && n2)
  255.  
  256. disj :: Val -> Val -> Val
  257. disj (B n1) (B n2) = B (n1 || n2)
  258.  
  259. add :: Val -> Val -> Val
  260. add (I n1) (I n2) = I (n1 + n2)
  261. add (D n1) (D n2) = D (n1 + n2)
  262. add (D n1) (I n2) = D (n1 + (fromInteger n2))
  263. add (I n1) (D n2) = D ((fromInteger n1) + n2)
  264.  
  265. mul :: Val -> Val -> Val
  266. mul (I n1) (I n2) = I (n1 * n2)
  267. mul (D n1) (D n2) = D (n1 * n2)
  268. mul (D n1) (I n2) = D (n1 * (fromInteger n2))
  269. mul (I n1) (D n2) = D ((fromInteger n1) * n2)
  270.  
  271. divide :: Val -> Val -> Val
  272. divide (I n1) (I n2) = I (div n1 n2)
  273. divide (D n1) (D n2) = D (n1 / n2)
  274. divide (D n1) (I n2) = D (n1 / (fromInteger n2))
  275. divide (I n1) (D n2) = D ((fromInteger n1) / n2)
  276.  
  277. sub :: Val -> Val -> Val
  278. sub (I n1) (I n2) = I (n1 - n2)
  279. sub (D n1) (D n2) = D (n1 - n2)
  280. sub (D n1) (I n2) = D (n1 - (fromInteger n2))
  281. sub (I n1) (D n2) = D ((fromInteger n1) - n2)
  282.  
  283. inc :: Val -> Val
  284. inc (I n) = I (n+1)
  285. inc (D n) = D (n+1)
  286.  
  287. dec :: Val -> Val
  288. dec (I n) = I (n-1)
  289. dec (D n) = D (n-1)
  290.  
  291. less :: Val -> Val -> Val
  292. less (I n1) (I n2) = B (n1 < n2)
  293. less (D n1) (D n2) = B (n1 < n2)
  294. less (I n1) (D n2) = B ((fromInteger n1) < n2)
  295. less (D n1) (I n2) = B (n1 < (fromInteger n2))
  296.  
  297. leq :: Val -> Val -> Val
  298. leq (I n1) (I n2) = B (n1 <= n2)
  299. leq (D n1) (D n2) = B (n1 <= n2)
  300. leq (I n1) (D n2) = B ((fromInteger n1) <= n2)
  301. leq (D n1) (I n2) = B (n1 <= (fromInteger n2))
  302.  
  303. geq :: Val -> Val -> Val
  304. geq (I n1) (I n2) = B (n1 >= n2)
  305. geq (D n1) (D n2) = B (n1 >= n2)
  306. geq (I n1) (D n2) = B ((fromInteger n1) >= n2)
  307. geq (D n1) (I n2) = B (n1 >= (fromInteger n2))
  308.  
  309. greater :: Val -> Val -> Val
  310. greater (I n1) (I n2) = B (n1 > n2)
  311. greater (D n1) (D n2) = B (n1 > n2)
  312. greater (I n1) (D n2) = B ((fromInteger n1) > n2)
  313. greater (D n1) (I n2) = B (n1 > (fromInteger n2))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement