Additional Primitives: Partial Application

This commit is contained in:
Yann Esposito (Yogsototh) 2011-03-02 15:12:48 +01:00
parent 8d534810b2
commit 4e160f41ed

View file

@ -136,6 +136,8 @@ apply func args = maybe (throwError $ NotFunction "Unrecognized primitive functi
($ args) ($ args)
(lookup func primitives) (lookup func primitives)
-- Primitives
primitives :: [(String, [LispVal] -> ThrowsError LispVal)] primitives :: [(String, [LispVal] -> ThrowsError LispVal)]
primitives = [("+", numericBinop (+)), primitives = [("+", numericBinop (+)),
("-", numericBinop (-)), ("-", numericBinop (-)),
@ -143,7 +145,20 @@ primitives = [("+", numericBinop (+)),
("/", numericBinop div), ("/", numericBinop div),
("mod", numericBinop mod), ("mod", numericBinop mod),
("quotient", numericBinop quot), ("quotient", numericBinop quot),
("remainder", numericBinop rem)] ("remainder", numericBinop rem),
("=", numBoolBinop (==)),
("<", numBoolBinop (<)),
(">", numBoolBinop (>)),
("/=", numBoolBinop (/=)),
(">=", numBoolBinop (>=)),
("<=", numBoolBinop (<=)),
("&&", boolBoolBinop (&&)),
("||", boolBoolBinop (||)),
("string=?", strBoolBinop (==)),
("string<?", strBoolBinop (<)),
("string>?", strBoolBinop (>)),
("string<=?", strBoolBinop (<=)),
("string>=?", strBoolBinop (>=))]
numericBinop :: (Integer -> Integer -> Integer) -> [LispVal] -> ThrowsError LispVal numericBinop :: (Integer -> Integer -> Integer) -> [LispVal] -> ThrowsError LispVal
numericBinop op singleVal@[_] = throwError $ NumArgs 2 singleVal numericBinop op singleVal@[_] = throwError $ NumArgs 2 singleVal
@ -158,6 +173,28 @@ unpackNum (String n) = let parsed = reads n in
unpackNum (List [n]) = unpackNum n unpackNum (List [n]) = unpackNum n
unpackNum notNum = throwError $ TypeMismatch "number" notNum unpackNum notNum = throwError $ TypeMismatch "number" notNum
boolBinop :: (LispVal -> ThrowsError a) -> (a -> a -> Bool) -> [LispVal] -> ThrowsError LispVal
boolBinop unpacker op args = if length args /= 2
then throwError $ NumArgs 2 args
else do
left <- unpacker $ args !! 0
right <- unpacker $ args !! 1
return $ Bool $ left `op` right
numBoolBinop = boolBinop unpackNum
strBoolBinop = boolBinop unpackStr
boolBoolBinop = boolBinop unpackBool
unpackStr :: LispVal -> ThrowsError String
unpackStr (String s) = return s
unpackStr (Number s) = return $ show s
unpackStr (Bool s) = return $ show s
unpackStr notString = throwError $ TypeMismatch "string" notString
unpackBool :: LispVal -> ThrowsError Bool
unpackBool (Bool b) = return b
unpackBool notBool = throwError $ TypeMismatch "boolean" notBool
-- Error checking -- Error checking
data LispError = NumArgs Integer [LispVal] data LispError = NumArgs Integer [LispVal]
| TypeMismatch String LispVal | TypeMismatch String LispVal