Ensure assoc updates maps properly
[jackhill/mal.git] / swift3 / Sources / printer.swift
1
2 func pr_str(_ obj: MalVal, _ print_readably: Bool = true) -> String {
3 switch obj {
4 case MalVal.MalList(let lst, _):
5 let elems = lst.map { pr_str($0, print_readably) }
6 return "(" + elems.joined(separator: " ") + ")"
7 case MalVal.MalVector(let lst, _):
8 let elems = lst.map { pr_str($0, print_readably) }
9 return "[" + elems.joined(separator: " ") + "]"
10 case MalVal.MalHashMap(let dict, _):
11 let elems = dict.map {
12 pr_str(MalVal.MalString($0), print_readably) +
13 " " + pr_str($1, print_readably)
14 }
15 return "{" + elems.joined(separator: " ") + "}"
16 case MalVal.MalString(let str):
17 //print("kw: '\(str[str.startIndex])'")
18 if str.characters.count > 0 && str[str.startIndex] == "\u{029e}" {
19 return ":" + str[str.index(after: str.startIndex)..<str.endIndex]
20 } else if print_readably {
21 let s1 = str.replacingOccurrences(of: "\\", with: "\\\\")
22 let s2 = s1.replacingOccurrences(of: "\"", with: "\\\"")
23 let s3 = s2.replacingOccurrences(of: "\n", with: "\\n")
24 return "\"" + s3 + "\""
25 } else {
26 return str
27 }
28 case MalVal.MalSymbol(let str):
29 return str
30 case MalVal.MalInt(let i): return String(i)
31 case MalVal.MalNil: return "nil"
32 case MalVal.MalFalse: return "false"
33 case MalVal.MalTrue: return "true"
34 case MalVal.MalFunc(_, nil, _, _, _, _):
35 return "#<native function>"
36 case MalVal.MalFunc(_, let ast, _, let params, _, _):
37 return "(fn* \(pr_str(params![0])) \(pr_str(ast![0])))"
38 case MalVal.MalAtom(let ma):
39 return "(atom \(pr_str(ma.val, print_readably)))"
40 default:
41 return String(describing:obj)
42 }
43 }