fsharp: step 4: Added list and comparison functions.
[jackhill/mal.git] / fsharp / printer.fs
... / ...
CommitLineData
1module Printer
2 open System.Text
3 open Reader
4 open Types
5
6 let pr_str data =
7 let acc = StringBuilder()
8 let appendStr (str : string) = acc.Append(str) |> ignore
9 let rec pr_node = function
10 | Nil -> appendStr "nil"
11 | List(nodes) -> pr_list nodes
12 | Vector(nodes) -> pr_vector nodes
13 | Map(map) -> pr_map map
14 | Symbol(symbol) -> appendStr symbol
15 | Keyword(keyword) -> appendStr ":"; appendStr keyword
16 | Number(num) -> acc.Append(num) |> ignore
17 | String(str) -> pr_str str
18 | Bool(true) -> appendStr "true"
19 | Bool(false) -> appendStr "false"
20 | Func({ Tag = tag; F = _}) -> pr_func tag
21
22 and pr prefix node =
23 appendStr prefix
24 pr_node node
25 " "
26
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
42 and pr_func tag =
43 sprintf "#<func %d>" tag |> appendStr
44
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 "]"
54
55 and pr_map map =
56 let pr prefix key value =
57 appendStr prefix
58 pr_node key
59 appendStr " "
60 pr_node value
61 " "
62 appendStr "{"
63 map |> Map.fold pr "" |> ignore
64 appendStr "}"
65
66 pr_node data
67 acc.ToString()