/
string.go
144 lines (133 loc) · 3.59 KB
/
string.go
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package expreduce
import "bytes"
import "github.com/cznic/wl"
type ToStringParams struct {
form string
context *String
contextPath *Expression
previousHead string
}
func needsParens(thisHead string, previousHead string) bool {
if previousHead == "<TOPLEVEL>" {
return false
}
prevToken, prevTokenOk := headsToTokens[previousHead]
thisToken, thisTokenOk := headsToTokens[thisHead]
if prevTokenOk && thisTokenOk {
prevPrec, prevPrecOk := wl.Precedence[prevToken]
thisPrec, thisPrecOk := wl.Precedence[thisToken]
if prevPrecOk && thisPrecOk {
if prevPrec < thisPrec {
return false
}
}
}
return true
}
func ToStringInfix(parts []Ex, delim string, thisHead string, p ToStringParams) (bool, string) {
if p.form != "InputForm" && p.form != "OutputForm" {
return false, ""
}
if len(parts) < 2 {
return false, ""
}
addParens := needsParens(thisHead, p.previousHead)
var buffer bytes.Buffer
if addParens {
buffer.WriteString("(")
}
nextParams := ToStringParams{
form: p.form,
context: p.context,
contextPath: p.contextPath,
previousHead: thisHead,
}
for i := 0; i < len(parts); i++ {
buffer.WriteString(parts[i].StringForm(nextParams))
if i != len(parts)-1 {
buffer.WriteString(delim)
}
}
if addParens {
buffer.WriteString(")")
}
return true, buffer.String()
}
func (this *Expression) ToStringInfix(p ToStringParams) (bool, string) {
if len(this.Parts) != 3 {
return false, ""
}
expr, isExpr := this.Parts[1].(*Expression)
delim, delimIsStr := this.Parts[2].(*String)
if !isExpr || !delimIsStr {
return false, ""
}
return ToStringInfix(expr.Parts[1:], delim.Val, "", p)
}
func ToStringInfixAdvanced(parts []Ex, delim string, thisHead string, surroundEachArg bool, start string, end string, params ToStringParams) (bool, string) {
if params.form != "InputForm" && params.form != "OutputForm" {
return false, ""
}
if len(parts) < 2 {
return false, ""
}
var buffer bytes.Buffer
addParens := needsParens(thisHead, params.previousHead)
if addParens {
buffer.WriteString("(")
}
if !surroundEachArg {
buffer.WriteString(start)
}
nextParams := ToStringParams{
form: params.form,
context: params.context,
contextPath: params.contextPath,
previousHead: thisHead,
}
for i := 0; i < len(parts); i++ {
if surroundEachArg {
buffer.WriteString("(")
buffer.WriteString(parts[i].StringForm(nextParams))
buffer.WriteString(")")
} else {
buffer.WriteString(parts[i].StringForm(nextParams))
}
if i != len(parts)-1 {
buffer.WriteString(delim)
}
}
if !surroundEachArg {
buffer.WriteString(end)
}
if addParens {
buffer.WriteString(")")
}
return true, buffer.String()
}
func DefaultStringFormArgs() (*String, *Expression) {
return NewString("Global`"), NewExpression([]Ex{
NewSymbol("System`List"),
NewString("System`"),
})
}
func DefinitionComplexityStringFormArgs() (*String, *Expression) {
// This was created because the "Private`" names in the blanks were
// indicating greater complexity than they deserved.
return NewString("Global`"), NewExpression([]Ex{
NewSymbol("System`List"),
NewString("System`"),
NewString("Private`"),
})
}
func ActualStringFormArgs(es *EvalState) (*String, *Expression) {
return NewString(es.GetStringDef("System`$Context", "Global`")), es.GetListDef("System`$ContextPath")
}
func ActualStringFormArgsFull(form string, es *EvalState) ToStringParams {
return ToStringParams{
form: form,
context: NewString(es.GetStringDef("System`$Context", "Global`")),
contextPath: es.GetListDef("System`$ContextPath"),
previousHead: "<TOPLEVEL>",
}
}