Skip to content

Commit

Permalink
basics of new environment set up
Browse files Browse the repository at this point in the history
  • Loading branch information
tdfirth committed Jul 9, 2017
1 parent 4fe8f0d commit e60d797
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 9 deletions.
1 change: 1 addition & 0 deletions lambda.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ executable lambda
, parsec
, mtl
, haskeline
, containers
hs-source-dirs: src
default-language: Haskell2010

Expand Down
49 changes: 45 additions & 4 deletions src/Lambda/Environment.hs
Original file line number Diff line number Diff line change
@@ -1,8 +1,49 @@
{-# LANGUAGE MultiParamTypeClasses, TypeFamilies, FlexibleInstances #-}
module Lambda.Environment where

import Lambda.Types

import qualified Data.Map.Strict as Map
import Data.IORef
import Control.Monad.Except
import System.IO
import Lambda.Types hiding (Env, isBound, getVar, setVar, defineVar, bindVars)

type Environment = IORef (Map.Map String (IORef LispVal))

nullEnv :: IO Environment
nullEnv = newIORef Map.empty

isBound :: Environment -> String -> IO Bool
isBound e s = readIORef e >>= return . Map.member s

getVar :: Environment -> String -> IOThrowsError LispVal
getVar e s = do
env <- liftIO $ readIORef e
case Map.lookup s env of
Just v -> liftIO $ readIORef v
Nothing -> throwError $ UnboundVar "Trying to get an unbound variable..." s

updateVar :: Environment -> String -> LispVal -> IOThrowsError LispVal
updateVar e s l = do
env <- liftIO $ readIORef e
case Map.lookup s env of
Just v -> liftIO $ writeIORef v l
Nothing -> throwError $ UnboundVar "Trying to update an unbound variable.." s
return l

defineVar :: Environment -> String -> LispVal -> IOThrowsError LispVal
defineVar e s l = do
defined <- liftIO $ isBound e s
if defined then updateVar e s l
else liftIO $ do
newVar <- newIORef l
modifyIORef' e $ Map.insert s newVar
return l

foo :: Int
foo = 1
bindVars :: Environment -> [(String, LispVal)] -> IO Environment
bindVars e ls = do
updates <- mapM mkRef ls >>= return . Map.fromList
modifyIORef' e (Map.union updates)
return e
where
mkRef :: (String, LispVal) -> IO (String, IORef LispVal)
mkRef (s, l) = newIORef l >>= return . (,) s
8 changes: 3 additions & 5 deletions src/Lambda/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ showVal (Vector contents) = "(" ++ unwordsList contents ++ ")"
showVal (IOFunc _) = "<IO primitive>"
showVal (Port _) = "<IO port>"
showVal (PrimitiveFunc _) = "<primitive>"
showVal (Func {params = args,
vararg = varargs,
body = body,
showVal (Func {params = args ,
vararg = varargs ,
body = body ,
closure = env}) = "(lambda (" ++ unwords (map show args) ++
(case varargs of
Nothing -> ""
Expand Down Expand Up @@ -138,5 +138,3 @@ bindVars envRef bindings = readIORef envRef >>= extendEnv bindings >>= newIORef
where extendEnv bindings env = liftM (++ env) (mapM addBinding bindings)
addBinding (var, value) = do ref <- newIORef value
return (var, ref)


0 comments on commit e60d797

Please sign in to comment.