From 1cc5b0b03a408cd197974c19d407d4fc28dece74 Mon Sep 17 00:00:00 2001 From: darkf Date: Thu, 17 Oct 2013 18:58:41 -0700 Subject: [PATCH] initial commit --- interp.hs | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 interp.hs diff --git a/interp.hs b/interp.hs new file mode 100644 index 0000000..71c0c27 --- /dev/null +++ b/interp.hs @@ -0,0 +1,53 @@ +import Control.Monad.State (State, runState, evalState, get, put) +import qualified Data.Map as M + +data AST = Add AST AST + | Def String AST + | Var String + | StrConst String + | IntConst Int + deriving (Show, Eq) + +data Value = IntV Int + | StrV String + deriving (Show, Eq) + +type Env = M.Map String Value -- an environment +type InterpState = State Env -- interpreter state (pass along the global environment) + +(IntV l) +$ (IntV r) = IntV (l + r) +(StrV l) +$ (StrV r) = StrV (l ++ r) +l +$ r = error $ "cannot + " ++ show l ++ " and " ++ show r + +eval :: AST -> InterpState Value + +eval (IntConst i) = return $ IntV i +eval (StrConst s) = return $ StrV s + +eval (Var var) = get >>= \m -> + case M.lookup var m of + Just v -> return v + Nothing -> error $ "unbound variable " ++ var + +eval (Def name v') = do + v <- eval v' + m <- get + put $ M.insert name v m + return v + +eval (Add l r) = do + l <- eval l + r <- eval r + return $ l +$ r + +evalProgram :: [AST] -> Value -- fold the state from each node and return the result +evalProgram nodes = evalState (foldr1 (>>) $ map eval nodes) M.empty + +main = do + print $ evalProgram prg + print $ evalProgram prg2 + where + prg = [Def "x" (IntConst 5), + Def "y" (IntConst 3), + Add (Var "x") (Var "y")] + prg2 = [Add (StrConst "hi ") (StrConst "there")] \ No newline at end of file