DISABLE FDs (REMOVE ME).
[jackhill/mal.git] / haskell / Printer.hs
CommitLineData
b76aa73b 1module Printer
fa9a9758 2( _pr_str, _pr_list )
b76aa73b
JM
3where
4
5import qualified Data.Map as Map
c150ec41 6import Data.IORef (readIORef)
b76aa73b
JM
7
8import Types
9
87cb47ec
NB
10_pr_list :: Bool -> String -> [MalVal] -> IO String
11_pr_list _ _ [] = return $ []
6116c2d5 12_pr_list pr _ [x] = _pr_str pr x
87cb47ec
NB
13_pr_list pr sep (x:xs) = format <$> _pr_str pr x <*> _pr_list pr sep xs where
14 format l r = l ++ sep ++ r
b76aa73b 15
b091e954 16_flatTuples :: [(String, MalVal)] -> [MalVal]
b76aa73b
JM
17_flatTuples ((a,b):xs) = MalString a : b : _flatTuples xs
18_flatTuples _ = []
19
b091e954 20unescape :: Char -> String
6116c2d5
NB
21unescape '\n' = "\\n"
22unescape '\\' = "\\\\"
23unescape '"' = "\\\""
24unescape c = [c]
b76aa73b 25
87cb47ec
NB
26_pr_str :: Bool -> MalVal -> IO String
27_pr_str _ (MalString (c : cs)) | c == keywordMagic
28 = return $ ':' : cs
29_pr_str True (MalString str) = return $ "\"" ++ concatMap unescape str ++ "\""
30_pr_str False (MalString str) = return str
31_pr_str _ (MalSymbol name) = return name
32_pr_str _ (MalNumber num) = return $ show num
33_pr_str _ (MalBoolean True) = return "true"
34_pr_str _ (MalBoolean False) = return $ "false"
35_pr_str _ Nil = return "nil"
36_pr_str pr (MalSeq _ (Vect False) items) = format <$> _pr_list pr " " items where
37 format x = "(" ++ x ++ ")"
38_pr_str pr (MalSeq _ (Vect True) items) = format <$> _pr_list pr " " items where
39 format x = "[" ++ x ++ "]"
40_pr_str pr (MalHashMap _ m) = format <$> _pr_list pr " " (_flatTuples $ Map.assocs m) where
41 format x = "{" ++ x ++ "}"
42_pr_str pr (MalAtom _ r) = format <$> (_pr_str pr =<< readIORef r) where
43 format x = "(atom " ++ x ++ ")"
44_pr_str _ (MalFunction {f_ast=Nil}) = pure "#<function>"
45_pr_str _ (MalFunction {f_ast=a, f_params=p, macro=False}) = format <$> _pr_str True a where
46 format x = "(fn* " ++ show p ++ " -> " ++ x ++ ")"
47_pr_str _ (MalFunction {f_ast=a, f_params=p, macro=True}) = format <$> _pr_str True a where
48 format x = "(macro* " ++ show p ++ " -> " ++ x ++ ")"