Substitute with the version from the video

This commit is contained in:
2025-04-12 19:40:32 -07:00
parent 288c999c0e
commit 2e819b454f
7 changed files with 162 additions and 168 deletions

View File

@@ -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