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