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