aboutsummaryrefslogtreecommitdiff
path: root/src/Operators.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Operators.hs')
-rw-r--r--src/Operators.hs53
1 files changed, 27 insertions, 26 deletions
diff --git a/src/Operators.hs b/src/Operators.hs
index 27488f3..051655a 100644
--- a/src/Operators.hs
+++ b/src/Operators.hs
@@ -7,21 +7,21 @@ import Error.Base (LispError (..), LispResult (..))
7import Parser 7import Parser
8 8
9primitives :: [(String, [Expr] -> LispResult Expr)] 9primitives :: [(String, [Expr] -> LispResult Expr)]
10primitives = 10primitives = map (\(n, f) -> (n, f n))
11 [ 11 [
12 ("+", arithmetic (+)) 12 ("+" , arithmetic (+))
13 , ("-", arithmetic (-)) 13 , ("-" , arithmetic (-))
14 , ("*", arithmetic (*)) 14 , ("*" , arithmetic (*))
15 , ("/", arithmetic (/)) 15 , ("/" , arithmetic (/))
16 , (">", comparator (>)) 16 , (">" , comparator (>))
17 , ("<", comparator (<)) 17 , ("<" , comparator (<))
18 , (">=", comparator (>=)) 18 , (">=" , comparator (>=))
19 , ("<=", comparator (<=)) 19 , ("<=" , comparator (<=))
20 , ("=", comparator (==)) 20 , ("=" , comparator (==))
21 , ("!=", comparator (/=)) 21 , ("!=" , comparator (/=))
22 , ("not", unaryBool not) 22 , ("not" , unaryBool not)
23 , ("or", naryBool (||)) 23 , ("or" , naryBool (||))
24 , ("and", naryBool (&&)) 24 , ("and" , naryBool (&&))
25 ] 25 ]
26 26
27data LispNumber = I Integer 27data LispNumber = I Integer
@@ -46,33 +46,34 @@ instance Fractional LispNumber where
46 (I a) / (F b) = F $ fromIntegral a / b 46 (I a) / (F b) = F $ fromIntegral a / b
47 (F a) / (F b) = F $ a / b 47 (F a) / (F b) = F $ a / b
48 48
49type FName = String
49type Arithmetic = LispNumber -> LispNumber -> LispNumber 50type Arithmetic = LispNumber -> LispNumber -> LispNumber
50type Comparator = LispNumber -> LispNumber -> Bool 51type Comparator = LispNumber -> LispNumber -> Bool
51type UnaryBool = Bool -> Bool 52type UnaryBool = Bool -> Bool
52type NaryBool = Bool -> Bool -> Bool 53type NaryBool = Bool -> Bool -> Bool
53 54
54arithmetic :: Arithmetic -> [Expr] -> LispResult Expr 55arithmetic :: Arithmetic -> FName -> [Expr] -> LispResult Expr
55arithmetic op args 56arithmetic op name args
56 | null args = throwError $ ArgCount 1 args 57 | null args = throwError $ ArgCount name 1 args
57 | otherwise = do 58 | otherwise = do
58 as <- mapM unwrapNum args 59 as <- mapM unwrapNum args
59 return . wrapNum $ foldl1 op as 60 return . wrapNum $ foldl1 op as
60 61
61comparator :: Comparator -> [Expr] -> LispResult Expr 62comparator :: Comparator -> FName -> [Expr] -> LispResult Expr
62comparator op args 63comparator op name args
63 | length args < 2 = throwError $ ArgCount 2 args 64 | length args < 2 = throwError $ ArgCount name 2 args
64 | otherwise = do 65 | otherwise = do
65 as <- mapM unwrapNum args 66 as <- mapM unwrapNum args
66 return . BoolLiteral . all (== True) $ zipWith op as (tail as) 67 return . BoolLiteral . all (== True) $ zipWith op as (tail as)
67 68
68unaryBool :: UnaryBool -> [Expr] -> LispResult Expr 69unaryBool :: UnaryBool -> FName -> [Expr] -> LispResult Expr
69unaryBool op args 70unaryBool op name args
70 | length args /= 1 = throwError $ ArgCount 1 args 71 | length args /= 1 = throwError $ ArgCount name 1 args
71 | otherwise = BoolLiteral . op <$> unwrapBool (head args) 72 | otherwise = BoolLiteral . op <$> unwrapBool (head args)
72 73
73naryBool :: NaryBool -> [Expr] -> LispResult Expr 74naryBool :: NaryBool -> FName -> [Expr] -> LispResult Expr
74naryBool op args 75naryBool op name args
75 | length args < 2 = throwError $ ArgCount 2 args 76 | length args < 2 = throwError $ ArgCount name 2 args
76 | otherwise = do 77 | otherwise = do
77 as <- mapM unwrapBool args 78 as <- mapM unwrapBool args
78 return . BoolLiteral $ foldl1 op as 79 return . BoolLiteral $ foldl1 op as