module Language.Scheme.Macro
    (
      expand
    , macroEval
    , loadMacros  
    , getDivertedVars 
    ) where
import Language.Scheme.Types
import Language.Scheme.Variables
import Language.Scheme.Macro.ExplicitRenaming
import qualified Language.Scheme.Macro.Matches as Matches
import Language.Scheme.Primitives (_gensym)
import Control.Monad.Except
import Data.Array
getDivertedVars :: Env -> IOThrowsError [LispVal]
getDivertedVars :: Env -> IOThrowsError [LispVal]
getDivertedVars Env
env = do
  List [LispVal]
tmp <- Env -> Char -> String -> IOThrowsError LispVal
getNamespacedVar Env
env Char
' ' String
"diverted"
  [LispVal] -> IOThrowsError [LispVal]
forall (m :: * -> *) a. Monad m => a -> m a
return [LispVal]
tmp
clearDivertedVars :: Env -> IOThrowsError LispVal
clearDivertedVars :: Env -> IOThrowsError LispVal
clearDivertedVars Env
env = Env -> Char -> String -> LispVal -> IOThrowsError LispVal
defineNamespacedVar Env
env Char
' ' String
"diverted" (LispVal -> IOThrowsError LispVal)
-> LispVal -> IOThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal] -> LispVal
List []
macroEval :: Env        
          -> LispVal    
          -> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal) 
          -> IOThrowsError LispVal 
                                   
macroEval :: Env
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
macroEval Env
env lisp :: LispVal
lisp@(List (Atom String
_ : [LispVal]
_)) LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply = do
  
  LispVal
_ <- Env -> IOThrowsError LispVal
clearDivertedVars Env
env
  Env
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
_macroEval Env
env LispVal
lisp LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply
macroEval Env
env LispVal
lisp LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply = Env
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
_macroEval Env
env LispVal
lisp LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply
_macroEval :: Env
           -> LispVal
           -> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
           -> ExceptT LispError IO LispVal
_macroEval :: Env
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
_macroEval Env
env lisp :: LispVal
lisp@(List (Atom String
x : [LispVal]
_)) LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply = do
  
  Maybe LispVal
var <- Env -> Char -> String -> IOThrowsError (Maybe LispVal)
getNamespacedVar' Env
env Char
macroNamespace String
x
  
  case Maybe LispVal
var of
    
    Just (SyntaxExplicitRenaming transformer :: LispVal
transformer@(Func {})) -> do
      Env
renameEnv <- IO Env -> ExceptT LispError IO Env
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Env -> ExceptT LispError IO Env)
-> IO Env -> ExceptT LispError IO Env
forall a b. (a -> b) -> a -> b
$ IO Env
nullEnv 
      LispVal
expanded <- Env
-> Env
-> Env
-> LispVal
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
explicitRenamingTransform Env
env Env
renameEnv Env
renameEnv 
                                          LispVal
lisp LispVal
transformer LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply
      Env
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
_macroEval Env
env LispVal
expanded LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply
    
    Just (Syntax (Just Env
defEnv) Maybe Env
_ Bool
definedInMacro String
ellipsis [LispVal]
identifiers [LispVal]
rules) -> do
      Env
renameEnv <- IO Env -> ExceptT LispError IO Env
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Env -> ExceptT LispError IO Env)
-> IO Env -> ExceptT LispError IO Env
forall a b. (a -> b) -> a -> b
$ IO Env
nullEnv 
                                    
      Env
cleanupEnv <- IO Env -> ExceptT LispError IO Env
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Env -> ExceptT LispError IO Env)
-> IO Env -> ExceptT LispError IO Env
forall a b. (a -> b) -> a -> b
$ IO Env
nullEnv 
                                     
                                     
                                     
                                     
      
      
      LispVal
expanded <- [Env]
-> Env
-> Env
-> Env
-> Env
-> Bool
-> LispVal
-> [LispVal]
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> String
-> IOThrowsError LispVal
macroTransform [Env
defEnv] Env
env Env
env Env
renameEnv Env
cleanupEnv 
                                 Bool
definedInMacro 
                                ([LispVal] -> LispVal
List [LispVal]
identifiers) [LispVal]
rules LispVal
lisp LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply
                                String
ellipsis
      Env
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
_macroEval Env
env LispVal
expanded LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply
      
      
    Just 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
"_macroEval"
    Maybe LispVal
Nothing -> LispVal -> IOThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return LispVal
lisp
_macroEval Env
_ LispVal
lisp LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
_ = LispVal -> IOThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return LispVal
lisp
macroTransform :: 
     [Env]
  -> Env 
  -> Env 
  -> Env 
  -> Env 
  -> Bool 
  -> LispVal 
  -> [LispVal] 
  -> LispVal 
  -> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal) 
  -> String 
  -> IOThrowsError LispVal
macroTransform :: [Env]
-> Env
-> Env
-> Env
-> Env
-> Bool
-> LispVal
-> [LispVal]
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> String
-> IOThrowsError LispVal
macroTransform [Env]
defEnv Env
env Env
divertEnv Env
renameEnv Env
cleanupEnv Bool
dim LispVal
identifiers (rule :: LispVal
rule@(List [LispVal]
_) : [LispVal]
rs) LispVal
input LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply String
esym = do
  Env
localEnv <- IO Env -> ExceptT LispError IO Env
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Env -> ExceptT LispError IO Env)
-> IO Env -> ExceptT LispError IO Env
forall a b. (a -> b) -> a -> b
$ IO Env
nullEnv 
                               
  LispVal
result <- [Env]
-> Env
-> Env
-> Bool
-> LispVal
-> Env
-> Env
-> Env
-> LispVal
-> LispVal
-> String
-> IOThrowsError LispVal
matchRule [Env]
defEnv Env
env Env
divertEnv Bool
dim LispVal
identifiers Env
localEnv Env
renameEnv Env
cleanupEnv LispVal
rule LispVal
input String
esym
  case LispVal
result of
    
    Nil String
_ -> [Env]
-> Env
-> Env
-> Env
-> Env
-> Bool
-> LispVal
-> [LispVal]
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> String
-> IOThrowsError LispVal
macroTransform [Env]
defEnv Env
env Env
divertEnv Env
renameEnv Env
cleanupEnv Bool
dim LispVal
identifiers [LispVal]
rs LispVal
input LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply String
esym
    LispVal
_ -> do
        
        [Env]
-> Env
-> Env
-> Env
-> Env
-> Bool
-> Bool
-> Bool
-> LispVal
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
walkExpanded [Env]
defEnv Env
env Env
divertEnv Env
renameEnv Env
cleanupEnv Bool
dim Bool
True Bool
False ([LispVal] -> LispVal
List []) LispVal
result LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply
macroTransform [Env]
_ Env
_ Env
_ Env
_ Env
_ Bool
_ LispVal
_ [LispVal]
_ LispVal
input LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
_ String
_ = 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 -> LispVal -> LispError
BadSpecialForm String
"Input does not match a macro pattern" LispVal
input
macroElementMatchesMany :: LispVal -> String -> Bool
macroElementMatchesMany :: LispVal -> String -> Bool
macroElementMatchesMany (List (LispVal
_ : [LispVal]
ps)) String
ellipsisSym = do
  Bool -> Bool
not ([LispVal] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [LispVal]
ps) Bool -> Bool -> Bool
&& (([LispVal] -> LispVal
forall a. [a] -> a
head [LispVal]
ps) LispVal -> LispVal -> Bool
forall a. Eq a => a -> a -> Bool
== (String -> LispVal
Atom String
ellipsisSym))
macroElementMatchesMany LispVal
_ String
_ = Bool
False
matchRule :: [Env] -> Env -> Env -> Bool -> LispVal -> Env -> Env -> Env -> LispVal -> LispVal -> String -> IOThrowsError LispVal
matchRule :: [Env]
-> Env
-> Env
-> Bool
-> LispVal
-> Env
-> Env
-> Env
-> LispVal
-> LispVal
-> String
-> IOThrowsError LispVal
matchRule [Env]
defEnv Env
outerEnv Env
divertEnv Bool
dim LispVal
identifiers Env
localEnv Env
renameEnv Env
cleanupEnv (List [LispVal
pattern, LispVal
template]) (List [LispVal]
inputVar) String
esym = do
   let is :: [LispVal]
is = [LispVal] -> [LispVal]
forall a. [a] -> [a]
tail [LispVal]
inputVar
   let p :: (LispVal, Bool)
p = case LispVal
pattern of
              DottedList [LispVal]
ds LispVal
d -> case [LispVal]
ds of
                                  
                                  
                                  (Atom String
l : [LispVal]
ls) -> ([LispVal] -> LispVal
List [String -> LispVal
Atom String
l, [LispVal] -> LispVal -> LispVal
DottedList [LispVal]
ls LispVal
d], Bool
True)
                                  [LispVal]
_ -> (LispVal
pattern, Bool
False)
              LispVal
_ -> (LispVal
pattern, Bool
False)
   case (LispVal, Bool)
p of
      ((List (Atom String
_ : [LispVal]
ps)), Bool
flag) -> do
        LispVal
match <- [LispVal] -> [LispVal] -> Bool -> IOThrowsError LispVal
checkPattern [LispVal]
ps [LispVal]
is Bool
flag 
        case LispVal
match of
           Bool Bool
False -> 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
Nil String
""
           LispVal
_ -> do
                [Env]
