Last active
August 5, 2017 20:24
-
-
Save jw3126/822d3139665007b78d4570974e8a6764 to your computer and use it in GitHub Desktop.
Interpreter in haskell that can store and retrieve variables
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Data.Map as Map | |
import Data.Map | |
import Control.Monad.State.Lazy | |
import Control.Monad | |
data Expr = ExInteger Integer | |
| ExSymbol String | |
| ExBinding String Expr deriving (Show) | |
type Errorful t = Either String t | |
type Store = Map String Expr | |
type InterpreterM t = StateT Store IO (Errorful t) | |
eval :: Expr -> InterpreterM Expr | |
eval x@(ExInteger _) = return $ Right x | |
eval x@(ExSymbol s) = do | |
store <- get | |
liftIO $ putStrLn $ "looking for " ++ (show x) | |
case Map.lookup s store of | |
Nothing -> return $ Left $ "undefined variable: " ++ (show x) | |
Just ex -> return $ Right ex | |
eval x@(ExBinding s v) = do | |
store <- get | |
liftIO $ putStrLn $ "defining " ++ (show x) | |
ev <- eval v | |
case ev of | |
Left msg -> return $ Left msg | |
Right val -> do put $ Map.insert s val store | |
return $ Right x | |
store :: Store | |
store = empty | |
repl1 :: InterpreterM Expr | |
repl1 = do | |
s <- liftIO getLine | |
eval $ ExBinding s (ExInteger 2) | |
eval $ ExSymbol s | |
repl :: InterpreterM Expr | |
repl = forever repl1 | |
main = runStateT repl store | |
main |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment