module Language.Scheme.Macro.ExplicitRenaming
(
explicitRenamingTransform
) where
import Language.Scheme.Types
import Language.Scheme.Variables
import Language.Scheme.Primitives (_gensym)
import Control.Monad.Except
explicitRenamingTransform ::
Env
-> Env
-> Env
-> LispVal
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
explicitRenamingTransform :: Env
-> Env
-> Env
-> LispVal
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
explicitRenamingTransform Env
useEnv Env
renameEnv Env
srRenameEnv LispVal
lisp
transformer :: LispVal
transformer@(Func [String]
_ Maybe String
_ [LispVal]
_ Env
defEnv) LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply = do
let continuation :: LispVal
continuation = Env -> LispVal
makeNullContinuation Env
useEnv
LispVal
result <- LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply
LispVal
continuation
LispVal
transformer
[LispVal
lisp,
([LispVal] -> IOThrowsError LispVal) -> LispVal
IOFunc (([LispVal] -> IOThrowsError LispVal) -> LispVal)
-> ([LispVal] -> IOThrowsError LispVal) -> LispVal
forall a b. (a -> b) -> a -> b
$ Env -> Env -> Env -> Env -> [LispVal] -> IOThrowsError LispVal
exRename Env
useEnv Env
renameEnv Env
srRenameEnv Env
defEnv,
([LispVal] -> IOThrowsError LispVal) -> LispVal
IOFunc (([LispVal] -> IOThrowsError LispVal) -> LispVal)
-> ([LispVal] -> IOThrowsError LispVal) -> LispVal
forall a b. (a -> b) -> a -> b
$ Env -> Env -> Env -> [LispVal] -> IOThrowsError LispVal
exCompare Env
useEnv Env
renameEnv Env
defEnv]
LispVal -> IOThrowsError LispVal
recDerefPtrs LispVal
result
explicitRenamingTransform Env
_ Env
_ Env
_ LispVal
_ LispVal
_ LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
_ =
LispError -> IOThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> IOThrowsError LispVal)
-> LispError -> IOThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ String -> LispError
InternalError String
"explicitRenamingTransform"
exRename :: Env -> Env -> Env -> Env -> [LispVal] -> IOThrowsError LispVal
exRename :: Env -> Env -> Env -> Env -> [LispVal] -> IOThrowsError LispVal
exRename Env
useEnv Env
_ Env
srRenameEnv Env
defEnv [Atom String
a] = do
Bool
isSynRulesRenamed <- IO Bool -> ExceptT LispError IO Bool
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Bool -> ExceptT LispError IO Bool)
-> IO Bool -> ExceptT LispError IO Bool
forall a b. (a -> b) -> a -> b
$ Env -> String -> IO Bool
isRecBound Env
srRenameEnv String
a
if Bool
isSynRulesRenamed
then Env -> String -> IOThrowsError LispVal
getVar Env
srRenameEnv String
a
else do
Bool
isDef <- IO Bool -> ExceptT LispError IO Bool
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Bool -> ExceptT LispError IO Bool)
-> IO Bool -> ExceptT LispError IO Bool
forall a b. (a -> b) -> a -> b
$ Env -> String -> IO Bool
isRecBound Env
defEnv String
a
if Bool
isDef
then do
Maybe LispVal
r <- Env -> Char -> String -> IOThrowsError (Maybe LispVal)
getNamespacedVar' Env
useEnv Char
'r' String
a
case Maybe LispVal
r of
Just LispVal
renamed -> LispVal -> IOThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return LispVal
renamed
Maybe LispVal
Nothing -> do
LispVal
value <- Env -> String -> IOThrowsError LispVal
getVar Env
defEnv String
a
Atom String
renamed <- String -> IOThrowsError LispVal
_gensym String
a
LispVal
_ <- Env -> String -> LispVal -> IOThrowsError LispVal
defineVar Env
useEnv String
renamed LispVal
value
LispVal
_ <- Env -> Char -> String -> LispVal -> IOThrowsError LispVal
defineNamespacedVar Env
useEnv Char
'r' String
a (LispVal -> IOThrowsError LispVal)
-> LispVal -> IOThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ String -> LispVal
Atom String
renamed
List [LispVal]
diverted <- Env -> Char -> String -> IOThrowsError LispVal
getNamespacedVar Env
useEnv Char
' ' String
"diverted"
LispVal
_ <- Env -> Char -> String -> LispVal -> IOThrowsError LispVal
setNamespacedVar Env
useEnv Char
' ' String
"diverted" (LispVal -> IOThrowsError LispVal)
-> LispVal -> IOThrowsError LispVal
forall a b. (a -> b) -> a -> b
$
[LispVal] -> LispVal
List ([LispVal]
diverted [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ [[LispVal] -> LispVal
List [String -> LispVal
Atom String
renamed, String -> LispVal
Atom String
a]])
LispVal -> IOThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> IOThrowsError LispVal)
-> LispVal -> IOThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ String -> LispVal
Atom String
renamed
else
LispVal -> IOThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> IOThrowsError LispVal)
-> LispVal -> IOThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ String -> LispVal
Atom String
a
exRename Env
_ Env
_ Env
_ Env
_ [LispVal]
form = LispError -> IOThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> IOThrowsError LispVal)
-> LispError -> IOThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ String -> LispError
Default (String -> LispError) -> String -> LispError
forall a b. (a -> b) -> a -> b
$ String
"Unable to rename: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ [LispVal] -> String
forall a. Show a => a -> String
show [LispVal]
form
exCompare :: Env
-> Env
-> Env
-> [LispVal]
-> IOThrowsError LispVal
exCompare :: Env -> Env -> Env -> [LispVal] -> IOThrowsError LispVal
exCompare Env
_ Env
_ Env
_ [LispVal
a, LispVal
b] = do
LispVal -> IOThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return (LispVal -> IOThrowsError LispVal)
-> LispVal -> IOThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool (Bool -> LispVal) -> Bool -> LispVal
forall a b. (a -> b) -> a -> b
$ LispVal -> LispVal -> Bool
eqVal LispVal
a LispVal
b
exCompare Env
_ Env
_ Env
_ [LispVal]
form = LispError -> IOThrowsError LispVal
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError (LispError -> IOThrowsError LispVal)
-> LispError -> IOThrowsError LispVal
forall a b. (a -> b) -> a -> b
$
String -> LispError
Default (String -> LispError) -> String -> LispError
forall a b. (a -> b) -> a -> b
$ String
"Unable to compare: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ [LispVal] -> String
forall a. Show a => a -> String
show [LispVal]
form