aboutsummaryrefslogtreecommitdiff
path: root/go/src/printer/printer.go
blob: 016e65f8d8ea92c72436d0423ee493916ca30601 (plain)
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)
	}
}