Substitute with the version from the video
This commit is contained in:
@@ -1,20 +1,25 @@
|
||||
{-# LANGUAGE InstanceSigs #-}
|
||||
module Primitives
|
||||
( PrologIO(..)
|
||||
, Globals
|
||||
, newGlobals
|
||||
, newVarPrim, unnewVarPrim
|
||||
, getVarPrim, setVarPrim
|
||||
, errorPrim
|
||||
)
|
||||
where
|
||||
|
||||
import Data.IORef
|
||||
( Globals(..)
|
||||
, PrologIO(..)
|
||||
, newGlobals
|
||||
, newVarPrim, unnewVarPrim, getVarPrim, setVarPrim, errorPrim
|
||||
) where
|
||||
import Classes
|
||||
import qualified Data.IntMap.Strict as M
|
||||
import Data.IORef
|
||||
import Terms
|
||||
import Classes (LiftIO(..))
|
||||
|
||||
newtype PrologIO a = PrologIO { runPrologIO :: Globals -> IO a }
|
||||
data Globals = Globals
|
||||
{ values :: IORef (M.IntMap Term)
|
||||
, names :: IORef (M.IntMap Name)
|
||||
, nextSlot :: IORef Int
|
||||
}
|
||||
|
||||
instance LiftIO PrologIO where
|
||||
liftIO :: IO a -> PrologIO a
|
||||
liftIO io = PrologIO (\_ -> io)
|
||||
|
||||
instance Functor PrologIO where
|
||||
fmap :: (a -> b) -> PrologIO a -> PrologIO b
|
||||
@@ -24,17 +29,19 @@ instance Applicative PrologIO where
|
||||
pure :: a -> PrologIO a
|
||||
pure x = PrologIO (\_ -> pure x)
|
||||
|
||||
(<*>) :: PrologIO (a -> b) -> PrologIO a -> PrologIO b
|
||||
(PrologIO f) <*> (PrologIO x) = PrologIO (
|
||||
\globals -> do
|
||||
f' <- f globals
|
||||
x' <- x globals
|
||||
pure (f' x')
|
||||
return (f' x')
|
||||
)
|
||||
|
||||
instance Monad PrologIO where
|
||||
return :: a -> PrologIO a
|
||||
return = pure
|
||||
|
||||
(>>=) :: PrologIO a -> (a -> PrologIO b) -> PrologIO b
|
||||
(PrologIO a) >>= f = PrologIO (
|
||||
\globals -> do
|
||||
a' <- a globals
|
||||
@@ -42,44 +49,33 @@ instance Monad PrologIO where
|
||||
b' globals
|
||||
)
|
||||
|
||||
data Globals = Globals
|
||||
{ values :: IORef (M.IntMap Term)
|
||||
, names :: IORef (M.IntMap Name)
|
||||
, nextVar :: IORef Int
|
||||
}
|
||||
|
||||
newGlobals :: IO (Globals)
|
||||
newGlobals :: IO Globals
|
||||
newGlobals = do
|
||||
vs <- newIORef (M.empty)
|
||||
ns <- newIORef (M.empty)
|
||||
vs <- newIORef M.empty
|
||||
ns <- newIORef M.empty
|
||||
next <- newIORef 0
|
||||
return $ Globals { values = vs, names = ns, nextVar = next }
|
||||
return Globals { values=vs, names=ns, nextSlot=next }
|
||||
|
||||
newVarPrim :: Name -> PrologIO Var
|
||||
newVarPrim :: Name -> PrologIO Slot
|
||||
newVarPrim name = PrologIO $ \globals -> do
|
||||
var <- readIORef (nextVar globals)
|
||||
modifyIORef (names globals) (M.insert var name)
|
||||
modifyIORef (nextVar globals) succ
|
||||
return (VInt var)
|
||||
slot <- readIORef (nextSlot globals)
|
||||
modifyIORef (names globals) (M.insert slot name)
|
||||
modifyIORef (nextSlot globals) (\s -> s + 1)
|
||||
return (Slot slot)
|
||||
|
||||
unnewVarPrim :: PrologIO ()
|
||||
unnewVarPrim = PrologIO $ \globals -> do
|
||||
modifyIORef (nextVar globals) pred
|
||||
var <- readIORef (nextVar globals)
|
||||
modifyIORef (names globals) (M.delete var)
|
||||
return ()
|
||||
modifyIORef (nextSlot globals) (\s -> s - 1)
|
||||
slot <- readIORef (nextSlot globals)
|
||||
modifyIORef (names globals) (M.delete slot)
|
||||
|
||||
getVarPrim :: Var -> PrologIO (Maybe Term)
|
||||
getVarPrim (VInt var) = PrologIO $ \globals ->
|
||||
fmap (M.lookup var) (readIORef (values globals))
|
||||
getVarPrim :: Slot -> PrologIO (Maybe Term)
|
||||
getVarPrim (Slot slot) = PrologIO $ \globals ->
|
||||
fmap (M.lookup slot) (readIORef (values globals))
|
||||
|
||||
setVarPrim :: Var -> Maybe Term -> PrologIO ()
|
||||
setVarPrim (VInt var) term = PrologIO $ \globals -> do
|
||||
modifyIORef (values globals) (M.alter (\_ -> term) var)
|
||||
return ()
|
||||
setVarPrim :: Slot -> Maybe Term -> PrologIO ()
|
||||
setVarPrim (Slot slot) term = PrologIO $ \globals ->
|
||||
modifyIORef (values globals) (M.alter (\_ -> term) slot)
|
||||
|
||||
errorPrim :: String -> PrologIO a
|
||||
errorPrim message = error message
|
||||
|
||||
instance LiftIO PrologIO where
|
||||
liftIO x = PrologIO (\_ -> x)
|
||||
errorPrim message = error message
|
||||
Reference in New Issue
Block a user