Haskell: Add steps9-A, metadata, and atoms.
[jackhill/mal.git] / haskell / Printer.hs
1 module Printer
2 ( _pr_str, _pr_list )
3 where
4
5 import qualified Data.Map as Map
6 import Data.IORef (readIORef)
7 import System.IO.Unsafe (unsafePerformIO)
8
9 import Types
10
11 --concat (map (++ delim) list)
12 --join [] delim = []
13 --join (x:xs) delim = x ++ delim ++ join xs delim
14
15
16 _pr_list :: Bool -> String -> [MalVal] -> String
17 _pr_list pr sep [] = []
18 _pr_list pr sep (x:[]) = (_pr_str pr x)
19 _pr_list pr sep (x:xs) = (_pr_str pr x) ++ sep ++ (_pr_list pr sep xs)
20
21 _flatTuples ((a,b):xs) = MalString a : b : _flatTuples xs
22 _flatTuples _ = []
23
24 unescape chr = case chr of
25 '\n' -> "\\n"
26 '\\' -> "\\\\"
27 '"' -> "\\\""
28 c -> [c]
29
30 _pr_str :: Bool -> MalVal -> String
31 _pr_str _ (MalString ('\x029e':str)) = ":" ++ str
32 _pr_str True (MalString str) = "\"" ++ concatMap unescape str ++ "\""
33 _pr_str False (MalString str) = str
34 _pr_str _ (MalSymbol name) = name
35 _pr_str _ (MalNumber num) = show num
36 _pr_str _ (MalTrue) = "true"
37 _pr_str _ (MalFalse) = "false"
38 _pr_str _ (Nil) = "nil"
39 _pr_str pr (MalList items _) = "(" ++ (_pr_list pr " " items) ++ ")"
40 _pr_str pr (MalVector items _) = "[" ++ (_pr_list pr " " items) ++ "]"
41 _pr_str pr (MalHashMap m _) = "{" ++ (_pr_list pr " " (_flatTuples $ Map.assocs m)) ++ "}"
42 _pr_str pr (MalAtom r _) = "(atom " ++ (_pr_str pr (unsafePerformIO (readIORef r))) ++ ")"
43 _pr_str _ (Func f _) = "#<function>"
44 _pr_str _ (MalFunc {ast=ast, env=fn_env, params=params}) = "(fn* " ++ (show params) ++ " " ++ (show ast) ++ ")"
45
46 instance Show MalVal where show = _pr_str True
47