fsharp: step 4: Added list and comparison functions.
[jackhill/mal.git] / fsharp / printer.fs
CommitLineData
ed3a12f5
PS
1module Printer
2 open System.Text
3 open Reader
4 open Types
5
6 let pr_str data =
7 let acc = StringBuilder()
327bd967 8 let appendStr (str : string) = acc.Append(str) |> ignore
ed3a12f5 9 let rec pr_node = function
327bd967
PS
10 | Nil -> appendStr "nil"
11 | List(nodes) -> pr_list nodes
12 | Vector(nodes) -> pr_vector nodes
6dcc04db 13 | Map(map) -> pr_map map
327bd967
PS
14 | Symbol(symbol) -> appendStr symbol
15 | Keyword(keyword) -> appendStr ":"; appendStr keyword
ed3a12f5 16 | Number(num) -> acc.Append(num) |> ignore
327bd967
PS
17 | String(str) -> pr_str str
18 | Bool(true) -> appendStr "true"
19 | Bool(false) -> appendStr "false"
a836d8f3 20 | Func({ Tag = tag; F = _}) -> pr_func tag
ed3a12f5 21
327bd967
PS
22 and pr prefix node =
23 appendStr prefix
24 pr_node node
25 " "
3b82891f 26
327bd967
PS
27 and pr_str str =
28 let appendChar = function
29 | '\t' -> appendStr "\\t"
30 | '\b' -> appendStr "\\b"
31 | '\n' -> appendStr "\\n"
32 | '\r' -> appendStr "\\r"
33 | '\f' -> appendStr "\\f"
34 | '\'' -> appendStr "\\'"
35 | '"' -> appendStr "\\\""
36 | '\\' -> appendStr "\\\\"
37 | ch -> acc.Append(ch) |> ignore
38 appendStr "\""
39 str |> Seq.iter appendChar
40 appendStr "\""
41
a836d8f3
PS
42 and pr_func tag =
43 sprintf "#<func %d>" tag |> appendStr
8f1ee487 44
327bd967
PS
45 and pr_list nodes =
46 appendStr "("
47 nodes |> List.fold pr "" |> ignore
48 appendStr ")"
49
50 and pr_vector nodes =
51 appendStr "["
52 nodes |> Seq.fold pr "" |> ignore
53 appendStr "]"
6dcc04db
PS
54
55 and pr_map map =
327bd967
PS
56 let pr prefix key value =
57 appendStr prefix
6dcc04db 58 pr_node key
327bd967 59 appendStr " "
6dcc04db
PS
60 pr_node value
61 " "
327bd967
PS
62 appendStr "{"
63 map |> Map.fold pr "" |> ignore
64 appendStr "}"
ed3a12f5
PS
65
66 pr_node data
67 acc.ToString()