DISABLE FDs (REMOVE ME).
[jackhill/mal.git] / haskell / Types.hs
CommitLineData
b76aa73b 1module Types
6116c2d5
NB
2( MalVal (..), IOThrows, Fn, Env, MetaData (..), Vect (..),
3 keyValuePairs, throwStr, toList, keywordMagic)
b76aa73b
JM
4where
5
fa9a9758 6import Data.IORef (IORef)
b76aa73b 7import qualified Data.Map as Map
6116c2d5 8import Control.Monad.Except (ExceptT, throwError)
b76aa73b 9
fa9a9758
JM
10
11-- Base Mal types --
6116c2d5
NB
12type Fn = [MalVal] -> IOThrows MalVal
13
14-- Use type safety for unnamed components, without runtime penalty.
15newtype MetaData = MetaData MalVal
16newtype Vect = Vect Bool
17
b76aa73b 18data MalVal = Nil
6116c2d5 19 | MalBoolean Bool
b76aa73b
JM
20 | MalNumber Int
21 | MalString String
22 | MalSymbol String
6116c2d5
NB
23 | MalSeq MetaData Vect [MalVal]
24 | MalHashMap MetaData (Map.Map String MalVal)
25 | MalAtom MetaData (IORef MalVal)
26 | MalFunction {fn :: Fn,
b091e954
NB
27 f_ast :: MalVal,
28 f_params :: [String],
c150ec41
JM
29 macro :: Bool,
30 meta :: MalVal}
fa9a9758 31
6116c2d5
NB
32keywordMagic :: Char
33keywordMagic = '\x029e'
34
b091e954 35_equal_Q :: MalVal -> MalVal -> Bool
fa9a9758 36_equal_Q Nil Nil = True
6116c2d5 37_equal_Q (MalBoolean a) (MalBoolean b) = a == b
fa9a9758
JM
38_equal_Q (MalNumber a) (MalNumber b) = a == b
39_equal_Q (MalString a) (MalString b) = a == b
40_equal_Q (MalSymbol a) (MalSymbol b) = a == b
6116c2d5
NB
41_equal_Q (MalSeq _ _ a) (MalSeq _ _ b) = a == b
42_equal_Q (MalHashMap _ a) (MalHashMap _ b) = a == b
43_equal_Q (MalAtom _ a) (MalAtom _ b) = a == b
fa9a9758 44_equal_Q _ _ = False
b76aa73b 45
fa9a9758
JM
46instance Eq MalVal where
47 x == y = _equal_Q x y
b76aa73b 48
b76aa73b 49
5400d4bf
JM
50--- Errors/Exceptions ---
51
6116c2d5 52type IOThrows = ExceptT MalVal IO
5400d4bf 53
53db2d63 54throwStr :: String -> IOThrows a
6116c2d5 55throwStr = throwError . MalString
5400d4bf 56
fa9a9758
JM
57-- Env types --
58-- Note: Env functions are in Env module
6116c2d5 59type Env = [IORef (Map.Map String MalVal)]
fa9a9758 60
6116c2d5 61-- Convenient shortcuts for common situations.
c150ec41 62
6116c2d5
NB
63toList :: [MalVal] -> MalVal
64toList = MalSeq (MetaData Nil) (Vect False)
fa9a9758 65
6116c2d5
NB
66keyValuePairs :: [MalVal] -> Maybe [(String, MalVal)]
67keyValuePairs [] = pure []
68keyValuePairs (MalString k : v : kvs) = ((k, v) :) <$> keyValuePairs kvs
69keyValuePairs _ = Nothing