1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
package printer
import (
"fmt"
"strings"
)
import (
"types"
)
func Pr_list(lst []types.MalType, pr bool,
start string, end string, join string) string {
str_list := make([]string, 0, len(lst))
for _, e := range lst {
str_list = append(str_list, Pr_str(e, pr))
}
return start + strings.Join(str_list, join) + end
}
func Pr_str(obj types.MalType, print_readably bool) string {
switch tobj := obj.(type) {
case types.List:
return Pr_list(tobj.Val, print_readably, "(", ")", " ")
case types.Vector:
return Pr_list(tobj.Val, print_readably, "[", "]", " ")
case types.HashMap:
str_list := make([]string, 0, len(tobj.Val)*2)
for k, v := range tobj.Val {
str_list = append(str_list, Pr_str(k, print_readably))
str_list = append(str_list, Pr_str(v, print_readably))
}
return "{" + strings.Join(str_list, " ") + "}"
case string:
if strings.HasPrefix(tobj, "\u029e") {
return ":" + tobj[2:len(tobj)]
} else if print_readably {
return `"` + strings.Replace(
strings.Replace(
strings.Replace(tobj,`\`,`\\`, -1),
`"`, `\"`, -1),
"\n", `\n`, -1) + `"`
} else {
return tobj
}
case types.Symbol:
return tobj.Val
case nil:
return "nil"
case types.MalFunc:
return "(fn* " +
Pr_str(tobj.Params, true) + " " +
Pr_str(tobj.Exp, true) + ")"
case func([]types.MalType)(types.MalType, error):
return fmt.Sprintf("<function %v>", obj)
case *types.Atom:
return "(atom " +
Pr_str(tobj.Val, true) + ")"
default:
return fmt.Sprintf("%v", obj)
}
}
|