// Hoist all the argument evaluation up before the lock.
walkexprlistcheap(nn.List.Slice(), init)
- notfirst := false
- calls := []*Node{mkcall("printlock", nil, init)}
- for i, n := range nn.List.Slice() {
- if notfirst {
- calls = append(calls, mkcall("printsp", nil, init))
+ // For println, add " " between elements and "\n" at the end.
+ if nn.Op == OPRINTN {
+ s := nn.List.Slice()
+ t := make([]*Node, 0, len(s)*2)
+ for i, n := range s {
+ x := " "
+ if len(s)-1 == i {
+ x = "\n"
+ }
+ t = append(t, n, nodstr(x))
}
+ nn.List.Set(t)
+ }
- notfirst = nn.Op == OPRINTN
-
+ calls := []*Node{mkcall("printlock", nil, init)}
+ for i, n := range nn.List.Slice() {
if n.Op == OLITERAL {
switch n.Val().Ctype() {
case CTRUNE:
case TBOOL:
on = syslook("printbool")
case TSTRING:
- on = syslook("printstring")
+ cs := ""
+ if Isconst(n, CTSTR) {
+ cs = n.Val().U.(string)
+ }
+ switch cs {
+ case " ":
+ on = syslook("printsp")
+ case "\n":
+ on = syslook("printnl")
+ default:
+ on = syslook("printstring")
+ }
default:
badtype(OPRINT, n.Type, nil)
continue
}
- t := on.Type.Params().Field(0).Type
-
- if !eqtype(t, n.Type) {
- n = nod(OCONV, n, nil)
- n.Type = t
- }
-
r := nod(OCALL, on, nil)
- r.List.Append(n)
+ if params := on.Type.Params().FieldSlice(); len(params) > 0 {
+ t := params[0].Type
+ if !eqtype(t, n.Type) {
+ n = nod(OCONV, n, nil)
+ n.Type = t
+ }
+ r.List.Append(n)
+ }
calls = append(calls, r)
}
- if nn.Op == OPRINTN {
- calls = append(calls, mkcall("printnl", nil, nil))
- }
-
calls = append(calls, mkcall("printunlock", nil, init))
typecheckslice(calls, Etop)
// The compiler emits calls to printlock and printunlock around
// the multiple calls that implement a single Go print or println
-// statement. Some of the print helpers (printsp, for example)
+// statement. Some of the print helpers (printslice, for example)
// call print recursively. There is also the problem of a crash
// happening during the print routines and needing to acquire
// the print lock to print information about the crash.
}
func printsp() {
- print(" ")
+ printstring(" ")
}
func printnl() {
- print("\n")
+ printstring("\n")
}
func printbool(v bool) {
if v {
- print("true")
+ printstring("true")
} else {
- print("false")
+ printstring("false")
}
}
func printfloat(v float64) {
switch {
case v != v:
- print("NaN")
+ printstring("NaN")
return
case v+v == v && v > 0:
- print("+Inf")
+ printstring("+Inf")
return
case v+v == v && v < 0:
- print("-Inf")
+ printstring("-Inf")
return
}
func printint(v int64) {
if v < 0 {
- print("-")
+ printstring("-")
v = -v
}
printuint(uint64(v))