diff options
Diffstat (limited to 'src/Operators.hs')
-rw-r--r-- | src/Operators.hs | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/src/Operators.hs b/src/Operators.hs index beb6364..e607250 100644 --- a/src/Operators.hs +++ b/src/Operators.hs | |||
@@ -19,6 +19,7 @@ primitives = | |||
19 | , ("<=", comparator (<=)) | 19 | , ("<=", comparator (<=)) |
20 | , ("=", comparator (==)) | 20 | , ("=", comparator (==)) |
21 | , ("!=", comparator (/=)) | 21 | , ("!=", comparator (/=)) |
22 | , ("not", unaryBool not) | ||
22 | ] | 23 | ] |
23 | 24 | ||
24 | data LispNumber = I Integer | 25 | data LispNumber = I Integer |
@@ -38,7 +39,9 @@ instance Num LispNumber where | |||
38 | (F a) * (F b) = F $ a * b | 39 | (F a) * (F b) = F $ a * b |
39 | 40 | ||
40 | instance Fractional LispNumber where | 41 | instance Fractional LispNumber where |
41 | (I a) / (I b) = I $ a `div` b | 42 | (I a) / (I b) = F $ fromIntegral a / fromIntegral b |
43 | (F a) / (I b) = F $ a / fromIntegral b | ||
44 | (I a) / (F b) = F $ fromIntegral a / b | ||
42 | (F a) / (F b) = F $ a / b | 45 | (F a) / (F b) = F $ a / b |
43 | 46 | ||
44 | arithmetic :: (LispNumber -> LispNumber -> LispNumber) -> [Expr] -> LispResult Expr | 47 | arithmetic :: (LispNumber -> LispNumber -> LispNumber) -> [Expr] -> LispResult Expr |
@@ -55,6 +58,16 @@ comparator op args | |||
55 | as <- mapM unwrapNum args | 58 | as <- mapM unwrapNum args |
56 | return . BoolLiteral . all (== True) $ zipWith op as (tail as) | 59 | return . BoolLiteral . all (== True) $ zipWith op as (tail as) |
57 | 60 | ||
61 | unaryBool :: (Bool -> Bool) -> [Expr] -> LispResult Expr | ||
62 | unaryBool op args | ||
63 | | length args /= 1 = throwError $ ArgCount 1 args | ||
64 | | otherwise = BoolLiteral . op <$> unwrapBool (head args) | ||
65 | |||
66 | naryBool :: (Bool -> Bool -> Bool) -> [Expr] -> LispResult Expr | ||
67 | naryBool op args | ||
68 | | length args < 2 = throwError $ ArgCount 2 args | ||
69 | |||
70 | |||
58 | unwrapNum :: Expr -> LispResult LispNumber | 71 | unwrapNum :: Expr -> LispResult LispNumber |
59 | unwrapNum (IntLiteral n) = return $ I n | 72 | unwrapNum (IntLiteral n) = return $ I n |
60 | unwrapNum (FloatLiteral n) = return $ F n | 73 | unwrapNum (FloatLiteral n) = return $ F n |
@@ -63,3 +76,7 @@ unwrapNum x = throwError $ TypeMismatch "number" x | |||
63 | wrapNum :: LispNumber -> Expr | 76 | wrapNum :: LispNumber -> Expr |
64 | wrapNum (I n) = IntLiteral n | 77 | wrapNum (I n) = IntLiteral n |
65 | wrapNum (F n) = FloatLiteral n | 78 | wrapNum (F n) = FloatLiteral n |
79 | |||
80 | unwrapBool :: Expr -> LispResult Bool | ||
81 | unwrapBool (BoolLiteral s) = return s | ||
82 | unwrapBool x = throwError $ TypeMismatch "boolean" x | ||