aboutsummaryrefslogtreecommitdiff
path: root/src/Operators.hs
blob: 3b96281d6ba641e4c0ae1f3f65b3b38addd63b40 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
module Operators (
    primitives
    ) where

import           Control.Monad.Except
import           Error                (LispError (..), LispResult (..))
import           Parser

primitives :: [(String, [Expr] -> LispResult Expr)]
primitives =
    [
    ("+", arithmetic (+))
    , ("-", arithmetic (-))
    , ("*", arithmetic (*))
    , ("/", arithmetic div)
    ]

arithmetic :: (Integer -> Integer -> Integer) -> [Expr] -> LispResult Expr
arithmetic op args
    | length args < 2 = throwError $ ArgCount 2 args
    | otherwise = do
        as <- mapM unwrapNum args
        return . IntLiteral $ foldl1 op as

unwrapNum :: Expr -> LispResult Integer
unwrapNum (IntLiteral n) = return n
unwrapNum x              = throwError $ TypeMismatch "number" x