-> Env
-> Env
-> Env
-> Env
-> Env
-> Bool
-> LispVal
-> String
-> Int
-> [Int]
-> LispVal
-> LispVal
-> IOThrowsError LispVal
transformRule [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv Env
cleanupEnv Bool
dim LispVal
identifiers String
esym Int
0 [] ([LispVal] -> LispVal
List []) LispVal
template
      (LispVal, Bool)
_ -> 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 -> LispVal -> LispError
BadSpecialForm String
"Malformed rule in syntax-rules" (LispVal -> LispError) -> LispVal -> LispError
forall a b. (a -> b) -> a -> b
$ String -> LispVal
String (String -> LispVal) -> String -> LispVal
forall a b. (a -> b) -> a -> b
$ (LispVal, Bool) -> String
forall a. Show a => a -> String
show (LispVal, Bool)
p
 where
   
   
   checkPattern :: [LispVal] -> [LispVal] -> Bool -> IOThrowsError LispVal
checkPattern ps :: [LispVal]
ps@(DottedList [LispVal]
ds LispVal
d : [LispVal]
_) [LispVal]
is Bool
True = do
     case [LispVal]
is of
       (DottedList [LispVal]
_ LispVal
_ : [LispVal]
_) -> do 
         [Env]
-> Env
-> Env
-> Env
-> Env
-> LispVal
-> LispVal
-> LispVal
-> Int
-> [Int]
-> [(Bool, Bool)]
-> String
-> IOThrowsError LispVal
loadLocal [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv LispVal
identifiers 
                                  ([LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
ds [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ [LispVal
d, String -> LispVal
Atom String
esym])
                                  ([LispVal] -> LispVal
List [LispVal]
is)
                                   Int
0 []
                                  ([(Bool, Bool)] -> (Bool, Bool) -> Int -> [(Bool, Bool)]
flagDottedLists [] (Bool
False, Bool
False) (Int -> [(Bool, Bool)]) -> Int -> [(Bool, Bool)]
forall a b. (a -> b) -> a -> b
$ Int
0 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ ([LispVal] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([LispVal] -> Int) -> [LispVal] -> Int
forall a b. (a -> b) -> a -> b
$ (LispVal -> Bool) -> [LispVal] -> [LispVal]
forall a. (a -> Bool) -> [a] -> [a]
filter (String -> LispVal -> Bool
filterEsym String
esym) [LispVal]
ds)) 
                                  String
esym
       (List [LispVal]
_ : [LispVal]
_) -> do 
         [Env]
-> Env
-> Env
-> Env
-> Env
-> LispVal
-> LispVal
-> LispVal
-> Int
-> [Int]
-> [(Bool, Bool)]
-> String
-> IOThrowsError LispVal
loadLocal [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv LispVal
identifiers 
                                  ([LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
ds [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ [LispVal
d, String -> LispVal
Atom String
esym])
                                  ([LispVal] -> LispVal
List [LispVal]
is)
                                   Int
0 []
                                  ([(Bool, Bool)] -> (Bool, Bool) -> Int -> [(Bool, Bool)]
flagDottedLists [] (Bool
True, Bool
False) (Int -> [(Bool, Bool)]) -> Int -> [(Bool, Bool)]
forall a b. (a -> b) -> a -> b
$ Int
0 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ ([LispVal] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([LispVal] -> Int) -> [LispVal] -> Int
forall a b. (a -> b) -> a -> b
$ (LispVal -> Bool) -> [LispVal] -> [LispVal]
forall a. (a -> Bool) -> [a] -> [a]
filter (String -> LispVal -> Bool
filterEsym String
esym) [LispVal]
ds)) 
                                  String
esym
       [LispVal]
_ -> [Env]
-> Env
-> Env
-> Env
-> Env
-> LispVal
-> LispVal
-> LispVal
-> Int
-> [Int]
-> [(Bool, Bool)]
-> String
-> IOThrowsError LispVal
loadLocal [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv LispVal
identifiers ([LispVal] -> LispVal
List [LispVal]
ps) ([LispVal] -> LispVal
List [LispVal]
is) Int
0 [] [] String
esym
   
   checkPattern [LispVal]
ps [LispVal]
is Bool
_ = [Env]
-> Env
-> Env
-> Env
-> Env
-> LispVal
-> LispVal
-> LispVal
-> Int
-> [Int]
-> [(Bool, Bool)]
-> String
-> IOThrowsError LispVal
loadLocal [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv LispVal
identifiers ([LispVal] -> LispVal
List [LispVal]
ps) ([LispVal] -> LispVal
List [LispVal]
is) Int
0 [] [] String
esym
matchRule [Env]
_ Env
_ Env
_ Bool
_ LispVal
_ Env
_ Env
_ Env
_ LispVal
rule LispVal
input String
_ = do
  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 -> LispVal -> LispError
BadSpecialForm String
"Malformed rule in syntax-rules" (LispVal -> LispError) -> LispVal -> LispError
forall a b. (a -> b) -> a -> b
$ [LispVal] -> LispVal
List [String -> LispVal
Atom String
"rule: ", LispVal
rule, String -> LispVal
Atom String
"input: ", LispVal
input]
loadLocal :: [Env] -> Env -> Env -> Env -> Env -> LispVal -> LispVal -> LispVal -> Int -> [Int] -> [(Bool, Bool)] -> String -> IOThrowsError LispVal
loadLocal :: [Env]
-> Env
-> Env
-> Env
-> Env
-> LispVal
-> LispVal
-> LispVal
-> Int
-> [Int]
-> [(Bool, Bool)]
-> String
-> IOThrowsError LispVal
loadLocal [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv LispVal
identifiers LispVal
pattern LispVal
input Int
ellipsisLevel [Int]
ellipsisIndex [(Bool, Bool)]
listFlags String
esym = do
  
  case (LispVal
pattern, LispVal
input) of
       ((DottedList [LispVal]
ps LispVal
p), (DottedList [LispVal]
isRaw LispVal
iRaw)) -> do
         
         
         
         
         let isSplit :: ([LispVal], [LispVal])
isSplit = Int -> [LispVal] -> ([LispVal], [LispVal])
forall a. Int -> [a] -> ([a], [a])
splitAt ([LispVal] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [LispVal]
ps) [LispVal]
isRaw
         let is :: [LispVal]
is = ([LispVal], [LispVal]) -> [LispVal]
forall a b. (a, b) -> a
fst ([LispVal], [LispVal])
isSplit
         let i :: [LispVal]
i = (([LispVal], [LispVal]) -> [LispVal]
forall a b. (a, b) -> b
snd ([LispVal], [LispVal])
isSplit) [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ [LispVal
iRaw]
         LispVal
result <- [Env]
-> Env
-> Env
-> Env
-> Env
-> LispVal
-> LispVal
-> LispVal
-> Int
-> [Int]
-> [(Bool, Bool)]
-> String
-> IOThrowsError LispVal
loadLocal [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv LispVal
identifiers ([LispVal] -> LispVal
List [LispVal]
ps) ([LispVal] -> LispVal
List [LispVal]
is) Int
ellipsisLevel [Int]
ellipsisIndex [(Bool, Bool)]
listFlags String
esym
         case LispVal
result of
            Bool Bool
True -> 
                         
                         [Env]
-> Env
-> Env
-> Env
-> Env
-> LispVal
-> LispVal
-> LispVal
-> Int
-> [Int]
-> [(Bool, Bool)]
-> String
-> IOThrowsError LispVal
loadLocal [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv LispVal
identifiers 
                                  ([LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal
p, String -> LispVal
Atom String
esym]) 
                                  ([LispVal] -> LispVal
List [LispVal]
i)
                                   Int
ellipsisLevel 
                                   [Int]
ellipsisIndex
                                   ([(Bool, Bool)] -> (Bool, Bool) -> Int -> [(Bool, Bool)]
flagDottedLists [(Bool, Bool)]
listFlags (Bool
True, Bool
True) (Int -> [(Bool, Bool)]) -> Int -> [(Bool, Bool)]
forall a b. (a -> b) -> a -> b
$ [Int] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
ellipsisIndex) 
                                   String
esym
            LispVal
_ -> 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
False
       (List (LispVal
p : [LispVal]
ps), List (LispVal
i : [LispVal]
is)) -> do 
         let nextHasEllipsis :: Bool
nextHasEllipsis = LispVal -> String -> Bool
macroElementMatchesMany LispVal
pattern String
esym
         let level :: Int
level = if Bool
nextHasEllipsis then Int
ellipsisLevel Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
                                        else Int
ellipsisLevel
         let idx :: [Int]
idx = if Bool
nextHasEllipsis 
                      then if ([Int] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
ellipsisIndex Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
level)
                              
                              then do
                                let l :: ([Int], [Int])
l = Int -> [Int] -> ([Int], [Int])
forall a. Int -> [a] -> ([a], [a])
splitAt (Int
level Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) [Int]
ellipsisIndex
                                (([Int], [Int]) -> [Int]
forall a b. (a, b) -> a
fst ([Int], [Int])
l) [Int] -> [Int] -> [Int]
forall a. [a] -> [a] -> [a]
++ [([Int] -> Int
forall a. [a] -> a
head (([Int], [Int]) -> [Int]
forall a b. (a, b) -> b
snd ([Int], [Int])
l)) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1]
                              
                              else [Int]
ellipsisIndex [Int] -> [Int] -> [Int]
forall a. [a] -> [a] -> [a]
++ [Int
0]
                      else [Int]
ellipsisIndex
         
         LispVal
status <- [Env]
-> Env
-> Env
-> Env
-> Env
-> LispVal
-> Int
-> [Int]
-> LispVal
-> LispVal
-> [(Bool, Bool)]
-> String
-> IOThrowsError LispVal
checkLocal [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv LispVal
identifiers Int
level [Int]
idx LispVal
p LispVal
i [(Bool, Bool)]
listFlags String
esym
         case LispVal
status of
              
              Bool Bool
False -> if Bool
nextHasEllipsis
                                
                                then do
                                        case [LispVal]
ps of
                                          [Atom String
_] -> 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
True 
                                          [LispVal]
_ -> [Env]
-> Env
-> Env
-> Env
-> Env
-> LispVal
-> LispVal
-> LispVal
-> Int
-> [Int]
-> [(Bool, Bool)]
-> String
-> IOThrowsError LispVal
loadLocal [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv LispVal
identifiers ([LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal] -> [LispVal]
forall a. [a] -> [a]
tail [LispVal]
ps) ([LispVal] -> LispVal
List (LispVal
i LispVal -> [LispVal] -> [LispVal]
forall a. a -> [a] -> [a]
: [LispVal]
is)) Int
ellipsisLevel [Int]
ellipsisIndex [(Bool, Bool)]
listFlags String
esym
                                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
$ Bool -> LispVal
Bool Bool
False
              
              LispVal
_ -> if Bool
nextHasEllipsis
                      then 
                           [Env]
-> Env
-> Env
-> Env
-> Env
-> LispVal
-> LispVal
-> LispVal
-> Int
-> [Int]
-> [(Bool, Bool)]
-> String
-> IOThrowsError LispVal
loadLocal [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv LispVal
identifiers LispVal
pattern ([LispVal] -> LispVal
List [LispVal]
is)
                            Int
ellipsisLevel 
                            [Int]
idx 
                            [(Bool, Bool)]
listFlags
                            String
esym
                      else [Env]
-> Env
-> Env
-> Env
-> Env
-> LispVal
-> LispVal
-> LispVal
-> Int
-> [Int]
-> [(Bool, Bool)]
-> String
-> IOThrowsError LispVal
loadLocal [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv LispVal
identifiers ([LispVal] -> LispVal
List [LispVal]
ps) ([LispVal] -> LispVal
List [LispVal]
is) Int
ellipsisLevel [Int]
ellipsisIndex [(Bool, Bool)]
listFlags String
esym
       
       (List [], List []) -> 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
True
       
       (List (LispVal
_ : [LispVal]
_), List []) -> do
         if (LispVal -> String -> Bool
macroElementMatchesMany LispVal
pattern String
esym)
            then do
              
              
              
              
              let flags :: (Bool, Bool)
flags = [Int] -> [(Bool, Bool)] -> (Bool, Bool)
getListFlags ([Int]
ellipsisIndex [Int] -> [Int] -> [Int]
forall a. [a] -> [a] -> [a]
++ [Int
0]) [(Bool, Bool)]
listFlags
              [Env]
-> Env
-> Env
-> LispVal
-> LispVal
-> Bool
-> String
-> IOThrowsError LispVal
flagUnmatchedVars [Env]
defEnv Env
outerEnv Env
localEnv LispVal
identifiers LispVal
pattern ((Bool, Bool) -> Bool
forall a b. (a, b) -> a
fst (Bool, Bool)
flags) String
esym
            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
$ Bool -> LispVal
Bool Bool
False
       
       (List [], LispVal
_) -> 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
False
       
       (LispVal
_, LispVal
_) -> [Env]
-> Env
-> Env
-> Env
-> Env
-> LispVal
-> Int
-> [Int]
-> LispVal
-> LispVal
-> [(Bool, Bool)]
-> String
-> IOThrowsError LispVal
checkLocal [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv LispVal
identifiers Int
ellipsisLevel [Int]
ellipsisIndex LispVal
pattern LispVal
input [(Bool, Bool)]
listFlags String
esym
flagUnmatchedVars :: [Env] -> Env -> Env -> LispVal -> LispVal -> Bool -> String -> IOThrowsError LispVal 
flagUnmatchedVars :: [Env]
-> Env
-> Env
-> LispVal
-> LispVal
-> Bool
-> String
-> IOThrowsError LispVal
flagUnmatchedVars [Env]
defEnv Env
outerEnv Env
localEnv LispVal
identifiers (DottedList [LispVal]
ps LispVal
p) Bool
partOfImproperPattern String
esym = do
  [Env]
-> Env
-> Env
-> LispVal
-> LispVal
-> Bool
-> String
-> IOThrowsError LispVal
flagUnmatchedVars [Env]
defEnv Env
outerEnv Env
localEnv LispVal
identifiers ([LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
ps [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ [LispVal
p]) Bool
partOfImproperPattern String
esym
flagUnmatchedVars [Env]
defEnv Env
outerEnv Env
localEnv LispVal
identifiers (Vector Array Int LispVal
p) Bool
partOfImproperPattern String
esym = do
  [Env]
-> Env
-> Env
-> LispVal
-> LispVal
-> Bool
-> String
-> IOThrowsError LispVal
flagUnmatchedVars [Env]
defEnv Env
outerEnv Env
localEnv LispVal
identifiers ([LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ Array Int LispVal -> [LispVal]
forall i e. Array i e -> [e]
elems Array Int LispVal
p) Bool
partOfImproperPattern String
esym
flagUnmatchedVars [Env]
_ Env
_ Env
_ LispVal
_ (List []) Bool
_ String
_ = 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
True 
flagUnmatchedVars [Env]
defEnv Env
outerEnv Env
localEnv LispVal
identifiers (List (LispVal
p : [LispVal]
ps)) Bool
partOfImproperPattern String
esym = do
  LispVal
_ <- [Env]
-> Env
-> Env
-> LispVal
-> LispVal
-> Bool
-> String
-> IOThrowsError LispVal
flagUnmatchedVars [Env]
defEnv Env
outerEnv Env
localEnv LispVal
identifiers LispVal
p Bool
partOfImproperPattern String
esym
  [Env]
-> Env
-> Env
-> LispVal
-> LispVal
-> Bool
-> String
-> IOThrowsError LispVal
flagUnmatchedVars [Env]
defEnv Env
outerEnv Env
localEnv LispVal
identifiers ([LispVal] -> LispVal
List [LispVal]
ps) Bool
partOfImproperPattern String
esym
flagUnmatchedVars [Env]
defEnv Env
outerEnv Env
localEnv LispVal
identifiers (Atom String
p) Bool
partOfImproperPattern String
esym =
  if String
p String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
esym
     then 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
True
     else [Env]
-> Env -> Env -> LispVal -> String -> Bool -> IOThrowsError LispVal
flagUnmatchedAtom [Env]
defEnv Env
outerEnv Env
localEnv LispVal
identifiers String
p Bool
partOfImproperPattern
flagUnmatchedVars [Env]
_ Env
_ Env
_ LispVal
_ LispVal
_ Bool
_ String
_ = 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
True 
flagUnmatchedAtom :: [Env] -> Env -> Env -> LispVal -> String -> Bool -> IOThrowsError LispVal 
flagUnmatchedAtom :: [Env]
-> Env -> Env -> LispVal -> String -> Bool -> IOThrowsError LispVal
flagUnmatchedAtom [Env]
defEnv Env
outerEnv Env
localEnv LispVal
identifiers String
p Bool
improperListFlag = do
  Bool
isDefined <- 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
isBound Env
localEnv String
p
  LispVal
isIdent <- LispVal -> LispVal -> IOThrowsError LispVal
findAtom (String -> LispVal
Atom String
p) LispVal
identifiers
  if Bool
isDefined
     
     then IOThrowsError LispVal
continueFlagging
     else case LispVal
isIdent of
             Bool Bool
True -> do
                           Bool
matches <- Env -> Env -> String -> ExceptT LispError IO Bool
identifierMatches ([Env] -> Env
forall a. [a] -> a
head [Env]
defEnv) Env
outerEnv String
p
                           if Bool -> Bool
not Bool
matches 
                             then 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
True
                             else do LispVal
_ <- Env -> String -> Bool -> IOThrowsError LispVal
flagUnmatchedVar Env
localEnv String
p Bool
improperListFlag
                                     IOThrowsError LispVal
continueFlagging
             LispVal
_ -> do LispVal
_ <- Env -> String -> Bool -> IOThrowsError LispVal
flagUnmatchedVar Env
localEnv String
p Bool
improperListFlag 
                     IOThrowsError LispVal
continueFlagging
 where continueFlagging :: IOThrowsError LispVal
continueFlagging = 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
True 
flagUnmatchedVar :: Env -> String -> Bool -> IOThrowsError LispVal
flagUnmatchedVar :: Env -> String -> Bool -> IOThrowsError LispVal
flagUnmatchedVar Env
localEnv String
var Bool
improperListFlag = do
  LispVal
_ <- Env -> String -> LispVal -> IOThrowsError LispVal
defineVar Env
localEnv String
var (LispVal -> IOThrowsError LispVal)
-> LispVal -> IOThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ String -> LispVal
Nil String
"" 
  Env -> Char -> String -> LispVal -> IOThrowsError LispVal
defineNamespacedVar Env
localEnv 
                      Char
'_' 
                      String
var (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
$ Bool
improperListFlag
flagDottedLists :: [(Bool, Bool)] -> (Bool, Bool) -> Int -> [(Bool, Bool)]
flagDottedLists :: [(Bool, Bool)] -> (Bool, Bool) -> Int -> [(Bool, Bool)]
flagDottedLists [(Bool, Bool)]
listFlags (Bool, Bool)
status Int
lengthOfEllipsisIndex
 | [(Bool, Bool)] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [(Bool, Bool)]
listFlags Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
lengthOfEllipsisIndex = [(Bool, Bool)]
listFlags [(Bool, Bool)] -> [(Bool, Bool)] -> [(Bool, Bool)]
forall a. [a] -> [a] -> [a]
++ [(Bool, Bool)
status]
   
 | Bool
otherwise = [(Bool, Bool)]
listFlags [(Bool, Bool)] -> [(Bool, Bool)] -> [(Bool, Bool)]
forall a. [a] -> [a] -> [a]
++ (Int -> (Bool, Bool) -> [(Bool, Bool)]
forall a. Int -> a -> [a]
replicate (Int
lengthOfEllipsisIndex Int -> Int -> Int
forall a. Num a => a -> a -> a
- ([(Bool, Bool)] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [(Bool, Bool)]
listFlags)) (Bool
False, Bool
False)) [(Bool, Bool)] -> [(Bool, Bool)] -> [(Bool, Bool)]
forall a. [a] -> [a] -> [a]
++ [(Bool, Bool)
status]
getListFlags :: [Int] -> [(Bool, Bool)] -> (Bool, Bool)
getListFlags :: [Int] -> [(Bool, Bool)] -> (Bool, Bool)
getListFlags [Int]
elIndices [(Bool, Bool)]
flags 
  | Bool -> Bool
not ([Int] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Int]
elIndices) Bool -> Bool -> Bool
&& [(Bool, Bool)] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [(Bool, Bool)]
flags Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= [Int] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
elIndices = [(Bool, Bool)]
flags [(Bool, Bool)] -> Int -> (Bool, Bool)
forall a. [a] -> Int -> a
!! (([Int] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
elIndices) Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
  | Bool
otherwise = (Bool
False, Bool
False)
checkLocal :: [Env]          
           -> Env            
           -> Env            
           -> Env            
           -> Env            
           -> LispVal        
           -> Int            
           -> [Int]          
           -> LispVal        
           -> LispVal        
           -> [(Bool, Bool)] 
           -> String         
           -> IOThrowsError LispVal
checkLocal :: [Env]
-> Env
-> Env
-> Env
-> Env
-> LispVal
-> Int
-> [Int]
-> LispVal
-> LispVal
-> [(Bool, Bool)]
-> String
-> IOThrowsError LispVal
checkLocal [Env]
_ Env
_ Env
_ Env
_ Env
_ LispVal
_ Int
_ [Int]
_ (Bool Bool
pattern) (Bool Bool
input) [(Bool, Bool)]
_ String
_ = 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
$ Bool
pattern Bool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Bool
input
checkLocal [Env]
_ Env
_ Env
_ Env
_ Env
_ LispVal
_ Int
_ [Int]
_ (Number Integer
pattern) (Number Integer
input) [(Bool, Bool)]
_ String
_ = 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
$ Integer
pattern Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
input
checkLocal [Env]
_ Env
_ Env
_ Env
_ Env
_ LispVal
_ Int
_ [Int]
_ (Float Double
pattern) (Float Double
input) [(Bool, Bool)]
_ String
_ = 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
$ Double
pattern Double -> Double -> Bool
forall a. Eq a => a -> a -> Bool
== Double
input
checkLocal [Env]
_ Env
_ Env
_ Env
_ Env
_ LispVal
_ Int
_ [Int]
_ (String String
pattern) (String String
input) [(Bool, Bool)]
_ String
_ = 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
$ String
pattern String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
input
checkLocal [Env]
_ Env
_ Env
_ Env
_ Env
_ LispVal
_ Int
_ [Int]
_ (Char Char
pattern) (Char Char
input) [(Bool, Bool)]
_ String
_ = 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
$ Char
pattern Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
input
checkLocal [Env]
defEnv Env
outerEnv Env
_ Env
localEnv Env
renameEnv LispVal
identifiers Int
ellipsisLevel [Int]
ellipsisIndex (Atom String
pattern) LispVal
input [(Bool, Bool)]
listFlags String
_ = do
  
  
  
  
  
  
  
  
  
  Bool
isRenamed <- 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
renameEnv String
pattern
  Bool
doesIdentMatch <- Env -> Env -> String -> ExceptT LispError IO Bool
identifierMatches ([Env] -> Env
forall a. [a] -> a
head [Env]
defEnv) Env
outerEnv String
pattern
  Int
match <- Bool -> Bool -> IOThrowsError Int
haveMatch Bool
isRenamed Bool
doesIdentMatch
  if Int
match Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 
     then 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
False
     else if Int
ellipsisLevel Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0
             
             then do Bool
isDefined <- 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
isBound Env
localEnv String
pattern
                     if Int
match Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 
                        then Bool -> Int -> [Int] -> String -> LispVal -> IOThrowsError LispVal
forall p.
Bool -> p -> [Int] -> String -> LispVal -> IOThrowsError LispVal
addPatternVar Bool
isDefined Int
ellipsisLevel [Int]
ellipsisIndex String
pattern (LispVal -> IOThrowsError LispVal)
-> LispVal -> IOThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ String -> LispVal
Atom String
pattern
                        else Bool -> Int -> [Int] -> String -> LispVal -> IOThrowsError LispVal
forall p.
Bool -> p -> [Int] -> String -> LispVal -> IOThrowsError LispVal
addPatternVar Bool
isDefined Int
ellipsisLevel [Int]
ellipsisIndex String
pattern LispVal
input
             
             else do
                  LispVal
_ <- Env -> String -> LispVal -> IOThrowsError LispVal
defineVar Env
localEnv String
pattern LispVal
input
                  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
True
    where
      haveMatch :: Bool -> Bool -> IOThrowsError Int
      haveMatch :: Bool -> Bool -> IOThrowsError Int
haveMatch Bool
isRenamed Bool
doesIdentMatch = do
         LispVal
isIdent <- LispVal -> LispVal -> IOThrowsError LispVal
findAtom (String -> LispVal
Atom String
pattern) LispVal
identifiers
         case LispVal
isIdent of
            
            Bool Bool
True -> do
                case LispVal
input of
                    Atom String
inpt -> do
                        String
p' <- Env -> String -> IOThrowsError String
getOrigName Env
renameEnv String
pattern
                        String
i' <- Env -> String -> IOThrowsError String
getOrigName Env
renameEnv String
inpt
                        Bool
pl <- Env -> Env -> String -> ExceptT LispError IO Bool
isLexicallyDefined Env
outerEnv Env
renameEnv String
pattern
                        Bool
il <- Env -> Env -> String -> ExceptT LispError IO Bool
isLexicallyDefined Env
outerEnv Env
renameEnv String
inpt
                        if (((String
p' String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
i' Bool -> Bool -> Bool
&& Bool
doesIdentMatch) Bool -> Bool -> Bool
&& (Bool -> Bool
not Bool
isRenamed)) Bool -> Bool -> Bool
|| 
                            
                            (String
p' String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
i' Bool -> Bool -> Bool
&& (Bool -> Bool
not Bool
pl) Bool -> Bool -> Bool
&& (Bool -> Bool
not Bool
il)))
                           then Int -> IOThrowsError Int
forall (m :: * -> *) a. Monad m => a -> m a
return Int
1
                           else Int -> IOThrowsError Int
forall (m :: * -> *) a. Monad m => a -> m a
return Int
0
                    
                    LispVal
_ -> Int -> IOThrowsError Int
forall (m :: * -> *) a. Monad m => a -> m a
return Int
0
            
            LispVal
_ -> Int -> IOThrowsError Int
forall (m :: * -> *) a. Monad m => a -> m a
return Int
2
      
      
      
      
      
      
      
      addPatternVar :: Bool -> p -> [Int] -> String -> LispVal -> IOThrowsError LispVal
addPatternVar Bool
isDefined p
ellipLevel [Int]
ellipIndex String
pat LispVal
val
        | Bool
isDefined = do LispVal
v <- Env -> String -> IOThrowsError LispVal
getVar Env
localEnv String
pat
                         case LispVal
v of
                            Nil String
_ -> do
                              
                              
                              
                              
                              
                              
                              
                              
                              LispVal
_ <- p -> [Int] -> String -> LispVal -> IOThrowsError LispVal
forall p. p -> [Int] -> String -> LispVal -> IOThrowsError LispVal
initializePatternVar p
ellipLevel [Int]
ellipIndex String
pat LispVal
val
                              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
False
                            LispVal
_ -> do LispVal
_ <- Env -> String -> LispVal -> IOThrowsError LispVal
setVar Env
localEnv String
pat (LispVal -> [Int] -> LispVal -> LispVal
Matches.setData LispVal
v [Int]
ellipIndex LispVal
val)
                                    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
True
        | Bool
otherwise = do
            LispVal
_ <- p -> [Int] -> String -> LispVal -> IOThrowsError LispVal
forall p. p -> [Int] -> String -> LispVal -> IOThrowsError LispVal
initializePatternVar p
ellipLevel [Int]
ellipIndex String
pat LispVal
val
            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
True
      
      initializePatternVar :: p -> [Int] -> String -> LispVal -> IOThrowsError LispVal
initializePatternVar p
_ [Int]
ellipIndex String
pat LispVal
val = do
        let flags :: (Bool, Bool)
flags = [Int] -> [(Bool, Bool)] -> (Bool, Bool)
getListFlags [Int]
ellipIndex [(Bool, Bool)]
listFlags 
        LispVal
_ <- Env -> String -> LispVal -> IOThrowsError LispVal
defineVar Env
localEnv String
pat (LispVal -> [Int] -> LispVal -> LispVal
Matches.setData ([LispVal] -> LispVal
List []) [Int]
ellipIndex LispVal
val)
        LispVal
_ <- Env -> Char -> String -> LispVal -> IOThrowsError LispVal
defineNamespacedVar Env
localEnv Char
'p'  String
pat (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
$ (Bool, Bool) -> Bool
forall a b. (a, b) -> a
fst (Bool, Bool)
flags
        Env -> Char -> String -> LispVal -> IOThrowsError LispVal
defineNamespacedVar Env
localEnv Char
'i'  String
pat (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
$ (Bool, Bool) -> Bool
forall a b. (a, b) -> b
snd (Bool, Bool)
flags
checkLocal [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv LispVal
identifiers Int
ellipsisLevel [Int]
ellipsisIndex (Vector Array Int LispVal
p) (Vector Array Int LispVal
i) [(Bool, Bool)]
flags String
esym =
  
  
  
  [Env]
-> Env
-> Env
-> Env
-> Env
-> LispVal
-> LispVal
-> LispVal
-> Int
-> [Int]
-> [(Bool, Bool)]
-> String
-> IOThrowsError LispVal
loadLocal [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv LispVal
identifiers ([LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ Array Int LispVal -> [LispVal]
forall i e. Array i e -> [e]
elems Array Int LispVal
p) ([LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ Array Int LispVal -> [LispVal]
forall i e. Array i e -> [e]
elems Array Int LispVal
i) Int
ellipsisLevel [Int]
ellipsisIndex [(Bool, Bool)]
flags String
esym
checkLocal [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv LispVal
identifiers Int
ellipsisLevel [Int]
ellipsisIndex pattern :: LispVal
pattern@(DottedList [LispVal]
_ LispVal
_) input :: LispVal
input@(DottedList [LispVal]
_ LispVal
_) [(Bool, Bool)]
flags String
esym =
  [Env]
-> Env
-> Env
-> Env
-> Env
-> LispVal
-> LispVal
-> LispVal
-> Int
-> [Int]
-> [(Bool, Bool)]
-> String
-> IOThrowsError LispVal
loadLocal [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv LispVal
identifiers LispVal
pattern LispVal
input Int
ellipsisLevel [Int]
ellipsisIndex [(Bool, Bool)]
flags String
esym
checkLocal [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv LispVal
identifiers Int
ellipsisLevel [Int]
ellipsisIndex (DottedList [LispVal]
ps LispVal
p) input :: LispVal
input@(List (LispVal
_ : [LispVal]
_)) [(Bool, Bool)]
flags String
esym = do
  [Env]
-> Env
-> Env
-> Env
-> Env
-> LispVal
-> LispVal
-> LispVal
-> Int
-> [Int]
-> [(Bool, Bool)]
-> String
-> IOThrowsError LispVal
loadLocal [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv LispVal
identifiers 
                                  ([LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
ps [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ [LispVal
p, String -> LispVal
Atom String
esym])
                                  LispVal
input
                                   Int
ellipsisLevel 
                                   [Int]
ellipsisIndex
                                   ([(Bool, Bool)] -> (Bool, Bool) -> Int -> [(Bool, Bool)]
flagDottedLists [(Bool, Bool)]
flags (Bool
True, Bool
False) (Int -> [(Bool, Bool)]) -> Int -> [(Bool, Bool)]
forall a b. (a -> b) -> a -> b
$ ([Int] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
ellipsisIndex) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ ([LispVal] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([LispVal] -> Int) -> [LispVal] -> Int
forall a b. (a -> b) -> a -> b
$ (LispVal -> Bool) -> [LispVal] -> [LispVal]
forall a. (a -> Bool) -> [a] -> [a]
filter (String -> LispVal -> Bool
filterEsym String
esym) [LispVal]
ps)) 
                                   String
esym
checkLocal [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv LispVal
identifiers Int
ellipsisLevel [Int]
ellipsisIndex pattern :: LispVal
pattern@(List [LispVal]
_) input :: LispVal
input@(List [LispVal]
_) [(Bool, Bool)]
flags String
esym =
  [Env]
-> Env
-> Env
-> Env
-> Env
-> LispVal
-> LispVal
-> LispVal
-> Int
-> [Int]
-> [(Bool, Bool)]
-> String
-> IOThrowsError LispVal
loadLocal [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv LispVal
identifiers LispVal
pattern LispVal
input Int
ellipsisLevel [Int]
ellipsisIndex [(Bool, Bool)]
flags String
esym
checkLocal [Env]
_ Env
_ Env
_ Env
_ Env
_ LispVal
_ Int
_ [Int]
_ LispVal
_ LispVal
_ [(Bool, Bool)]
_ String
_ = 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
False
filterEsym :: String -> LispVal -> Bool
filterEsym :: String -> LispVal -> Bool
filterEsym String
esym (Atom String
a) = String
esym String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
a
filterEsym String
_ LispVal
_ = Bool
False
identifierMatches :: Env -> Env -> String -> IOThrowsError Bool
identifierMatches :: Env -> Env -> String -> ExceptT LispError IO Bool
identifierMatches Env
defEnv Env
useEnv String
ident = do
  Bool
atDef <- 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
ident
  Bool
atUse <- 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
useEnv String
ident
  Bool -> Bool -> ExceptT LispError IO Bool
matchIdent Bool
atDef Bool
atUse
 where
  matchIdent :: Bool -> Bool -> ExceptT LispError IO Bool
matchIdent Bool
False Bool
False = Bool -> ExceptT LispError IO Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True 
  matchIdent Bool
True Bool
True = do 
    LispVal
d <- Env -> String -> IOThrowsError LispVal
getVar Env
defEnv String
ident
    LispVal
u <- Env -> String -> IOThrowsError LispVal
getVar Env
useEnv String
ident
    Bool -> ExceptT LispError IO Bool
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> ExceptT LispError IO Bool)
-> Bool -> ExceptT LispError IO Bool
forall a b. (a -> b) -> a -> b
$ LispVal -> LispVal -> Bool
eqVal LispVal
d LispVal
u 
  matchIdent Bool
_ Bool
_ = Bool -> ExceptT LispError IO Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False 
expand :: 
     Env       
  -> Bool      
  -> LispVal   
  -> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal) 
  -> IOThrowsError LispVal 
expand :: Env
-> Bool
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
expand Env
env Bool
dim LispVal
code LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply = do
  Env
renameEnv <- IO Env -> ExceptT LispError IO Env
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Env -> ExceptT LispError IO Env)
-> IO Env -> ExceptT LispError IO Env
forall a b. (a -> b) -> a -> b
$ IO Env
nullEnv
  Env
cleanupEnv <- IO Env -> ExceptT LispError IO Env
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Env -> ExceptT LispError IO Env)
-> IO Env -> ExceptT LispError IO Env
forall a b. (a -> b) -> a -> b
$ IO Env
nullEnv
  
  LispVal
_ <- Env -> IOThrowsError LispVal
clearDivertedVars Env
env
  [Env]
-> Env
-> Env
-> Env
-> Env
-> Bool
-> Bool
-> Bool
-> LispVal
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
walkExpanded [Env
env] Env
env Env
env Env
renameEnv Env
cleanupEnv Bool
dim Bool
True Bool
False ([LispVal] -> LispVal
List []) LispVal
code LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply
walkExpanded :: [Env]
  -> Env 
  -> Env 
  -> Env 
  -> Env 
  -> Bool 
  -> Bool 
  -> Bool 
  -> LispVal 
  -> LispVal 
  -> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal) 
  -> IOThrowsError LispVal
walkExpanded :: [Env]
-> Env
-> Env
-> Env
-> Env
-> Bool
-> Bool
-> Bool
-> LispVal
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
walkExpanded [Env]
defEnv Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv Bool
dim Bool
_ Bool
isQuoted (List [LispVal]
result) (List (List [LispVal]
l : [LispVal]
ls)) LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply = do
  LispVal
lst <- [Env]
-> Env
-> Env
-> Env
-> Env
-> Bool
-> Bool
-> Bool
-> LispVal
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
walkExpanded [Env]
defEnv Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv Bool
dim Bool
True Bool
isQuoted ([LispVal] -> LispVal
List []) ([LispVal] -> LispVal
List [LispVal]
l) LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply
  [Env]
-> Env
-> Env
-> Env
-> Env
-> Bool
-> Bool
-> Bool
-> LispVal
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
walkExpanded [Env]
defEnv Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv Bool
dim Bool
False Bool
isQuoted ([LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
result [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ [LispVal
lst]) ([LispVal] -> LispVal
List [LispVal]
ls) LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply
walkExpanded [Env]
defEnv Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv Bool
dim Bool
_ Bool
isQuoted (List [LispVal]
result) (List ((Vector Array Int LispVal
v) : [LispVal]
vs)) LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply = do
  List [LispVal]
lst <- [Env]
-> Env
-> Env
-> Env
-> Env
-> Bool
-> Bool
-> Bool
-> LispVal
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
walkExpanded [Env]
defEnv Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv Bool
dim Bool
False Bool
isQuoted ([LispVal] -> LispVal
List []) ([LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ Array Int LispVal -> [LispVal]
forall i e. Array i e -> [e]
elems Array Int LispVal
v) LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply
  [Env]
-> Env
-> Env
-> Env
-> Env
-> Bool
-> Bool
-> Bool
-> LispVal
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
walkExpanded [Env]
defEnv Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv Bool
dim Bool
False Bool
isQuoted ([LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
result [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ [[LispVal] -> LispVal
asVector [LispVal]
lst]) ([LispVal] -> LispVal
List [LispVal]
vs) LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply
walkExpanded [Env]
defEnv Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv Bool
dim Bool
_ Bool
isQuoted (List [LispVal]
result) (List ((DottedList [LispVal]
ds LispVal
d) : [LispVal]
ts)) LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply = do
  List [LispVal]
ls <- [Env]
-> Env
-> Env
-> Env
-> Env
-> Bool
-> Bool
-> Bool
-> LispVal
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
walkExpanded [Env]
defEnv Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv Bool
dim Bool
False Bool
isQuoted ([LispVal] -> LispVal
List []) ([LispVal] -> LispVal
List [LispVal]
ds) LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply
  LispVal
l <- [Env]
-> Env
-> Env
-> Env
-> Env
-> Bool
-> Bool
-> Bool
-> LispVal
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
walkExpanded [Env]
defEnv Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv Bool
dim Bool
False Bool
isQuoted ([LispVal] -> LispVal
List []) LispVal
d LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply
  [Env]
-> Env
-> Env
-> Env
-> Env
-> Bool
-> Bool
-> Bool
-> LispVal
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
walkExpanded [Env]
defEnv Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv Bool
dim Bool
False Bool
isQuoted ([LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
result [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ [[LispVal] -> LispVal -> LispVal
DottedList [LispVal]
ls LispVal
l]) ([LispVal] -> LispVal
List [LispVal]
ts) LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply
walkExpanded [Env]
defEnv Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv Bool
dim Bool
startOfList Bool
inputIsQuoted (List [LispVal]
result) (List (Atom String
aa : [LispVal]
ts)) LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply = do
 Atom String
a <- Env -> LispVal -> IOThrowsError LispVal
expandAtom Env
renameEnv (String -> LispVal
Atom String
aa)
 Maybe LispVal
maybeMacro <- [Env] -> Env -> String -> IOThrowsError (Maybe LispVal)
findBoundMacro [Env]
defEnv Env
useEnv String
a
 
 
 let isQuoted :: Bool
isQuoted = Bool
inputIsQuoted Bool -> Bool -> Bool
|| (String
a String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"quote")
 case Maybe LispVal
maybeMacro of
   Just LispVal
_ -> [Env]
-> Env
-> Env
-> Env
-> Env
-> Bool
-> Bool
-> Bool
-> LispVal
-> String
-> [LispVal]
-> Bool
-> Maybe LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
walkExpandedAtom [Env]
defEnv Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv 
                              Bool
dim Bool
startOfList Bool
inputIsQuoted ([LispVal] -> LispVal
List [LispVal]
result) 
                              String
a [LispVal]
ts Bool
isQuoted Maybe LispVal
maybeMacro LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply
   Maybe LispVal
_ -> do
    
    
    if  (String
a String -> [String] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` 
           [ String
aa 
           
           
           
           , String
"if"
           , String
"let-syntax" 
           , String
"letrec-syntax" 
           , String
"define-syntax" 
           , String
"define"  
           , String
"set!"
           , String
"lambda"
           , String
"quote"
           , String
"expand"
           , String
"string-set!"
           , String
"set-car!"
           , String
"set-cdr!"
           , String
"vector-set!"
           , String
"hash-table-set!"
           , String
"hash-table-delete!"])
       then [Env]
-> Env
-> Env
-> Env
-> Env
-> Bool
-> Bool
-> Bool
-> LispVal
-> String
-> [LispVal]
-> Bool
-> Maybe LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
walkExpandedAtom [Env]
defEnv Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv 
                             Bool
dim Bool
startOfList Bool
inputIsQuoted ([LispVal] -> LispVal
List [LispVal]
result) String
a [LispVal]
ts Bool
isQuoted Maybe LispVal
maybeMacro LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply
       else [Env]
-> Env
-> Env
-> Env
-> Env
-> Bool
-> Bool
-> Bool
-> LispVal
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
walkExpanded [Env]
defEnv Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv 
                         Bool
dim Bool
startOfList Bool
inputIsQuoted ([LispVal] -> LispVal
List [LispVal]
result) ([LispVal] -> LispVal
List (String -> LispVal
Atom String
a LispVal -> [LispVal] -> [LispVal]
forall a. a -> [a] -> [a]
: [LispVal]
ts)) LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply
walkExpanded [Env]
defEnv Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv Bool
dim Bool
_ Bool
isQuoted (List [LispVal]
result) (List (LispVal
t : [LispVal]
ts)) LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply = do
  [Env]
-> Env
-> Env
-> Env
-> Env
-> Bool
-> Bool
-> Bool
-> LispVal
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
walkExpanded [Env]
defEnv Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv Bool
dim Bool
False Bool
isQuoted ([LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
result [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ [LispVal
t]) ([LispVal] -> LispVal
List [LispVal]
ts) LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply
walkExpanded [Env]
_ Env
_ Env
_ Env
_ Env
_ Bool
_ Bool
_ Bool
_ result :: LispVal
result@(List [LispVal]
_) (List []) LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
_ = LispVal -> IOThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return LispVal
result
walkExpanded [Env]
_ Env
_ Env
_ Env
renameEnv Env
_ Bool
_ Bool
_ Bool
_ LispVal
_ (Atom String
a) LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
_ = Env -> LispVal -> IOThrowsError LispVal
expandAtom Env
renameEnv (String -> LispVal
Atom String
a)
walkExpanded [Env]
_ Env
_ Env
_ Env
_ Env
_ Bool
_ Bool
_ Bool
_ LispVal
_ LispVal
transform LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
_ = LispVal -> IOThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return LispVal
transform
walkExpandedAtom :: [Env]
  -> Env 
  -> Env 
  -> Env 
  -> Env 
  -> Bool 
  -> Bool 
  -> Bool 
  -> LispVal 
  -> String 
  -> [LispVal] 
  -> Bool 
  -> Maybe LispVal 
  -> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal) 
  -> IOThrowsError LispVal
walkExpandedAtom :: [Env]
-> Env
-> Env
-> Env
-> Env
-> Bool
-> Bool
-> Bool
-> LispVal
-> String
-> [LispVal]
-> Bool
-> Maybe LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
walkExpandedAtom [Env]
defEnv Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv Bool
dim Bool
True Bool
inputIsQuoted (List [LispVal]
_)
    String
"let-syntax" 
    (List [LispVal]
_bindings : [LispVal]
_body)
    Bool
False Maybe LispVal
_ LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply = do
        Env
bodyEnv <- IO Env -> ExceptT LispError IO Env
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Env -> ExceptT LispError IO Env)
-> IO Env -> ExceptT LispError IO Env
forall a b. (a -> b) -> a -> b
$ Env -> [((Char, String), LispVal)] -> IO Env
extendEnv Env
useEnv []
        Env
bodyRenameEnv <- IO Env -> ExceptT LispError IO Env
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Env -> ExceptT LispError IO Env)
-> IO Env -> ExceptT LispError IO Env
forall a b. (a -> b) -> a -> b
$ Env -> [((Char, String), LispVal)] -> IO Env
extendEnv Env
renameEnv []
        LispVal
_ <- Env
-> Env -> Maybe Env -> Bool -> [LispVal] -> IOThrowsError LispVal
loadMacros Env
useEnv Env
bodyEnv (Env -> Maybe Env
forall a. a -> Maybe a
Just Env
bodyRenameEnv) Bool
True [LispVal]
_bindings
        LispVal
expanded <- [Env]
-> Env
-> Env
-> Env
-> Env
-> Bool
-> Bool
-> Bool
-> LispVal
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
walkExpanded [Env]
defEnv Env
bodyEnv Env
divertEnv Env
bodyRenameEnv Env
cleanupEnv Bool
dim Bool
True Bool
inputIsQuoted ([LispVal] -> LispVal
List [String -> LispVal
Atom String
"lambda", [LispVal] -> LispVal
List []]) ([LispVal] -> LispVal
List [LispVal]
_body) LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply
        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
$ [LispVal] -> LispVal
List [LispVal
expanded]
walkExpandedAtom [Env]
_ Env
_ Env
_ Env
_ Env
_ Bool
_ Bool
True Bool
_ LispVal
_ String
"let-syntax" [LispVal]
ts Bool
False Maybe LispVal
_ LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
_ = do
  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 -> LispVal -> LispError
BadSpecialForm String
"Malformed let-syntax expression" (LispVal -> LispError) -> LispVal -> LispError
forall a b. (a -> b) -> a -> b
$ [LispVal] -> LispVal
List (String -> LispVal
Atom String
"let-syntax" LispVal -> [LispVal] -> [LispVal]
forall a. a -> [a] -> [a]
: [LispVal]
ts)
walkExpandedAtom [Env]
defEnv Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv Bool
dim Bool
True Bool
inputIsQuoted (List [LispVal]
_)
    String
"letrec-syntax" 
    (List [LispVal]
_bindings : [LispVal]
_body)
    Bool
False Maybe LispVal
_ LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply = do
        Env
bodyEnv <- IO Env -> ExceptT LispError IO Env
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Env -> ExceptT LispError IO Env)
-> IO Env -> ExceptT LispError IO Env
forall a b. (a -> b) -> a -> b
$ Env -> [((Char, String), LispVal)] -> IO Env
extendEnv Env
useEnv []
        Env
bodyRenameEnv <- IO Env -> ExceptT LispError IO Env
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Env -> ExceptT LispError IO Env)
-> IO Env -> ExceptT LispError IO Env
forall a b. (a -> b) -> a -> b
$ Env -> [((Char, String), LispVal)] -> IO Env
extendEnv Env
renameEnv []
        LispVal
_ <- Env
-> Env -> Maybe Env -> Bool -> [LispVal] -> IOThrowsError LispVal
loadMacros Env
bodyEnv Env
bodyEnv (Env -> Maybe Env
forall a. a -> Maybe a
Just Env
bodyRenameEnv) Bool
True [LispVal]
_bindings
        LispVal
expanded <- [Env]
-> Env
-> Env
-> Env
-> Env
-> Bool
-> Bool
-> Bool
-> LispVal
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
walkExpanded [Env]
defEnv Env
bodyEnv Env
divertEnv Env
bodyRenameEnv Env
cleanupEnv Bool
dim Bool
True Bool
inputIsQuoted ([LispVal] -> LispVal
List [String -> LispVal
Atom String
"lambda", [LispVal] -> LispVal
List []]) ([LispVal] -> LispVal
List [LispVal]
_body) LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply
        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
$ [LispVal] -> LispVal
List [LispVal
expanded]
walkExpandedAtom [Env]
_ Env
_ Env
_ Env
_ Env
_ Bool
_ Bool
True Bool
_ LispVal
_ String
"letrec-syntax" [LispVal]
ts Bool
False Maybe LispVal
_ LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
_ = do
  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 -> LispVal -> LispError
BadSpecialForm String
"Malformed letrec-syntax expression" (LispVal -> LispError) -> LispVal -> LispError
forall a b. (a -> b) -> a -> b
$ [LispVal] -> LispVal
List (String -> LispVal
Atom String
"letrec-syntax" LispVal -> [LispVal] -> [LispVal]
forall a. a -> [a] -> [a]
: [LispVal]
ts)
walkExpandedAtom [Env]
_ Env
useEnv Env
_ Env
renameEnv Env
_ Bool
_ Bool
True Bool
_ (List [LispVal]
_)
    String
"define-syntax" 
    ([Atom String
keyword, (List (Atom String
"syntax-rules" : Atom String
ellipsis : (List [LispVal]
identifiers : [LispVal]
rules)))])
    Bool
False Maybe LispVal
_ LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
_ = do
        
        Env
renameEnvClosure <- IO Env -> ExceptT LispError IO Env
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Env -> ExceptT LispError IO Env)
-> IO Env -> ExceptT LispError IO Env
forall a b. (a -> b) -> a -> b
$ Env -> IO Env
copyEnv Env
renameEnv
        LispVal
_ <- Env -> Char -> String -> LispVal -> IOThrowsError LispVal
defineNamespacedVar Env
useEnv Char
macroNamespace String
keyword (LispVal -> IOThrowsError LispVal)
-> LispVal -> IOThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Maybe Env
-> Maybe Env -> Bool -> String -> [LispVal] -> [LispVal] -> LispVal
Syntax (Env -> Maybe Env
forall a. a -> Maybe a
Just Env
useEnv) (Env -> Maybe Env
forall a. a -> Maybe a
Just Env
renameEnvClosure) Bool
True String
ellipsis [LispVal]
identifiers [LispVal]
rules
        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
Nil String
"" 
walkExpandedAtom [Env]
_ Env
useEnv Env
_ Env
renameEnv Env
_ Bool
_ Bool
True Bool
_ (List [LispVal]
_)
    String
"define-syntax" 
    ([Atom String
keyword, (List (Atom String
"syntax-rules" : (List [LispVal]
identifiers : [LispVal]
rules)))])
    Bool
False Maybe LispVal
_ LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
_ = do
        
        Env
renameEnvClosure <- IO Env -> ExceptT LispError IO Env
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Env -> ExceptT LispError IO Env)
-> IO Env -> ExceptT LispError IO Env
forall a b. (a -> b) -> a -> b
$ Env -> IO Env
copyEnv Env
renameEnv
        LispVal
_ <- Env -> Char -> String -> LispVal -> IOThrowsError LispVal
defineNamespacedVar Env
useEnv Char
macroNamespace String
keyword (LispVal -> IOThrowsError LispVal)
-> LispVal -> IOThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ Maybe Env
-> Maybe Env -> Bool -> String -> [LispVal] -> [LispVal] -> LispVal
Syntax (Env -> Maybe Env
forall a. a -> Maybe a
Just Env
useEnv) (Env -> Maybe Env
forall a. a -> Maybe a
Just Env
renameEnvClosure) Bool
True String
"..." [LispVal]
identifiers [LispVal]
rules
        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
Nil String
"" 
walkExpandedAtom [Env]
_ Env
useEnv Env
_ Env
_ Env
_ Bool
_ Bool
True Bool
_ (List [LispVal]
_)
    String
"define-syntax" 
    ([Atom String
keyword, 
       (List [Atom String
"er-macro-transformer",  
             (List (Atom String
"lambda" : List [LispVal]
fparams : [LispVal]
fbody))])])
    Bool
False Maybe LispVal
_ LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
_ = do
        LispVal
f <- Env -> [LispVal] -> [LispVal] -> IOThrowsError LispVal
forall (m :: * -> *).
Monad m =>
Env -> [LispVal] -> [LispVal] -> m LispVal
makeNormalFunc Env
useEnv [LispVal]
fparams [LispVal]
fbody 
        LispVal
_ <- Env -> Char -> String -> LispVal -> IOThrowsError LispVal
defineNamespacedVar Env
useEnv Char
macroNamespace String
keyword (LispVal -> IOThrowsError LispVal)
-> LispVal -> IOThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ LispVal -> LispVal
SyntaxExplicitRenaming LispVal
f
        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
Nil String
"" 
walkExpandedAtom [Env]
_ Env
_ Env
_ Env
_ Env
_ Bool
_ Bool
True Bool
_ LispVal
_ String
"define-syntax" [LispVal]
ts Bool
False Maybe LispVal
_ LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
_ = do
  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 -> LispVal -> LispError
BadSpecialForm String
"Malformed define-syntax expression" (LispVal -> LispError) -> LispVal -> LispError
forall a b. (a -> b) -> a -> b
$ [LispVal] -> LispVal
List (String -> LispVal
Atom String
"define-syntax" LispVal -> [LispVal] -> [LispVal]
forall a. a -> [a] -> [a]
: [LispVal]
ts)
walkExpandedAtom [Env]
defEnv Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv Bool
dim Bool
True Bool
_ (List [LispVal]
_)
    String
"define" 
    [Atom String
var, LispVal
val]
    Bool
False Maybe LispVal
_ LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply = do
          LispVal
_ <- Env -> String -> LispVal -> IOThrowsError LispVal
defineVar Env
renameEnv String
var (LispVal -> IOThrowsError LispVal)
-> LispVal -> IOThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ String -> LispVal
Atom String
var
          IOThrowsError LispVal
walk
 where walk :: IOThrowsError LispVal
walk = [Env]
-> Env
-> Env
-> Env
-> Env
-> Bool
-> Bool
-> Bool
-> LispVal
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
walkExpanded [Env]
defEnv Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv Bool
dim Bool
False Bool
False ([LispVal] -> LispVal
List [String -> LispVal
Atom String
"define", String -> LispVal
Atom String
var]) ([LispVal] -> LispVal
List [LispVal
val]) LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply
walkExpandedAtom [Env]
defEnv Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv Bool
dim Bool
True Bool
_ (List [LispVal]
result) a :: String
a@String
"define" [LispVal]
ts Bool
False Maybe LispVal
_ LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply = do
    
    [Env]
-> Env
-> Env
-> Env
-> Env
-> Bool
-> Bool
-> Bool
-> LispVal
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
walkExpanded [Env]
defEnv Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv Bool
dim Bool
False Bool
False ([LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
result [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ [String -> LispVal
Atom String
a]) ([LispVal] -> LispVal
List [LispVal]
ts) LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply
walkExpandedAtom [Env]
defEnv Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv Bool
dim Bool
True Bool
_ (List [LispVal]
_)
    String
"set!" 
    [Atom String
var, LispVal
val]
    Bool
False Maybe LispVal
_ LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply = do
      Bool
isLexicalDef <- 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
useEnv String
var
      Bool
isAlreadyRenamed <- 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
renameEnv String
var
      case (Bool
isLexicalDef, Bool
isAlreadyRenamed) of
        
        
        
        (Bool
True, Bool
False) -> do
           LispVal
_ <- Env -> String -> LispVal -> IOThrowsError LispVal
defineVar Env
renameEnv String
var (LispVal -> IOThrowsError LispVal)
-> LispVal -> IOThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ String -> LispVal
Atom String
var
           IOThrowsError LispVal
walk
        (Bool, Bool)
_ -> IOThrowsError LispVal
walk
  where
    walk :: IOThrowsError LispVal
walk = [Env]
-> Env
-> Env
-> Env
-> Env
-> Bool
-> Bool
-> Bool
-> LispVal
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
walkExpanded [Env]
defEnv Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv Bool
dim Bool
False Bool
False ([LispVal] -> LispVal
List [String -> LispVal
Atom String
"set!"]) ([LispVal] -> LispVal
List [String -> LispVal
Atom String
var, LispVal
val]) LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply
walkExpandedAtom [Env]
defEnv Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv Bool
dim Bool
True Bool
_ (List [LispVal]
result) a :: String
a@String
"set!" [LispVal]
ts Bool
False Maybe LispVal
_ LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply = do
    
    [Env]
-> Env
-> Env
-> Env
-> Env
-> Bool
-> Bool
-> Bool
-> LispVal
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
walkExpanded [Env]
defEnv Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv Bool
dim Bool
False Bool
False ([LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
result [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ [String -> LispVal
Atom String
a]) ([LispVal] -> LispVal
List [LispVal]
ts) LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply
walkExpandedAtom [Env]
defEnv Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv Bool
dim Bool
True Bool
_ (List [LispVal]
_)
    String
"lambda" 
    (List [LispVal]
vars : [LispVal]
fbody)
    Bool
False Maybe LispVal
_ LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply = do
    
    Env
env <- IO Env -> ExceptT LispError IO Env
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Env -> ExceptT LispError IO Env)
-> IO Env -> ExceptT LispError IO Env
forall a b. (a -> b) -> a -> b
$ Env -> [((Char, String), LispVal)] -> IO Env
extendEnv Env
renameEnv []
    LispVal
renamedVars <- Env -> Env -> [LispVal] -> [LispVal] -> IOThrowsError LispVal
markBoundIdentifiers Env
env Env
cleanupEnv [LispVal]
vars []
    [Env]
-> Env
-> Env
-> Env
-> Env
-> Bool
-> Bool
-> Bool
-> LispVal
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
walkExpanded [Env]
defEnv Env
useEnv Env
divertEnv Env
env Env
cleanupEnv Bool
dim Bool
True Bool
False ([LispVal] -> LispVal
List [String -> LispVal
Atom String
"lambda", LispVal
renamedVars]) ([LispVal] -> LispVal
List [LispVal]
fbody) LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply
walkExpandedAtom [Env]
defEnv Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv Bool
dim Bool
True Bool
_ (List [LispVal]
result) a :: String
a@String
"lambda" [LispVal]
ts Bool
False Maybe LispVal
_ LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply = do
    
    [Env]
-> Env
-> Env
-> Env
-> Env
-> Bool
-> Bool
-> Bool
-> LispVal
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
walkExpanded [Env]
defEnv Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv Bool
dim Bool
False Bool
False ([LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
result [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ [String -> LispVal
Atom String
a]) ([LispVal] -> LispVal
List [LispVal]
ts) LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply
walkExpandedAtom [Env]
defEnvs Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv Bool
dim Bool
True Bool
_ (List [LispVal]
result)
    String
a
    [LispVal]
ts 
    Bool
False (Just LispVal
syn) LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply = do
    case LispVal
syn of
      Syntax Maybe Env
_ (Just Env
renameClosure) Bool
definedInMacro String
ellipsis [LispVal]
identifiers [LispVal]
rules -> do 
         
         
         
         
         
         
         
         
         
         
         List [LispVal]
lexpanded <- [Env]
-> Env
-> Env
-> Env
-> Env
-> Bool
-> Bool
-> LispVal
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
cleanExpanded [Env]
defEnvs Env
useEnv Env
divertEnv Env
renameEnv Env
renameEnv Bool
True Bool
False ([LispVal] -> LispVal
List []) ([LispVal] -> LispVal
List [LispVal]
ts) LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply
         [Env]
-> Env
-> Env
-> Env
-> Env
-> Bool
-> LispVal
-> [LispVal]
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> String
-> IOThrowsError LispVal
macroTransform [Env]
defEnvs Env
useEnv Env
divertEnv Env
renameClosure Env
cleanupEnv Bool
definedInMacro ([LispVal] -> LispVal
List [LispVal]
identifiers) [LispVal]
rules ([LispVal] -> LispVal
List (String -> LispVal
Atom String
a LispVal -> [LispVal] -> [LispVal]
forall a. a -> [a] -> [a]
: [LispVal]
lexpanded)) LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply String
ellipsis
      Syntax (Just Env
_defEnv) Maybe Env
_ Bool
definedInMacro String
ellipsis [LispVal]
identifiers [LispVal]
rules -> do 
        
        
        
        
        
        
        
        
        let defEnvs' :: [Env]
defEnvs' = if (Env -> [Env] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
elem Env
_defEnv [Env]
defEnvs)
                          then [Env]
defEnvs
                          else [Env]
defEnvs [Env] -> [Env] -> [Env]
forall a. [a] -> [a] -> [a]
++ [Env
_defEnv]
        [Env]
-> Env
-> Env
-> Env
-> Env
-> Bool
-> LispVal
-> [LispVal]
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> String
-> IOThrowsError LispVal
macroTransform [Env]
defEnvs' Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv 
                       Bool
definedInMacro ([LispVal] -> LispVal
List [LispVal]
identifiers) [LispVal]
rules 
                       ([LispVal] -> LispVal
List (String -> LispVal
Atom String
a LispVal -> [LispVal] -> [LispVal]
forall a. a -> [a] -> [a]
: [LispVal]
ts)) LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply String
ellipsis
      Syntax Maybe Env
Nothing Maybe Env
_ Bool
definedInMacro String
ellipsis [LispVal]
identifiers [LispVal]
rules -> do 
        
        
        
        
        
        
        [Env]
-> Env
-> Env
-> Env
-> Env
-> Bool
-> LispVal
-> [LispVal]
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> String
-> IOThrowsError LispVal
macroTransform [Env]
defEnvs Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv Bool
definedInMacro ([LispVal] -> LispVal
List [LispVal]
identifiers) [LispVal]
rules ([LispVal] -> LispVal
List (String -> LispVal
Atom String
a LispVal -> [LispVal] -> [LispVal]
forall a. a -> [a] -> [a]
: [LispVal]
ts)) LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply String
ellipsis
      SyntaxExplicitRenaming LispVal
transformer -> do
        Env
erRenameEnv <- IO Env -> ExceptT LispError IO Env
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Env -> ExceptT LispError IO Env)
-> IO Env -> ExceptT LispError IO Env
forall a b. (a -> b) -> a -> b
$ IO Env
nullEnv 
                                        
        LispVal
expanded <- Env
-> Env
-> Env
-> LispVal
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
explicitRenamingTransform 
                      Env
useEnv Env
erRenameEnv Env
renameEnv ([LispVal] -> LispVal
List (String -> LispVal
Atom String
a LispVal -> [LispVal] -> [LispVal]
forall a. a -> [a] -> [a]
: [LispVal]
ts)) LispVal
transformer LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply
        [Env]
-> Env
-> Env
-> Env
-> Env
-> Bool
-> Bool
-> Bool
-> LispVal
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
walkExpanded [Env]
defEnvs Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv 
          Bool
dim Bool
False Bool
False ([LispVal] -> LispVal
List [LispVal]
result) LispVal
expanded LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply
      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
Default String
"Unexpected error processing a macro in walkExpandedAtom"
walkExpandedAtom [Env]
defEnv Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv Bool
dim Bool
_ Bool
_ (List [LispVal]
result)
    String
a
    [LispVal]
ts
    Bool
True Maybe LispVal
_ LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply = do
    
    List [LispVal]
cleaned <- [Env]
-> Env
-> Env
-> Env
-> Env
-> Bool
-> Bool
-> LispVal
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
cleanExpanded 
                      [Env]
defEnv Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv 
                      Bool
dim Bool
True
                      ([LispVal] -> LispVal
List []) ([LispVal] -> LispVal
List [LispVal]
ts)
                      LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply
    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
$ [LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
result [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ (String -> LispVal
Atom String
a LispVal -> [LispVal] -> [LispVal]
forall a. a -> [a] -> [a]
: [LispVal]
cleaned)
walkExpandedAtom [Env]
defEnv Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv Bool
dim Bool
_ Bool
_ (List [LispVal]
result)
    String
a [LispVal]
ts Bool
isQuoted Maybe LispVal
_ LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply = do
    [Env]
-> Env
-> Env
-> Env
-> Env
-> Bool
-> Bool
-> Bool
-> LispVal
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
walkExpanded [Env]
defEnv Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv 
                 Bool
dim Bool
False Bool
isQuoted 
                ([LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
result [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ [String -> LispVal
Atom String
a]) ([LispVal] -> LispVal
List [LispVal]
ts)
                 LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply
walkExpandedAtom [Env]
_ Env
_ Env
_ Env
_ Env
_ Bool
_ Bool
_ Bool
_ LispVal
_ String
_ [LispVal]
_ Bool
_ Maybe 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
Default String
"Unexpected error in walkExpandedAtom"
markBoundIdentifiers :: Env -> Env -> [LispVal] -> [LispVal] -> IOThrowsError LispVal
markBoundIdentifiers :: Env -> Env -> [LispVal] -> [LispVal] -> IOThrowsError LispVal
markBoundIdentifiers Env
env Env
cleanupEnv (Atom String
v : [LispVal]
vs) [LispVal]
renamedVars = do
  Atom String
renamed <- String -> IOThrowsError LispVal
_gensym String
v
  LispVal
_ <- Env -> String -> LispVal -> IOThrowsError LispVal
defineVar Env
env String
v (LispVal -> IOThrowsError LispVal)
-> LispVal -> IOThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ String -> LispVal
Atom String
renamed
  LispVal
_ <- Env -> String -> LispVal -> IOThrowsError LispVal
defineVar Env
cleanupEnv String
renamed (LispVal -> IOThrowsError LispVal)
-> LispVal -> IOThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ String -> LispVal
Atom String
v
  Env -> Env -> [LispVal] -> [LispVal] -> IOThrowsError LispVal
markBoundIdentifiers Env
env Env
cleanupEnv [LispVal]
vs ([LispVal] -> IOThrowsError LispVal)
-> [LispVal] -> IOThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
renamedVars [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ [String -> LispVal
Atom String
renamed]
markBoundIdentifiers Env
env Env
cleanupEnv (LispVal
_: [LispVal]
vs) [LispVal]
renamedVars = Env -> Env -> [LispVal] -> [LispVal] -> IOThrowsError LispVal
markBoundIdentifiers Env
env Env
cleanupEnv [LispVal]
vs [LispVal]
renamedVars
markBoundIdentifiers Env
_ Env
_ [] [LispVal]
renamedVars = 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
$ [LispVal] -> LispVal
List [LispVal]
renamedVars
_expandAtom :: Bool -> Env -> LispVal -> IOThrowsError LispVal
_expandAtom :: Bool -> Env -> LispVal -> IOThrowsError LispVal
_expandAtom Bool
isRec Env
renameEnv (Atom String
a) = do
  Maybe LispVal
isDefined <- Env -> String -> IOThrowsError (Maybe LispVal)
getVar' Env
renameEnv String
a
  case Maybe LispVal
isDefined of
    Just LispVal
expanded -> do
       if Bool
isRec then Bool -> Env -> LispVal -> IOThrowsError LispVal
_expandAtom Bool
isRec Env
renameEnv LispVal
expanded
                else LispVal -> IOThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return LispVal
expanded
    Maybe LispVal
Nothing -> 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 
_expandAtom Bool
_ Env
_ LispVal
a = LispVal -> IOThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return LispVal
a
recExpandAtom :: Env -> LispVal -> IOThrowsError LispVal
recExpandAtom :: Env -> LispVal -> IOThrowsError LispVal
recExpandAtom = Bool -> Env -> LispVal -> IOThrowsError LispVal
_expandAtom Bool
True
expandAtom :: Env -> LispVal -> IOThrowsError LispVal
expandAtom :: Env -> LispVal -> IOThrowsError LispVal
expandAtom = Bool -> Env -> LispVal -> IOThrowsError LispVal
_expandAtom Bool
False
cleanExpanded :: 
     [Env]
  -> Env 
  -> Env 
  -> Env 
  -> Env 
  -> Bool 
  -> Bool 
  -> LispVal 
  -> LispVal 
  -> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal) 
  -> IOThrowsError LispVal
cleanExpanded :: [Env]
-> Env
-> Env
-> Env
-> Env
-> Bool
-> Bool
-> LispVal
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
cleanExpanded [Env]
defEnv Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv Bool
dim Bool
_ (List [LispVal]
result) (List (List [LispVal]
l : [LispVal]
ls)) LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply = do
  LispVal
lst <- [Env]
-> Env
-> Env
-> Env
-> Env
-> Bool
-> Bool
-> LispVal
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
cleanExpanded [Env]
defEnv Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv Bool
dim Bool
True ([LispVal] -> LispVal
List []) ([LispVal] -> LispVal
List [LispVal]
l) LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply
  [Env]
-> Env
-> Env
-> Env
-> Env
-> Bool
-> Bool
-> LispVal
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
cleanExpanded [Env]
defEnv Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv Bool
dim Bool
False ([LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
result [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ [LispVal
lst]) ([LispVal] -> LispVal
List [LispVal]
ls) LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply
cleanExpanded [Env]
defEnv Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv Bool
dim Bool
_ (List [LispVal]
result) (List ((Vector Array Int LispVal
v) : [LispVal]
vs)) LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply = do
  List [LispVal]
lst <- [Env]
-> Env
-> Env
-> Env
-> Env
-> Bool
-> Bool
-> LispVal
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
cleanExpanded [Env]
defEnv Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv Bool
dim Bool
True ([LispVal] -> LispVal
List []) ([LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ Array Int LispVal -> [LispVal]
forall i e. Array i e -> [e]
elems Array Int LispVal
v) LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply
  [Env]
-> Env
-> Env
-> Env
-> Env
-> Bool
-> Bool
-> LispVal
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
cleanExpanded [Env]
defEnv Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv Bool
dim Bool
False ([LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
result [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ [[LispVal] -> LispVal
asVector [LispVal]
lst]) ([LispVal] -> LispVal
List [LispVal]
vs) LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply
cleanExpanded [Env]
defEnv Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv Bool
dim Bool
_ (List [LispVal]
result) (List ((DottedList [LispVal]
ds LispVal
d) : [LispVal]
ts)) LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply = do
  List [LispVal]
ls <- [Env]
-> Env
-> Env
-> Env
-> Env
-> Bool
-> Bool
-> LispVal
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
cleanExpanded [Env]
defEnv Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv Bool
dim Bool
True ([LispVal] -> LispVal
List []) ([LispVal] -> LispVal
List [LispVal]
ds) LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply
  LispVal
l <- [Env]
-> Env
-> Env
-> Env
-> Env
-> Bool
-> Bool
-> LispVal
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
cleanExpanded [Env]
defEnv Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv Bool
dim Bool
True ([LispVal] -> LispVal
List []) LispVal
d LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply
  [Env]
-> Env
-> Env
-> Env
-> Env
-> Bool
-> Bool
-> LispVal
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
cleanExpanded [Env]
defEnv Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv Bool
dim Bool
False ([LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
result [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ [[LispVal] -> LispVal -> LispVal
DottedList [LispVal]
ls LispVal
l]) ([LispVal] -> LispVal
List [LispVal]
ts) LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply
cleanExpanded [Env]
defEnv Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv Bool
dim Bool
_ (List [LispVal]
result) (List (Atom String
a : [LispVal]
ts)) LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply = do
  LispVal
expanded <- Env -> LispVal -> IOThrowsError LispVal
recExpandAtom Env
cleanupEnv (LispVal -> IOThrowsError LispVal)
-> LispVal -> IOThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ String -> LispVal
Atom String
a
  [Env]
-> Env
-> Env
-> Env
-> Env
-> Bool
-> Bool
-> LispVal
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
cleanExpanded [Env]
defEnv Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv Bool
dim Bool
False ([LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
result [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ [LispVal
expanded]) ([LispVal] -> LispVal
List [LispVal]
ts) LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply
cleanExpanded [Env]
defEnv Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv Bool
dim Bool
_ (List [LispVal]
result) (List (LispVal
t : [LispVal]
ts)) LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply = do
  [Env]
-> Env
-> Env
-> Env
-> Env
-> Bool
-> Bool
-> LispVal
-> LispVal
-> (LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal)
-> IOThrowsError LispVal
cleanExpanded [Env]
defEnv Env
useEnv Env
divertEnv Env
renameEnv Env
cleanupEnv Bool
dim Bool
False ([LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
result [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ [LispVal
t]) ([LispVal] -> LispVal
List [LispVal]
ts) LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
apply
cleanExpanded [Env]
_ Env
_ Env
_ Env
_ Env
_ Bool
_ Bool
_ result :: LispVal
result@(List [LispVal]
_) (List []) LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
_ = do
  LispVal -> IOThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return LispVal
result
cleanExpanded [Env]
_ Env
_ Env
_ Env
_ Env
_ Bool
_ Bool
_ LispVal
_ LispVal
transform LispVal -> LispVal -> [LispVal] -> IOThrowsError LispVal
_ = LispVal -> IOThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return LispVal
transform
transformRule :: [Env]      
              -> Env        
              -> Env        
              -> Env        
              -> Env        
              -> Env        
              -> Bool
              -> LispVal    
              -> String     
              -> Int        
              -> [Int]      
                            
              -> LispVal    
                            
              -> LispVal    
              -> IOThrowsError LispVal
transformRule :: [Env]
-> Env
-> Env
-> Env
-> Env
-> Env
-> Bool
-> LispVal
-> String
-> Int
-> [Int]
-> LispVal
-> LispVal
-> IOThrowsError LispVal
transformRule [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv Env
cleanupEnv Bool
dim LispVal
identifiers String
esym Int
ellipsisLevel [Int]
ellipsisIndex (List [LispVal]
result) transform :: LispVal
transform@(List (List [LispVal]
l : [LispVal]
ts)) = do
  let nextHasEllipsis :: Bool
nextHasEllipsis = LispVal -> String -> Bool
macroElementMatchesMany LispVal
transform String
esym
  let level :: Int
level = Bool -> Int -> Int
calcEllipsisLevel Bool
nextHasEllipsis Int
ellipsisLevel
  let idx :: [Int]
idx = Bool -> Int -> [Int] -> [Int]
calcEllipsisIndex Bool
nextHasEllipsis Int
level [Int]
ellipsisIndex
  if Bool
nextHasEllipsis
     then do
             LispVal
curT <- [Env]
-> Env
-> Env
-> Env
-> Env
-> Env
-> Bool
-> LispVal
-> String
-> Int
-> [Int]
-> LispVal
-> LispVal
-> IOThrowsError LispVal
transformRule [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv Env
cleanupEnv Bool
dim LispVal
identifiers String
esym Int
level [Int]
idx ([LispVal] -> LispVal
List []) ([LispVal] -> LispVal
List [LispVal]
l)
             case LispVal
curT of
               Nil String
_ -> 
                        [Env]
-> Env
-> Env
-> Env
-> Env
-> Env
-> Bool
-> LispVal
-> String
-> Int
-> [Int]
-> [LispVal]
-> [LispVal]
-> IOThrowsError LispVal
continueTransform [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv Env
cleanupEnv Bool
dim LispVal
identifiers 
                                          String
esym
                                          Int
ellipsisLevel 
                                          ([Int] -> [Int]
forall a. [a] -> [a]
init [Int]
ellipsisIndex) 
                                          [LispVal]
result ([LispVal] -> IOThrowsError LispVal)
-> [LispVal] -> IOThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal] -> [LispVal]
forall a. [a] -> [a]
tail [LispVal]
ts
               List [LispVal]
_ -> [Env]
-> Env
-> Env
-> Env
-> Env
-> Env
-> Bool
-> LispVal
-> String
-> Int
-> [Int]
-> LispVal
-> LispVal
-> IOThrowsError LispVal
transformRule [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv Env
cleanupEnv Bool
dim LispVal
identifiers 
                           String
esym
                           Int
ellipsisLevel 
                           [Int]
idx 
                           ([LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
result [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ [LispVal
curT]) LispVal
transform
               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
Default String
"Unexpected error"
     else do
             LispVal
lst <- [Env]
-> Env
-> Env
-> Env
-> Env
-> Env
-> Bool
-> LispVal
-> String
-> Int
-> [Int]
-> LispVal
-> LispVal
-> IOThrowsError LispVal
transformRule [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv Env
cleanupEnv Bool
dim LispVal
identifiers String
esym Int
ellipsisLevel [Int]
ellipsisIndex ([LispVal] -> LispVal
List []) ([LispVal] -> LispVal
List [LispVal]
l)
             case LispVal
lst of
                  List [LispVal]
_ -> [Env]
-> Env
-> Env
-> Env
-> Env
-> Env
-> Bool
-> LispVal
-> String
-> Int
-> [Int]
-> LispVal
-> LispVal
-> IOThrowsError LispVal
transformRule [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv Env
cleanupEnv Bool
dim LispVal
identifiers String
esym Int
ellipsisLevel [Int]
ellipsisIndex ([LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
result [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ [LispVal
lst]) ([LispVal] -> LispVal
List [LispVal]
ts)
                  Nil String
_ -> LispVal -> IOThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return LispVal
lst
                  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 -> LispVal -> LispError
BadSpecialForm String
"Macro transform error" (LispVal -> LispError) -> LispVal -> LispError
forall a b. (a -> b) -> a -> b
$ [LispVal] -> LispVal
List [LispVal
lst, ([LispVal] -> LispVal
List [LispVal]
l), Integer -> LispVal
Number (Integer -> LispVal) -> Integer -> LispVal
forall a b. (a -> b) -> a -> b
$ Int -> Integer
forall a. Integral a => a -> Integer
toInteger Int
ellipsisLevel]
transformRule [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv Env
cleanupEnv Bool
dim LispVal
identifiers String
esym Int
ellipsisLevel [Int]
ellipsisIndex (List [LispVal]
result) transform :: LispVal
transform@(List ((Vector Array Int LispVal
v) : [LispVal]
ts)) = do
  let nextHasEllipsis :: Bool
nextHasEllipsis = LispVal -> String -> Bool
macroElementMatchesMany LispVal
transform String
esym
  let level :: Int
level = Bool -> Int -> Int
calcEllipsisLevel Bool
nextHasEllipsis Int
ellipsisLevel
  let idx :: [Int]
idx = Bool -> Int -> [Int] -> [Int]
calcEllipsisIndex Bool
nextHasEllipsis Int
level [Int]
ellipsisIndex
  if Bool
nextHasEllipsis
     then do
             
             LispVal
curT <- [Env]
-> Env
-> Env
-> Env
-> Env
-> Env
-> Bool
-> LispVal
-> String
-> Int
-> [Int]
-> LispVal
-> LispVal
-> IOThrowsError LispVal
transformRule [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv Env
cleanupEnv Bool
dim LispVal
identifiers String
esym Int
level [Int]
idx ([LispVal] -> LispVal
List []) ([LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ Array Int LispVal -> [LispVal]
forall i e. Array i e -> [e]
elems Array Int LispVal
v)
             case LispVal
curT of
               Nil String
_ -> 
                        [Env]
-> Env
-> Env
-> Env
-> Env
-> Env
-> Bool
-> LispVal
-> String
-> Int
-> [Int]
-> [LispVal]
-> [LispVal]
-> IOThrowsError LispVal
continueTransform [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv Env
cleanupEnv Bool
dim LispVal
identifiers String
esym Int
ellipsisLevel ([Int] -> [Int]
forall a. [a] -> [a]
init [Int]
ellipsisIndex) [LispVal]
result ([LispVal] -> IOThrowsError LispVal)
-> [LispVal] -> IOThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal] -> [LispVal]
forall a. [a] -> [a]
tail [LispVal]
ts
               List [LispVal]
t -> [Env]
-> Env
-> Env
-> Env
-> Env
-> Env
-> Bool
-> LispVal
-> String
-> Int
-> [Int]
-> LispVal
-> LispVal
-> IOThrowsError LispVal
transformRule [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv Env
cleanupEnv Bool
dim LispVal
identifiers 
                           String
esym
                           Int
ellipsisLevel 
                           [Int]
idx 
                           ([LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
result [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ [[LispVal] -> LispVal
asVector [LispVal]
t]) LispVal
transform
               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
Default String
"Unexpected error in transformRule"
     else do LispVal
lst <- [Env]
-> Env
-> Env
-> Env
-> Env
-> Env
-> Bool
-> LispVal
-> String
-> Int
-> [Int]
-> LispVal
-> LispVal
-> IOThrowsError LispVal
transformRule [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv Env
cleanupEnv Bool
dim LispVal
identifiers String
esym Int
ellipsisLevel [Int]
ellipsisIndex ([LispVal] -> LispVal
List []) ([LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ Array Int LispVal -> [LispVal]
forall i e. Array i e -> [e]
elems Array Int LispVal
v)
             case LispVal
lst of
                  List [LispVal]
l -> [Env]
-> Env
-> Env
-> Env
-> Env
-> Env
-> Bool
-> LispVal
-> String
-> Int
-> [Int]
-> LispVal
-> LispVal
-> IOThrowsError LispVal
transformRule [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv Env
cleanupEnv Bool
dim LispVal
identifiers String
esym Int
ellipsisLevel [Int]
ellipsisIndex ([LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
result [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ [[LispVal] -> LispVal
asVector [LispVal]
l]) ([LispVal] -> LispVal
List [LispVal]
ts)
                  Nil String
_ -> LispVal -> IOThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return LispVal
lst
                  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 -> LispVal -> LispError
BadSpecialForm String
"transformRule: Macro transform error" (LispVal -> LispError) -> LispVal -> LispError
forall a b. (a -> b) -> a -> b
$ [LispVal] -> LispVal
List [LispVal
lst, ([LispVal] -> LispVal
List [Array Int LispVal -> LispVal
Vector Array Int LispVal
v]), Integer -> LispVal
Number (Integer -> LispVal) -> Integer -> LispVal
forall a b. (a -> b) -> a -> b
$ Int -> Integer
forall a. Integral a => a -> Integer
toInteger Int
ellipsisLevel]
transformRule [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv Env
cleanupEnv Bool
dim LispVal
identifiers String
esym Int
ellipsisLevel [Int]
ellipsisIndex (List [LispVal]
result) transform :: LispVal
transform@(List (dl :: LispVal
dl@(DottedList [LispVal]
_ LispVal
_) : [LispVal]
ts)) = do
  let nextHasEllipsis :: Bool
nextHasEllipsis = LispVal -> String -> Bool
macroElementMatchesMany LispVal
transform String
esym
  let level :: Int
level = Bool -> Int -> Int
calcEllipsisLevel Bool
nextHasEllipsis Int
ellipsisLevel
  let idx :: [Int]
idx = Bool -> Int -> [Int] -> [Int]
calcEllipsisIndex Bool
nextHasEllipsis Int
level [Int]
ellipsisIndex
  if Bool
nextHasEllipsis
     then do
             
             LispVal
curT <- [Env]
-> Env
-> Env
-> Env
-> Env
-> Env
-> Bool
-> LispVal
-> String
-> Int
-> [Int]
-> LispVal
-> LispVal
-> IOThrowsError LispVal
transformDottedList [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv Env
cleanupEnv Bool
dim LispVal
identifiers String
esym Int
level [Int]
idx ([LispVal] -> LispVal
List []) ([LispVal] -> LispVal
List [LispVal
dl])
             case LispVal
curT of
               Nil String
_ -> 
                        [Env]
-> Env
-> Env
-> Env
-> Env
-> Env
-> Bool
-> LispVal
-> String
-> Int
-> [Int]
-> [LispVal]
-> [LispVal]
-> IOThrowsError LispVal
continueTransform [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv Env
cleanupEnv Bool
dim LispVal
identifiers String
esym Int
ellipsisLevel ([Int] -> [Int]
forall a. [a] -> [a]
init [Int]
ellipsisIndex) [LispVal]
result ([LispVal] -> IOThrowsError LispVal)
-> [LispVal] -> IOThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal] -> [LispVal]
forall a. [a] -> [a]
tail [LispVal]
ts 
               List [LispVal]
t -> [Env]
-> Env
-> Env
-> Env
-> Env
-> Env
-> Bool
-> LispVal
-> String
-> Int
-> [Int]
-> LispVal
-> LispVal
-> IOThrowsError LispVal
transformRule [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv Env
cleanupEnv Bool
dim LispVal
identifiers 
                          String
esym
                          Int
ellipsisLevel 
                          [Int]
idx 
                         ([LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
result [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ [LispVal]
t) LispVal
transform
               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
Default String
"Unexpected error in transformRule"
     else do LispVal
lst <- [Env]
-> Env
-> Env
-> Env
-> Env
-> Env
-> Bool
-> LispVal
-> String
-> Int
-> [Int]
-> LispVal
-> LispVal
-> IOThrowsError LispVal
transformDottedList [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv Env
cleanupEnv Bool
dim LispVal
identifiers String
esym Int
ellipsisLevel [Int]
ellipsisIndex ([LispVal] -> LispVal
List []) ([LispVal] -> LispVal
List [LispVal
dl])
             case LispVal
lst of
                  List [LispVal]
l -> [Env]
-> Env
-> Env
-> Env
-> Env
-> Env
-> Bool
-> LispVal
-> String
-> Int
-> [Int]
-> LispVal
-> LispVal
-> IOThrowsError LispVal
transformRule [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv Env
cleanupEnv Bool
dim LispVal
identifiers String
esym Int
ellipsisLevel [Int]
ellipsisIndex ([LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
result [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ [LispVal]
l) ([LispVal] -> LispVal
List [LispVal]
ts)
                  Nil String
_ -> LispVal -> IOThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return LispVal
lst
                  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 -> LispVal -> LispError
BadSpecialForm String
"transformRule: Macro transform error" (LispVal -> LispError) -> LispVal -> LispError
forall a b. (a -> b) -> a -> b
$ [LispVal] -> LispVal
List [LispVal
lst, ([LispVal] -> LispVal
List [LispVal
dl]), Integer -> LispVal
Number (Integer -> LispVal) -> Integer -> LispVal
forall a b. (a -> b) -> a -> b
$ Int -> Integer
forall a. Integral a => a -> Integer
toInteger Int
ellipsisLevel]
transformRule [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv Env
cleanupEnv Bool
dim LispVal
identifiers String
esym Int
ellipsisLevel [Int]
ellipsisIndex (List [LispVal]
result) transform :: LispVal
transform@(List (Atom String
a : [LispVal]
ts)) = do
  Bool Bool
isIdent <- LispVal -> LispVal -> IOThrowsError LispVal
findAtom (String -> LispVal
Atom String
a) LispVal
identifiers 
  Bool
isDefined <- 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
isBound Env
localEnv String
a 
  if Bool
isIdent
     then IOThrowsError LispVal
literalHere
     else do
        if Bool
hasEllipsis
          then Bool -> IOThrowsError LispVal
ellipsisHere Bool
isDefined
          else Bool -> IOThrowsError LispVal
noEllipsis Bool
isDefined
  where
    literalHere :: IOThrowsError LispVal
literalHere = do
      LispVal
expanded <- [Env]
-> Env -> Env -> Env -> Bool -> String -> IOThrowsError LispVal
transformLiteralIdentifier [Env]
defEnv Env
outerEnv Env
divertEnv Env
renameEnv Bool
dim String
a
      if Bool
hasEllipsis 
         then do
              
              
              
              
              
              
              
              
              [Env]
-> Env
-> Env
-> Env
-> Env
-> Env
-> Bool
-> LispVal
-> String
-> Int
-> [Int]
-> LispVal
-> LispVal
-> IOThrowsError LispVal
transformRule [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv Env
cleanupEnv Bool
dim LispVal
identifiers String
esym Int
ellipsisLevel [Int]
ellipsisIndex ([LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
result [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ [LispVal
expanded]) ([LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal] -> [LispVal]
forall a. [a] -> [a]
tail [LispVal]
ts)
         
         
         else do
              [LispVal] -> IOThrowsError LispVal
continueTransformWith ([LispVal] -> IOThrowsError LispVal)
-> [LispVal] -> IOThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
result [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ [LispVal
expanded]
    
    
    appendNil :: LispVal -> LispVal -> LispVal -> LispVal
appendNil LispVal
d (Bool Bool
isImproperPattern) (Bool Bool
isImproperInput) =
      case LispVal
d of
         List [LispVal]
lst -> if Bool
isImproperPattern Bool -> Bool -> Bool
&& Bool -> Bool
not Bool
isImproperInput
                        then [LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
lst [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ [[LispVal] -> LispVal
List []]
                        else [LispVal] -> LispVal
List [LispVal]
lst
         LispVal
_ -> LispVal
d
    appendNil LispVal
d LispVal
_ LispVal
_ = LispVal
d 
    loadNamespacedBool :: Char -> IOThrowsError LispVal
loadNamespacedBool Char
namespc = do
        Maybe LispVal
val <- Env -> Char -> String -> IOThrowsError (Maybe LispVal)
getNamespacedVar' Env
localEnv Char
namespc String
a
        case Maybe LispVal
val of
            Just LispVal
b -> LispVal -> IOThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return LispVal
b
            Maybe LispVal
Nothing -> 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
False
    hasEllipsis :: Bool
hasEllipsis = LispVal -> String -> Bool
macroElementMatchesMany LispVal
transform String
esym
    ellipsisHere :: Bool -> IOThrowsError LispVal
ellipsisHere Bool
isDefined = do
        if Bool
isDefined
             then do 
                    LispVal
isImproperPattern <- Char -> IOThrowsError LispVal
loadNamespacedBool Char
'p' 
                    LispVal
isImproperInput <- Char -> IOThrowsError LispVal
loadNamespacedBool Char
'i' 
                    
                    LispVal
var <- Env -> String -> IOThrowsError LispVal
getVar Env
localEnv String
a
                    case LispVal
var of
                      
                      List [LispVal]
_ -> do case (LispVal -> LispVal -> LispVal -> LispVal
appendNil (LispVal -> [Int] -> LispVal
Matches.getData LispVal
var [Int]
ellipsisIndex) LispVal
isImproperPattern LispVal
isImproperInput) of
                                     List [LispVal]
aa -> [Env]
-> Env
-> Env
-> Env
-> Env
-> Env
-> Bool
-> LispVal
-> String
-> Int
-> [Int]
-> LispVal
-> LispVal
-> IOThrowsError LispVal
transformRule [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv Env
cleanupEnv Bool
dim LispVal
identifiers String
esym Int
ellipsisLevel [Int]
ellipsisIndex ([LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
result [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ [LispVal]
aa) ([LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal] -> [LispVal]
forall a. [a] -> [a]
tail [LispVal]
ts)
                                     LispVal
_ -> 
                                          [Env]
-> Env
-> Env
-> Env
-> Env
-> Env
-> Bool
-> LispVal
-> String
-> Int
-> [Int]
-> [LispVal]
-> [LispVal]
-> IOThrowsError LispVal
continueTransform [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv Env
cleanupEnv Bool
dim LispVal
identifiers String
esym Int
ellipsisLevel [Int]
ellipsisIndex [LispVal]
result ([LispVal] -> IOThrowsError LispVal)
-> [LispVal] -> IOThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal] -> [LispVal]
forall a. [a] -> [a]
tail [LispVal]
ts
                      Nil String
"" -> 
                                [Env]
-> Env
-> Env
-> Env
-> Env
-> Env
-> Bool
-> LispVal
-> String
-> Int
-> [Int]
-> [LispVal]
-> [LispVal]
-> IOThrowsError LispVal
continueTransform [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv Env
cleanupEnv Bool
dim LispVal
identifiers String
esym Int
ellipsisLevel [Int]
ellipsisIndex [LispVal]
result ([LispVal] -> IOThrowsError LispVal)
-> [LispVal] -> IOThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal] -> [LispVal]
forall a. [a] -> [a]
tail [LispVal]
ts
                      LispVal
v -> [Env]
-> Env
-> Env
-> Env
-> Env
-> Env
-> Bool
-> LispVal
-> String
-> Int
-> [Int]
-> LispVal
-> LispVal
-> IOThrowsError LispVal
transformRule [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv Env
cleanupEnv Bool
dim LispVal
identifiers String
esym Int
ellipsisLevel [Int]
ellipsisIndex ([LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
result [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ [LispVal
v]) ([LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal] -> [LispVal]
forall a. [a] -> [a]
tail [LispVal]
ts)
             else 
                  [Env]
-> Env
-> Env
-> Env
-> Env
-> Env
-> Bool
-> LispVal
-> String
-> Int
-> [Int]
-> LispVal
-> LispVal
-> IOThrowsError LispVal
transformRule [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv Env
cleanupEnv Bool
dim LispVal
identifiers String
esym Int
ellipsisLevel [Int]
ellipsisIndex ([LispVal] -> LispVal
List [LispVal]
result) ([LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal] -> [LispVal]
forall a. [a] -> [a]
tail [LispVal]
ts)
    noEllipsis :: Bool -> IOThrowsError LispVal
noEllipsis Bool
isDefined = do
      LispVal
isImproperPattern <- Char -> IOThrowsError LispVal
loadNamespacedBool Char
'p' 
      LispVal
isImproperInput <- Char -> IOThrowsError LispVal
loadNamespacedBool Char
'i' 
      LispVal
t <- if Bool
isDefined
              then do
                   LispVal
var <- Env -> String -> IOThrowsError LispVal
getVar Env
localEnv String
a
                   case LispVal
var of
                     Nil String
"" -> do 
                        
                        
                        
                        
                        
                        LispVal
wasPair <- Env -> Char -> String -> IOThrowsError LispVal
getNamespacedVar Env
localEnv 
                                                    Char
'_' 
                                                    String
a
                        case LispVal
wasPair of
                            Bool Bool
True -> 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
Nil String
"var (pair) not defined in pattern"
                            LispVal
_ -> 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
Nil String
"var not defined in pattern"
                     Nil String
input -> Env -> String -> IOThrowsError LispVal
getVar Env
outerEnv String
input
                     List [LispVal]
_ -> do
                          if Int
ellipsisLevel Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0
                                  then 
                                       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
$ LispVal -> LispVal -> LispVal -> LispVal
appendNil (LispVal -> [Int] -> LispVal
Matches.getData LispVal
var [Int]
ellipsisIndex) 
                                                           LispVal
isImproperPattern 
                                                           LispVal
isImproperInput 
                                  else LispVal -> IOThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return LispVal
var 
                     LispVal
_ -> LispVal -> IOThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return LispVal
var
              else do
                  
                  
                  
                  
                  Maybe LispVal
alreadyRenamed <- Env -> Char -> String -> IOThrowsError (Maybe LispVal)
getNamespacedVar' Env
localEnv Char
'r'  String
a
                  case Maybe LispVal
alreadyRenamed of
                    Just LispVal
renamed -> LispVal -> IOThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return LispVal
renamed
                    Maybe LispVal
Nothing -> do
                       Atom String
renamed <- String -> IOThrowsError LispVal
_gensym String
a
                       LispVal
_ <- Env -> Char -> String -> LispVal -> IOThrowsError LispVal
defineNamespacedVar Env
localEnv  Char
'r'  String
a (LispVal -> IOThrowsError LispVal)
-> LispVal -> IOThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ String -> LispVal
Atom String
renamed
                       LispVal
_ <- Env -> Char -> String -> LispVal -> IOThrowsError LispVal
defineNamespacedVar Env
renameEnv Char
'r'  String
a (LispVal -> IOThrowsError LispVal)
-> LispVal -> IOThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ String -> LispVal
Atom String
renamed
                       
                       LispVal
_ <- Env -> String -> LispVal -> IOThrowsError LispVal
defineVar Env
cleanupEnv String
renamed (LispVal -> IOThrowsError LispVal)
-> LispVal -> IOThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ String -> LispVal
Atom String
a 
                       LispVal
_ <- Env -> String -> LispVal -> IOThrowsError LispVal
defineVar Env
renameEnv String
renamed (LispVal -> IOThrowsError LispVal)
-> LispVal -> IOThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ 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
      case LispVal
t of
         Nil String
"var not defined in pattern" -> 
            if Int
ellipsisLevel Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0
               then LispVal -> IOThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return LispVal
t
               else [LispVal] -> IOThrowsError LispVal
continueTransformWith [LispVal]
result 
         Nil String
"var (pair) not defined in pattern" -> 
            if Int
ellipsisLevel Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0
               then LispVal -> IOThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return LispVal
t
                    
               else [LispVal] -> IOThrowsError LispVal
continueTransformWith ([LispVal] -> IOThrowsError LispVal)
-> [LispVal] -> IOThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
result [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ [[LispVal] -> LispVal
List []]
         Nil String
_ -> LispVal -> IOThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return LispVal
t
         List [LispVal]
l -> do
            
            
            if (LispVal -> LispVal -> Bool
eqVal LispVal
isImproperPattern (LispVal -> Bool) -> LispVal -> Bool
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool Bool
True) Bool -> Bool -> Bool
&& (LispVal -> LispVal -> Bool
eqVal LispVal
isImproperInput (LispVal -> Bool) -> LispVal -> Bool
forall a b. (a -> b) -> a -> b
$ Bool -> LispVal
Bool Bool
True)
              then [LispVal] -> IOThrowsError LispVal
continueTransformWith ([LispVal] -> IOThrowsError LispVal)
-> [LispVal] -> IOThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
result [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ ([LispVal] -> [LispVal]
buildImproperList [LispVal]
l)
              else [LispVal] -> IOThrowsError LispVal
continueTransformWith ([LispVal] -> IOThrowsError LispVal)
-> [LispVal] -> IOThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
result [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ [LispVal
t]
         LispVal
_ -> [LispVal] -> IOThrowsError LispVal
continueTransformWith ([LispVal] -> IOThrowsError LispVal)
-> [LispVal] -> IOThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
result [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ [LispVal
t]
    
    buildImproperList :: [LispVal] -> [LispVal]
buildImproperList [LispVal]
lst 
      | [LispVal] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [LispVal]
lst Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
1 = [[LispVal] -> LispVal -> LispVal
DottedList ([LispVal] -> [LispVal]
forall a. [a] -> [a]
init [LispVal]
lst) ([LispVal] -> LispVal
forall a. [a] -> a
last [LispVal]
lst)]
      | Bool
otherwise      = [LispVal]
lst
    
    continueTransformWith :: [LispVal] -> IOThrowsError LispVal
continueTransformWith [LispVal]
results = 
      [Env]
-> Env
-> Env
-> Env
-> Env
-> Env
-> Bool
-> LispVal
-> String
-> Int
-> [Int]
-> LispVal
-> LispVal
-> IOThrowsError LispVal
transformRule [Env]
defEnv Env
outerEnv Env
divertEnv 
                    Env
localEnv
                    Env
renameEnv Env
cleanupEnv Bool
dim LispVal
identifiers 
                    String
esym
                    Int
ellipsisLevel 
                    [Int]
ellipsisIndex 
                   ([LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
results)
                   ([LispVal] -> LispVal
List [LispVal]
ts)
transformRule [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv Env
cleanupEnv Bool
dim LispVal
identifiers String
esym Int
ellipsisLevel [Int]
ellipsisIndex (List [LispVal]
result) (List (LispVal
t : [LispVal]
ts)) = do
  [Env]
-> Env
-> Env
-> Env
-> Env
-> Env
-> Bool
-> LispVal
-> String
-> Int
-> [Int]
-> LispVal
-> LispVal
-> IOThrowsError LispVal
transformRule [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv Env
cleanupEnv Bool
dim LispVal
identifiers String
esym Int
ellipsisLevel [Int]
ellipsisIndex ([LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
result [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ [LispVal
t]) ([LispVal] -> LispVal
List [LispVal]
ts) 
transformRule [Env]
_ Env
_ Env
_ Env
_ Env
_ Env
_ Bool
_ LispVal
_ String
_ Int
_ [Int]
_ result :: LispVal
result@(List [LispVal]
_) (List []) = do
  LispVal -> IOThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return LispVal
result
transformRule [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv Env
_ Bool
dim LispVal
identifiers String
_ Int
_ [Int]
_ LispVal
_ (Atom String
transform) = do
  Bool Bool
isIdent <- LispVal -> LispVal -> IOThrowsError LispVal
findAtom (String -> LispVal
Atom String
transform) LispVal
identifiers
  Bool
isPattVar <- 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
localEnv String
transform
  if Bool
isPattVar Bool -> Bool -> Bool
&& Bool -> Bool
not Bool
isIdent
     then Env -> String -> IOThrowsError LispVal
getVar Env
localEnv String
transform
     else [Env]
-> Env -> Env -> Env -> Bool -> String -> IOThrowsError LispVal
transformLiteralIdentifier [Env]
defEnv Env
outerEnv Env
divertEnv Env
renameEnv Bool
dim String
transform
transformRule [Env]
_ Env
_ Env
_ Env
_ Env
_ Env
_ Bool
_ LispVal
_ String
_ Int
_ [Int]
_ LispVal
_ LispVal
transform = LispVal -> IOThrowsError LispVal
forall (m :: * -> *) a. Monad m => a -> m a
return LispVal
transform
transformLiteralIdentifier :: [Env] -> Env -> Env -> Env -> Bool -> String -> IOThrowsError LispVal
transformLiteralIdentifier :: [Env]
-> Env -> Env -> Env -> Bool -> String -> IOThrowsError LispVal
transformLiteralIdentifier [Env]
defEnv Env
outerEnv Env
divertEnv Env
renameEnv Bool
definedInMacro String
transform = do
  Bool
isInDef <- 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] -> Env
forall a. [a] -> a
head [Env]
defEnv) String
transform
  Bool
isRenamed <- 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
renameEnv String
transform
  if (Bool
isInDef Bool -> Bool -> Bool
&& Bool -> Bool
not Bool
definedInMacro) Bool -> Bool -> Bool
|| (Bool
isInDef Bool -> Bool -> Bool
&& Bool
definedInMacro Bool -> Bool -> Bool
&& Bool -> Bool
not Bool
isRenamed)
     then do
          
         LispVal
value <- Env -> String -> IOThrowsError LispVal
getVar ([Env] -> Env
forall a. [a] -> a
head [Env]
defEnv) String
transform
         Atom String
renamed <- String -> IOThrowsError LispVal
_gensym String
transform
         LispVal
_ <- Env -> String -> LispVal -> IOThrowsError LispVal
defineVar Env
divertEnv String
renamed LispVal
value 
         
         List [LispVal]
diverted <- Env -> Char -> String -> IOThrowsError LispVal
getNamespacedVar Env
outerEnv Char
' ' String
"diverted"
         LispVal
_ <- Env -> Char -> String -> LispVal -> IOThrowsError LispVal
setNamespacedVar Env
outerEnv 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
transform]])
         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 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
$ String -> LispVal
Atom String
transform
         
transformDottedList :: [Env] -> Env -> Env -> Env -> Env -> Env -> Bool -> LispVal -> String -> Int -> [Int] -> LispVal -> LispVal -> IOThrowsError LispVal
transformDottedList :: [Env]
-> Env
-> Env
-> Env
-> Env
-> Env
-> Bool
-> LispVal
-> String
-> Int
-> [Int]
-> LispVal
-> LispVal
-> IOThrowsError LispVal
transformDottedList [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv Env
cleanupEnv Bool
dim LispVal
identifiers String
esym Int
ellipsisLevel [Int]
ellipsisIndex (List [LispVal]
result) (List (DottedList [LispVal]
ds LispVal
d : [LispVal]
ts)) = do
          LispVal
lsto <- [Env]
-> Env
-> Env
-> Env
-> Env
-> Env
-> Bool
-> LispVal
-> String
-> Int
-> [Int]
-> LispVal
-> LispVal
-> IOThrowsError LispVal
transformRule [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv Env
cleanupEnv Bool
dim LispVal
identifiers String
esym Int
ellipsisLevel [Int]
ellipsisIndex ([LispVal] -> LispVal
List []) ([LispVal] -> LispVal
List [LispVal]
ds)
          case LispVal
lsto of
            List [LispVal]
lst -> do
              
              
              
              
              
              LispVal
r <- [Env]
-> Env
-> Env
-> Env
-> Env
-> Env
-> Bool
-> LispVal
-> String
-> Int
-> [Int]
-> LispVal
-> LispVal
-> IOThrowsError LispVal
transformRule [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv Env
cleanupEnv Bool
dim LispVal
identifiers 
                                 String
esym
                                 Int
ellipsisLevel 
                                 [Int]
ellipsisIndex 
                                 ([LispVal] -> LispVal
List []) 
                                 ([LispVal] -> LispVal
List [LispVal
d, String -> LispVal
Atom String
esym])
              case LispVal
r of
                   
                   List [] ->
                       [Env]
-> Env
-> Env
-> Env
-> Env
-> Env
-> Bool
-> LispVal
-> String
-> Int
-> [Int]
-> LispVal
-> LispVal
-> IOThrowsError LispVal
transformRule [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv Env
cleanupEnv Bool
dim LispVal
identifiers String
esym Int
ellipsisLevel [Int]
ellipsisIndex ([LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
result [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ [[LispVal] -> LispVal
List [LispVal]
lst]) ([LispVal] -> LispVal
List [LispVal]
ts)
                   Nil String
_ ->  
                       [Env]
-> Env
-> Env
-> Env
-> Env
-> Env
-> Bool
-> LispVal
-> String
-> Int
-> [Int]
-> LispVal
-> LispVal
-> IOThrowsError LispVal
transformRule [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv Env
cleanupEnv Bool
dim LispVal
identifiers String
esym Int
ellipsisLevel [Int]
ellipsisIndex ([LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
result [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ [[LispVal] -> LispVal
List [LispVal]
lst]) ([LispVal] -> LispVal
List [LispVal]
ts)
                   List [LispVal]
rst -> do
                       [Env]
-> Env
-> Env
-> Env
-> Env
-> Env
-> Bool
-> LispVal
-> String
-> Int
-> [Int]
-> LispVal
-> LispVal
-> IOThrowsError LispVal
transformRule [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv Env
cleanupEnv Bool
dim LispVal
identifiers String
esym Int
ellipsisLevel [Int]
ellipsisIndex 
                                    ([LispVal] -> [LispVal] -> [LispVal] -> LispVal
buildTransformedCode [LispVal]
result [LispVal]
lst [LispVal]
rst) ([LispVal] -> LispVal
List [LispVal]
ts)
                   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 -> LispVal -> LispError
BadSpecialForm String
"Macro transform error processing pair" (LispVal -> LispError) -> LispVal -> LispError
forall a b. (a -> b) -> a -> b
$ [LispVal] -> LispVal -> LispVal
DottedList [LispVal]
ds LispVal
d
            Nil String
_ -> 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
Nil String
""
            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 -> LispVal -> LispError
BadSpecialForm String
"Macro transform error processing pair" (LispVal -> LispError) -> LispVal -> LispError
forall a b. (a -> b) -> a -> b
$ [LispVal] -> LispVal -> LispVal
DottedList [LispVal]
ds LispVal
d
 where 
   
   
   buildTransformedCode :: [LispVal] -> [LispVal] -> [LispVal] -> LispVal
buildTransformedCode [LispVal]
results [LispVal]
ps [LispVal]
p = do 
     case [LispVal]
p of
        [List []] -> [LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
results [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ [[LispVal] -> LispVal
List [LispVal]
ps]         
        [List [LispVal]
ls] -> [LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
results [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ [[LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
ps [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ [LispVal]
ls] 
        [LispVal
l] -> [LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
results [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ [[LispVal] -> LispVal -> LispVal
DottedList [LispVal]
ps LispVal
l]
        [LispVal]
ls -> do
            
            
            case [LispVal] -> LispVal
forall a. [a] -> a
last [LispVal]
ls of
              List [] -> [LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
results [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ [[LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
ps [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ [LispVal] -> [LispVal]
forall a. [a] -> [a]
init [LispVal]
ls]
              List [LispVal]
lls -> [LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
results [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ [[LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
ps [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ ([LispVal] -> [LispVal]
forall a. [a] -> [a]
init [LispVal]
ls) [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ [LispVal]
lls]
              LispVal
t -> [LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
results [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ [[LispVal] -> LispVal -> LispVal
DottedList ([LispVal]
ps [LispVal] -> [LispVal] -> [LispVal]
forall a. [a] -> [a] -> [a]
++ [LispVal] -> [LispVal]
forall a. [a] -> [a]
init [LispVal]
ls) LispVal
t]
transformDottedList [Env]
_ Env
_ Env
_ Env
_ Env
_ Env
_ Bool
_ LispVal
_ String
_ Int
_ [Int]
_ LispVal
_ 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
Default String
"Unexpected error in transformDottedList"
continueTransform :: [Env] -> Env -> Env -> Env -> Env -> Env -> Bool -> LispVal -> String -> Int -> [Int] -> [LispVal] -> [LispVal] -> IOThrowsError LispVal
continueTransform :: [Env]
-> Env
-> Env
-> Env
-> Env
-> Env
-> Bool
-> LispVal
-> String
-> Int
-> [Int]
-> [LispVal]
-> [LispVal]
-> IOThrowsError LispVal
continueTransform [Env]
defEnv Env
outerEnv Env
divertEnv Env
localEnv Env
renameEnv Env
cleanupEnv Bool
dim LispVal
identifiers String
esym Int
ellipsisLevel [Int]
ellipsisIndex [LispVal]
result [LispVal]
remaining = do
    if Bool -> Bool
not ([LispVal] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [LispVal]
remaining)
       then [Env]
-> Env
-> Env
-> Env
-> Env
-> Env
-> Bool
-> LispVal
-> String
-> Int
-> [Int]
-> LispVal
-> LispVal
-> IOThrowsError LispVal
transformRule [Env]
defEnv Env
outerEnv Env
divertEnv 
                          Env
localEnv 
                          Env
renameEnv
                          Env
cleanupEnv Bool
dim LispVal
identifiers
                          String
esym
                          Int
ellipsisLevel 
                          [Int]
ellipsisIndex 
                         ([LispVal] -> LispVal
List [LispVal]
result) 
                         ([LispVal] -> LispVal
List ([LispVal] -> LispVal) -> [LispVal] -> LispVal
forall a b. (a -> b) -> a -> b
$ [LispVal]
remaining)
       else if Bool -> Bool
not ([LispVal] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [LispVal]
result)
               then 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
$ [LispVal] -> LispVal
List [LispVal]
result
               else if Int
ellipsisLevel Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
0 
                       then 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
Nil String
""  
                       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
$ [LispVal] -> LispVal
List [] 
findAtom :: LispVal -> LispVal -> IOThrowsError LispVal
findAtom :: LispVal -> LispVal -> IOThrowsError LispVal
findAtom (Atom String
target) (List (Atom String
a : [LispVal]
as)) = do
  if String
target String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
a
     then 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
True
     else LispVal -> LispVal -> IOThrowsError LispVal
findAtom (String -> LispVal
Atom String
target) ([LispVal] -> LispVal
List [LispVal]
as)
findAtom LispVal
_ (List (LispVal
badtype : [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 -> LispVal -> LispError
TypeMismatch String
"symbol" LispVal
badtype
findAtom LispVal
_ LispVal
_ = 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
False
calcEllipsisLevel :: Bool -> Int -> Int
calcEllipsisLevel :: Bool -> Int -> Int
calcEllipsisLevel  Bool
nextHasEllipsis Int
ellipsisLevel =
    if Bool
nextHasEllipsis then Int
ellipsisLevel Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1
                       else Int
ellipsisLevel
calcEllipsisIndex :: Bool -> Int -> [Int] -> [Int]
calcEllipsisIndex :: Bool -> Int -> [Int] -> [Int]
calcEllipsisIndex Bool
nextHasEllipsis Int
ellipsisLevel [Int]
ellipsisIndex =
    if Bool
nextHasEllipsis 
       then if ([Int] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Int]
ellipsisIndex Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ellipsisLevel)
               
               then do
                 let l :: ([Int], [Int])
l = Int -> [Int] -> ([Int], [Int])
forall a. Int -> [a] -> ([a], [a])
splitAt (Int
ellipsisLevel Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) [Int]
ellipsisIndex
                 (([Int], [Int]) -> [Int]
forall a b. (a, b) -> a
fst ([Int], [Int])
l) [Int] -> [Int] -> [Int]
forall a. [a] -> [a] -> [a]
++ [([Int] -> Int
forall a. [a] -> a
head (([Int], [Int]) -> [Int]
forall a b. (a, b) -> b
snd ([Int], [Int])
l)) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1]
               
               else [Int]
ellipsisIndex [Int] -> [Int] -> [Int]
forall a. [a] -> [a] -> [a]
++ [Int
0]
       else [Int]
ellipsisIndex
asVector :: [LispVal] -> LispVal
asVector :: [LispVal] -> LispVal
asVector [LispVal]
lst = (Array Int LispVal -> LispVal
Vector (Array Int LispVal -> LispVal) -> Array Int LispVal -> LispVal
forall a b. (a -> b) -> a -> b
$ ((Int, Int) -> [LispVal] -> Array Int LispVal
forall i e. Ix i => (i, i) -> [e] -> Array i e
listArray (Int
0, [LispVal] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [LispVal]
lst Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)) [LispVal]
lst)
loadMacros :: Env       
           -> Env       
           -> Maybe Env 
           -> Bool      
           -> [LispVal] 
           -> IOThrowsError LispVal 
loadMacros :: Env
-> Env -> Maybe Env -> Bool -> [LispVal] -> IOThrowsError LispVal
loadMacros Env
e Env
be Maybe Env
Nothing Bool
dim 
    (List 
        [Atom String
keyword, 
         (List (Atom String
"syntax-rules" : 
                Atom String
ellipsis :
                (List [LispVal]
identifiers : [LispVal]
rules)))] : 
        [LispVal]
bs) = do
  LispVal
_ <- Env -> Char -> String -> LispVal -> IOThrowsError LispVal
defineNamespacedVar Env
be Char
macroNamespace String
keyword (LispVal -> IOThrowsError LispVal)
-> LispVal -> IOThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ 
        Maybe Env
-> Maybe Env -> Bool -> String -> [LispVal] -> [LispVal] -> LispVal
Syntax (Env -> Maybe Env
forall a. a -> Maybe a
Just Env
e) Maybe Env
forall a. Maybe a
Nothing Bool
dim String
ellipsis [LispVal]
identifiers [LispVal]
rules
  Env
-> Env -> Maybe Env -> Bool -> [LispVal] -> IOThrowsError LispVal
loadMacros Env
e Env
be Maybe Env
forall a. Maybe a
Nothing Bool
dim [LispVal]
bs
loadMacros Env
e Env
be Maybe Env
Nothing Bool
dim 
    (List 
        [Atom String
keyword, 
         (List (Atom String
"syntax-rules" : 
                (List [LispVal]
identifiers : [LispVal]
rules)))] : 
        [LispVal]
bs) = do
  LispVal
_ <- Env -> Char -> String -> LispVal -> IOThrowsError LispVal
defineNamespacedVar Env
be Char
macroNamespace String
keyword (LispVal -> IOThrowsError LispVal)
-> LispVal -> IOThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ 
        Maybe Env
-> Maybe Env -> Bool -> String -> [LispVal] -> [LispVal] -> LispVal
Syntax (Env -> Maybe Env
forall a. a -> Maybe a
Just Env
e) Maybe Env
forall a. Maybe a
Nothing Bool
dim String
"..." [LispVal]
identifiers [LispVal]
rules
  Env
-> Env -> Maybe Env -> Bool -> [LispVal] -> IOThrowsError LispVal
loadMacros Env
e Env
be Maybe Env
forall a. Maybe a
Nothing Bool
dim [LispVal]
bs
loadMacros Env
e Env
be Maybe Env
Nothing Bool
dim 
    (List  
       [Atom String
keyword, (List [Atom String
"er-macro-transformer",  
             (List (Atom String
"lambda" : List [LispVal]
fparams : [LispVal]
fbody))])]
       : [LispVal]
bs) = do
  LispVal
f <- Env -> [LispVal] -> [LispVal] -> IOThrowsError LispVal
forall (m :: * -> *).
Monad m =>
Env -> [LispVal] -> [LispVal] -> m LispVal
makeNormalFunc Env
e [LispVal]
fparams [LispVal]
fbody 
  LispVal
_ <- Env -> Char -> String -> LispVal -> IOThrowsError LispVal
defineNamespacedVar Env
be Char
macroNamespace String
keyword (LispVal -> IOThrowsError LispVal)
-> LispVal -> IOThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ LispVal -> LispVal
SyntaxExplicitRenaming LispVal
f
  Env
-> Env -> Maybe Env -> Bool -> [LispVal] -> IOThrowsError LispVal
loadMacros Env
e Env
be Maybe Env
forall a. Maybe a
Nothing Bool
dim [LispVal]
bs
loadMacros Env
e Env
be (Just Env
re) Bool
dim 
    args :: [LispVal]
args@(List [Atom String
keyword, 
                (List (Atom String
syntaxrules : [LispVal]
spec))] : 
               [LispVal]
bs) = do
  Atom String
exKeyword <- Env -> LispVal -> IOThrowsError LispVal
expandAtom Env
re (String -> LispVal
Atom String
keyword)
  LispVal
exSynRules <- Env -> LispVal -> IOThrowsError LispVal
expandAtom Env
re (String -> LispVal
Atom String
syntaxrules)
  case (LispVal
exSynRules, [LispVal]
spec) of
    (Atom String
"syntax-rules", 
     (Atom String
ellipsis :
      (List [LispVal]
identifiers : [LispVal]
rules))) -> do
        LispVal
_ <- Env -> Char -> String -> LispVal -> IOThrowsError LispVal
defineNamespacedVar Env
be Char
macroNamespace String
exKeyword (LispVal -> IOThrowsError LispVal)
-> LispVal -> IOThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ 
             Maybe Env
-> Maybe Env -> Bool -> String -> [LispVal] -> [LispVal] -> LispVal
Syntax (Env -> Maybe Env
forall a. a -> Maybe a
Just Env
e) (Env -> Maybe Env
forall a. a -> Maybe a
Just Env
re) Bool
dim String
ellipsis [LispVal]
identifiers [LispVal]
rules
        Env
-> Env -> Maybe Env -> Bool -> [LispVal] -> IOThrowsError LispVal
loadMacros Env
e Env
be (Env -> Maybe Env
forall a. a -> Maybe a
Just Env
re) Bool
dim [LispVal]
bs
    (Atom String
"syntax-rules", 
      (List [LispVal]
identifiers : [LispVal]
rules)) -> do
        
        LispVal
_ <- Env -> Char -> String -> LispVal -> IOThrowsError LispVal
defineNamespacedVar Env
be Char
macroNamespace String
exKeyword (LispVal -> IOThrowsError LispVal)
-> LispVal -> IOThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ 
             Maybe Env
-> Maybe Env -> Bool -> String -> [LispVal] -> [LispVal] -> LispVal
Syntax (Env -> Maybe Env
forall a. a -> Maybe a
Just Env
e) (Env -> Maybe Env
forall a. a -> Maybe a
Just Env
re) Bool
dim String
"..." [LispVal]
identifiers [LispVal]
rules
        Env
-> Env -> Maybe Env -> Bool -> [LispVal] -> IOThrowsError LispVal
loadMacros Env
e Env
be (Env -> Maybe Env
forall a. a -> Maybe a
Just Env
re) Bool
dim [LispVal]
bs
    
    
    
    (Atom String
"er-macro-transformer",
      [List (Atom String
_ : List [LispVal]
fparams : [LispVal]
fbody)]) -> do
        
        
        LispVal
f <- Env -> [LispVal] -> [LispVal] -> IOThrowsError LispVal
forall (m :: * -> *).
Monad m =>
Env -> [LispVal] -> [LispVal] -> m LispVal
makeNormalFunc Env
e [LispVal]
fparams [LispVal]
fbody 
        LispVal
_ <- Env -> Char -> String -> LispVal -> IOThrowsError LispVal
defineNamespacedVar Env
be Char
macroNamespace String
exKeyword (LispVal -> IOThrowsError LispVal)
-> LispVal -> IOThrowsError LispVal
forall a b. (a -> b) -> a -> b
$ LispVal -> LispVal
SyntaxExplicitRenaming LispVal
f
        Env
-> Env -> Maybe Env -> Bool -> [LispVal] -> IOThrowsError LispVal
loadMacros Env
e Env
be (Env -> Maybe Env
forall a. a -> Maybe a
Just Env
re) Bool
dim [LispVal]
bs
    (LispVal, [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 -> LispVal -> LispError
BadSpecialForm String
"Unable to evaluate form w/re" (LispVal -> LispError) -> LispVal -> LispError
forall a b. (a -> b) -> a -> b
$ [LispVal] -> LispVal
List [LispVal]
args
loadMacros Env
_ Env
_ Maybe Env
_ Bool
_ [] = 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
Nil String
""
loadMacros Env
_ Env
_ Maybe Env
_ Bool
_ [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 -> LispVal -> LispError
BadSpecialForm String
"Unable to evaluate form" (LispVal -> LispError) -> LispVal -> LispError
forall a b. (a -> b) -> a -> b
$ [LispVal] -> LispVal
List [LispVal]
form 
getOrigName :: Env -> String -> IOThrowsError String
getOrigName :: Env -> String -> IOThrowsError String
getOrigName Env
renameEnv String
a = do
  Maybe LispVal
v <- Env -> String -> IOThrowsError (Maybe LispVal)
getVar' Env
renameEnv String
a
  case Maybe LispVal
v of 
    Just (Atom String
a') ->
      if String
a String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
a'
        then String -> IOThrowsError String
forall (m :: * -> *) a. Monad m => a -> m a
return String
a'
        else Env -> String -> IOThrowsError String
getOrigName Env
renameEnv String
a'
    Maybe LispVal
_ -> String -> IOThrowsError String
forall (m :: * -> *) a. Monad m => a -> m a
return String
a
isLexicallyDefined :: Env -> Env -> String -> IOThrowsError Bool
isLexicallyDefined :: Env -> Env -> String -> ExceptT LispError IO Bool
isLexicallyDefined Env
outerEnv Env
renameEnv String
a = do
  Bool
o <- 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
isBound Env
outerEnv String
a
  Bool
r <- 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
isBound Env
renameEnv String
a
  Bool -> ExceptT LispError IO Bool
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> ExceptT LispError IO Bool)
-> Bool -> ExceptT LispError IO Bool
forall a b. (a -> b) -> a -> b
$ Bool
o Bool -> Bool -> Bool
|| Bool
r
findBoundMacro :: [Env] -> Env -> String -> IOThrowsError (Maybe LispVal)
findBoundMacro :: [Env] -> Env -> String -> IOThrowsError (Maybe LispVal)
findBoundMacro [Env]
defEnv Env
useEnv String
a = do
  Maybe LispVal
synUse <- Env -> Char -> String -> IOThrowsError (Maybe LispVal)
getNamespacedVar' Env
useEnv Char
macroNamespace String
a
  case Maybe LispVal
synUse of
    Just LispVal
syn -> Maybe LispVal -> IOThrowsError (Maybe LispVal)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe LispVal -> IOThrowsError (Maybe LispVal))
-> Maybe LispVal -> IOThrowsError (Maybe LispVal)
forall a b. (a -> b) -> a -> b
$ LispVal -> Maybe LispVal
forall a. a -> Maybe a
Just LispVal
syn
    Maybe LispVal
_ -> [Env] -> IOThrowsError (Maybe LispVal)
check [Env]
defEnv
 where
  check :: [Env] -> IOThrowsError (Maybe LispVal)
check (Env
e : [Env]
es) = do
    Maybe LispVal
r <- Env -> Char -> String -> IOThrowsError (Maybe LispVal)
getNamespacedVar' Env
e Char
macroNamespace String
a
    case Maybe LispVal
r of
      Just LispVal
_ -> Maybe LispVal -> IOThrowsError (Maybe LispVal)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe LispVal
r
      Maybe LispVal
_ -> [Env] -> IOThrowsError (Maybe LispVal)
check [Env]
es
  check [] = Maybe LispVal -> IOThrowsError (Maybe LispVal)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe LispVal
forall a. Maybe a
Nothing