1
0
mirror of https://github.com/golang/go synced 2024-11-18 04:54:49 -07:00

cmd/compile: use fmt.State in exprfmt

Change-Id: If6c2d469c66a7aa8471bf54310354efdac3e0235
Reviewed-on: https://go-review.googlesource.com/28337
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
Robert Griesemer 2016-08-31 16:02:36 -07:00
parent ebdc8faf04
commit 0510f0dfe7

View File

@ -1139,13 +1139,14 @@ var opprec = []int{
OEND: 0, OEND: 0,
} }
func (p *printer) exprfmt(n *Node, prec int) *printer { func (n *Node) exprfmt(s fmt.State, prec int) {
for n != nil && n.Implicit && (n.Op == OIND || n.Op == OADDR) { for n != nil && n.Implicit && (n.Op == OIND || n.Op == OADDR) {
n = n.Left n = n.Left
} }
if n == nil { if n == nil {
return p.s("<N>") fmt.Fprint(s, "<N>")
return
} }
nprec := opprec[n.Op] nprec := opprec[n.Op]
@ -1154,186 +1155,234 @@ func (p *printer) exprfmt(n *Node, prec int) *printer {
} }
if prec > nprec { if prec > nprec {
return p.f("(%v)", n) fmt.Fprintf(s, "(%v)", n)
return
} }
switch n.Op { switch n.Op {
case OPAREN: case OPAREN:
return p.f("(%v)", n.Left) fmt.Fprintf(s, "(%v)", n.Left)
return
case ODDDARG: case ODDDARG:
return p.s("... argument") fmt.Fprint(s, "... argument")
return
case OREGISTER: case OREGISTER:
return p.s(obj.Rconv(int(n.Reg))) fmt.Fprint(s, obj.Rconv(int(n.Reg)))
return
case OLITERAL: // this is a bit of a mess case OLITERAL: // this is a bit of a mess
if fmtmode == FErr { if fmtmode == FErr {
if n.Orig != nil && n.Orig != n { if n.Orig != nil && n.Orig != n {
return p.exprfmt(n.Orig, prec) n.Orig.exprfmt(s, prec)
return
} }
if n.Sym != nil { if n.Sym != nil {
return p.s(n.Sym.String()) fmt.Fprint(s, n.Sym.String())
return
} }
} }
if n.Val().Ctype() == CTNIL && n.Orig != nil && n.Orig != n { if n.Val().Ctype() == CTNIL && n.Orig != nil && n.Orig != n {
return p.exprfmt(n.Orig, prec) n.Orig.exprfmt(s, prec)
return
} }
if n.Type != nil && n.Type.Etype != TIDEAL && n.Type.Etype != TNIL && n.Type != idealbool && n.Type != idealstring { if n.Type != nil && n.Type.Etype != TIDEAL && n.Type.Etype != TNIL && n.Type != idealbool && n.Type != idealstring {
// Need parens when type begins with what might // Need parens when type begins with what might
// be misinterpreted as a unary operator: * or <-. // be misinterpreted as a unary operator: * or <-.
if n.Type.IsPtr() || (n.Type.IsChan() && n.Type.ChanDir() == Crecv) { if n.Type.IsPtr() || (n.Type.IsChan() && n.Type.ChanDir() == Crecv) {
return p.f("(%v)(%v)", n.Type, n.Val()) fmt.Fprintf(s, "(%v)(%v)", n.Type, n.Val())
return
} else { } else {
return p.f("%v(%v)", n.Type, n.Val()) fmt.Fprintf(s, "%v(%v)", n.Type, n.Val())
return
} }
} }
return p.f("%s", n.Val()) fmt.Fprintf(s, "%s", n.Val())
return
// Special case: name used as local variable in export. // Special case: name used as local variable in export.
// _ becomes ~b%d internally; print as _ for export // _ becomes ~b%d internally; print as _ for export
case ONAME: case ONAME:
if fmtmode == FErr && n.Sym != nil && n.Sym.Name[0] == '~' && n.Sym.Name[1] == 'b' { if fmtmode == FErr && n.Sym != nil && n.Sym.Name[0] == '~' && n.Sym.Name[1] == 'b' {
return p.s("_") fmt.Fprint(s, "_")
return
} }
fallthrough fallthrough
case OPACK, ONONAME: case OPACK, ONONAME:
return p.s(n.Sym.String()) fmt.Fprint(s, n.Sym.String())
return
case OTYPE: case OTYPE:
if n.Type == nil && n.Sym != nil { if n.Type == nil && n.Sym != nil {
return p.s(n.Sym.String()) fmt.Fprint(s, n.Sym.String())
return
} }
return p.f("%v", n.Type) fmt.Fprintf(s, "%v", n.Type)
return
case OTARRAY: case OTARRAY:
if n.Left != nil { if n.Left != nil {
return p.f("[]%v", n.Left) fmt.Fprintf(s, "[]%v", n.Left)
return
} }
return p.f("[]%v", n.Right) // happens before typecheck fmt.Fprintf(s, "[]%v", n.Right) // happens before typecheck
return
case OTMAP: case OTMAP:
return p.f("map[%v]%v", n.Left, n.Right) fmt.Fprintf(s, "map[%v]%v", n.Left, n.Right)
return
case OTCHAN: case OTCHAN:
switch ChanDir(n.Etype) { switch ChanDir(n.Etype) {
case Crecv: case Crecv:
return p.f("<-chan %v", n.Left) fmt.Fprintf(s, "<-chan %v", n.Left)
return
case Csend: case Csend:
return p.f("chan<- %v", n.Left) fmt.Fprintf(s, "chan<- %v", n.Left)
return
default: default:
if n.Left != nil && n.Left.Op == OTCHAN && n.Left.Sym == nil && ChanDir(n.Left.Etype) == Crecv { if n.Left != nil && n.Left.Op == OTCHAN && n.Left.Sym == nil && ChanDir(n.Left.Etype) == Crecv {
return p.f("chan (%v)", n.Left) fmt.Fprintf(s, "chan (%v)", n.Left)
return
} else { } else {
return p.f("chan %v", n.Left) fmt.Fprintf(s, "chan %v", n.Left)
return
} }
} }
case OTSTRUCT: case OTSTRUCT:
return p.s("<struct>") fmt.Fprint(s, "<struct>")
return
case OTINTER: case OTINTER:
return p.s("<inter>") fmt.Fprint(s, "<inter>")
return
case OTFUNC: case OTFUNC:
return p.s("<func>") fmt.Fprint(s, "<func>")
return
case OCLOSURE: case OCLOSURE:
if fmtmode == FErr { if fmtmode == FErr {
return p.s("func literal") fmt.Fprint(s, "func literal")
return
} }
if n.Nbody.Len() != 0 { if n.Nbody.Len() != 0 {
return p.f("%v { %v }", n.Type, n.Nbody) fmt.Fprintf(s, "%v { %v }", n.Type, n.Nbody)
return
} }
return p.f("%v { %v }", n.Type, n.Func.Closure.Nbody) fmt.Fprintf(s, "%v { %v }", n.Type, n.Func.Closure.Nbody)
return
case OCOMPLIT: case OCOMPLIT:
ptrlit := n.Right != nil && n.Right.Implicit && n.Right.Type != nil && n.Right.Type.IsPtr() ptrlit := n.Right != nil && n.Right.Implicit && n.Right.Type != nil && n.Right.Type.IsPtr()
if fmtmode == FErr { if fmtmode == FErr {
if n.Right != nil && n.Right.Type != nil && !n.Implicit { if n.Right != nil && n.Right.Type != nil && !n.Implicit {
if ptrlit { if ptrlit {
return p.f("&%v literal", n.Right.Type.Elem()) fmt.Fprintf(s, "&%v literal", n.Right.Type.Elem())
return
} else { } else {
return p.f("%v literal", n.Right.Type) fmt.Fprintf(s, "%v literal", n.Right.Type)
return
} }
} }
return p.s("composite literal") fmt.Fprint(s, "composite literal")
return
} }
return p.f("(%v{ %v })", n.Right, hconv(n.List, FmtComma)) fmt.Fprintf(s, "(%v{ %v })", n.Right, hconv(n.List, FmtComma))
return
case OPTRLIT: case OPTRLIT:
return p.f("&%v", n.Left) fmt.Fprintf(s, "&%v", n.Left)
return
case OSTRUCTLIT, OARRAYLIT, OSLICELIT, OMAPLIT: case OSTRUCTLIT, OARRAYLIT, OSLICELIT, OMAPLIT:
if fmtmode == FErr { if fmtmode == FErr {
return p.f("%v literal", n.Type) fmt.Fprintf(s, "%v literal", n.Type)
return
} }
return p.f("(%v{ %v })", n.Type, hconv(n.List, FmtComma)) fmt.Fprintf(s, "(%v{ %v })", n.Type, hconv(n.List, FmtComma))
return
case OKEY: case OKEY:
if n.Left != nil && n.Right != nil { if n.Left != nil && n.Right != nil {
return p.f("%v:%v", n.Left, n.Right) fmt.Fprintf(s, "%v:%v", n.Left, n.Right)
return
} }
if n.Left == nil && n.Right != nil { if n.Left == nil && n.Right != nil {
return p.f(":%v", n.Right) fmt.Fprintf(s, ":%v", n.Right)
return
} }
if n.Left != nil && n.Right == nil { if n.Left != nil && n.Right == nil {
return p.f("%v:", n.Left) fmt.Fprintf(s, "%v:", n.Left)
return
} }
return p.s(":") fmt.Fprint(s, ":")
return
case OCALLPART: case OCALLPART:
p.exprfmt(n.Left, nprec) n.Left.exprfmt(s, nprec)
if n.Right == nil || n.Right.Sym == nil { if n.Right == nil || n.Right.Sym == nil {
return p.s(".<nil>") fmt.Fprint(s, ".<nil>")
return
} }
return p.f(".%01v", n.Right.Sym) fmt.Fprintf(s, ".%01v", n.Right.Sym)
return
case OXDOT, ODOT, ODOTPTR, ODOTINTER, ODOTMETH: case OXDOT, ODOT, ODOTPTR, ODOTINTER, ODOTMETH:
p.exprfmt(n.Left, nprec) n.Left.exprfmt(s, nprec)
if n.Sym == nil { if n.Sym == nil {
return p.s(".<nil>") fmt.Fprint(s, ".<nil>")
return
} }
return p.f(".%01v", n.Sym) fmt.Fprintf(s, ".%01v", n.Sym)
return
case ODOTTYPE, ODOTTYPE2: case ODOTTYPE, ODOTTYPE2:
p.exprfmt(n.Left, nprec) n.Left.exprfmt(s, nprec)
if n.Right != nil { if n.Right != nil {
return p.f(".(%v)", n.Right) fmt.Fprintf(s, ".(%v)", n.Right)
return
} }
return p.f(".(%v)", n.Type) fmt.Fprintf(s, ".(%v)", n.Type)
return
case OINDEX, OINDEXMAP: case OINDEX, OINDEXMAP:
return p.exprfmt(n.Left, nprec).f("[%v]", n.Right) n.Left.exprfmt(s, nprec)
fmt.Fprintf(s, "[%v]", n.Right)
return
case OSLICE, OSLICESTR, OSLICEARR, OSLICE3, OSLICE3ARR: case OSLICE, OSLICESTR, OSLICEARR, OSLICE3, OSLICE3ARR:
p.exprfmt(n.Left, nprec) n.Left.exprfmt(s, nprec)
p.s("[") fmt.Fprint(s, "[")
low, high, max := n.SliceBounds() low, high, max := n.SliceBounds()
if low != nil { if low != nil {
p.s(low.String()) fmt.Fprint(s, low.String())
} }
p.s(":") fmt.Fprint(s, ":")
if high != nil { if high != nil {
p.s(high.String()) fmt.Fprint(s, high.String())
} }
if n.Op.IsSlice3() { if n.Op.IsSlice3() {
p.s(":") fmt.Fprint(s, ":")
if max != nil { if max != nil {
p.s(max.String()) fmt.Fprint(s, max.String())
} }
} }
return p.s("]") fmt.Fprint(s, "]")
return
case OCOPY, OCOMPLEX: case OCOPY, OCOMPLEX:
return p.f("%#v(%v, %v)", n.Op, n.Left, n.Right) fmt.Fprintf(s, "%#v(%v, %v)", n.Op, n.Left, n.Right)
return
case OCONV, case OCONV,
OCONVIFACE, OCONVIFACE,
@ -1344,12 +1393,15 @@ func (p *printer) exprfmt(n *Node, prec int) *printer {
OSTRARRAYRUNE, OSTRARRAYRUNE,
ORUNESTR: ORUNESTR:
if n.Type == nil || n.Type.Sym == nil { if n.Type == nil || n.Type.Sym == nil {
return p.f("(%v)(%v)", n.Type, n.Left) fmt.Fprintf(s, "(%v)(%v)", n.Type, n.Left)
return
} }
if n.Left != nil { if n.Left != nil {
return p.f("%v(%v)", n.Type, n.Left) fmt.Fprintf(s, "%v(%v)", n.Type, n.Left)
return
} }
return p.f("%v(%v)", n.Type, hconv(n.List, FmtComma)) fmt.Fprintf(s, "%v(%v)", n.Type, hconv(n.List, FmtComma))
return
case OREAL, case OREAL,
OIMAG, OIMAG,
@ -1365,31 +1417,40 @@ func (p *printer) exprfmt(n *Node, prec int) *printer {
OPRINT, OPRINT,
OPRINTN: OPRINTN:
if n.Left != nil { if n.Left != nil {
return p.f("%#v(%v)", n.Op, n.Left) fmt.Fprintf(s, "%#v(%v)", n.Op, n.Left)
return
} }
if n.Isddd { if n.Isddd {
return p.f("%#v(%v...)", n.Op, hconv(n.List, FmtComma)) fmt.Fprintf(s, "%#v(%v...)", n.Op, hconv(n.List, FmtComma))
return
} }
return p.f("%#v(%v)", n.Op, hconv(n.List, FmtComma)) fmt.Fprintf(s, "%#v(%v)", n.Op, hconv(n.List, FmtComma))
return
case OCALL, OCALLFUNC, OCALLINTER, OCALLMETH, OGETG: case OCALL, OCALLFUNC, OCALLINTER, OCALLMETH, OGETG:
p.exprfmt(n.Left, nprec) n.Left.exprfmt(s, nprec)
if n.Isddd { if n.Isddd {
return p.f("(%v...)", hconv(n.List, FmtComma)) fmt.Fprintf(s, "(%v...)", hconv(n.List, FmtComma))
return
} }
return p.f("(%v)", hconv(n.List, FmtComma)) fmt.Fprintf(s, "(%v)", hconv(n.List, FmtComma))
return
case OMAKEMAP, OMAKECHAN, OMAKESLICE: case OMAKEMAP, OMAKECHAN, OMAKESLICE:
if n.List.Len() != 0 { // pre-typecheck if n.List.Len() != 0 { // pre-typecheck
return p.f("make(%v, %v)", n.Type, hconv(n.List, FmtComma)) fmt.Fprintf(s, "make(%v, %v)", n.Type, hconv(n.List, FmtComma))
return
} }
if n.Right != nil { if n.Right != nil {
return p.f("make(%v, %v, %v)", n.Type, n.Left, n.Right) fmt.Fprintf(s, "make(%v, %v, %v)", n.Type, n.Left, n.Right)
return
} }
if n.Left != nil && (n.Op == OMAKESLICE || !n.Left.Type.IsUntyped()) { if n.Left != nil && (n.Op == OMAKESLICE || !n.Left.Type.IsUntyped()) {
return p.f("make(%v, %v)", n.Type, n.Left) fmt.Fprintf(s, "make(%v, %v)", n.Type, n.Left)
return
} }
return p.f("make(%v)", n.Type) fmt.Fprintf(s, "make(%v)", n.Type)
return
// Unary // Unary
case OPLUS, case OPLUS,
@ -1399,11 +1460,12 @@ func (p *printer) exprfmt(n *Node, prec int) *printer {
OIND, OIND,
ONOT, ONOT,
ORECV: ORECV:
p.s(n.Op.GoString()) // %#v fmt.Fprint(s, n.Op.GoString()) // %#v
if n.Left.Op == n.Op { if n.Left.Op == n.Op {
p.s(" ") fmt.Fprint(s, " ")
} }
return p.exprfmt(n.Left, nprec+1) n.Left.exprfmt(s, nprec+1)
return
// Binary // Binary
case OADD, case OADD,
@ -1426,31 +1488,31 @@ func (p *printer) exprfmt(n *Node, prec int) *printer {
OSEND, OSEND,
OSUB, OSUB,
OXOR: OXOR:
p.exprfmt(n.Left, nprec) n.Left.exprfmt(s, nprec)
p.f(" %#v ", n.Op) fmt.Fprintf(s, " %#v ", n.Op)
p.exprfmt(n.Right, nprec+1) n.Right.exprfmt(s, nprec+1)
return p return
case OADDSTR: case OADDSTR:
i := 0 i := 0
for _, n1 := range n.List.Slice() { for _, n1 := range n.List.Slice() {
if i != 0 { if i != 0 {
p.s(" + ") fmt.Fprint(s, " + ")
} }
p.exprfmt(n1, nprec) n1.exprfmt(s, nprec)
i++ i++
} }
return p return
case OCMPSTR, OCMPIFACE: case OCMPSTR, OCMPIFACE:
p.exprfmt(n.Left, nprec) n.Left.exprfmt(s, nprec)
// TODO(marvin): Fix Node.EType type union. // TODO(marvin): Fix Node.EType type union.
p.f(" %#v ", Op(n.Etype)) fmt.Fprintf(s, " %#v ", Op(n.Etype))
p.exprfmt(n.Right, nprec+1) n.Right.exprfmt(s, nprec+1)
return p return
} }
return p.f("<node %v>", n.Op) fmt.Fprintf(s, "<node %v>", n.Op)
} }
func (n *Node) nodefmt(s fmt.State, flag FmtFlag) { func (n *Node) nodefmt(s fmt.State, flag FmtFlag) {
@ -1479,7 +1541,7 @@ func (n *Node) nodefmt(s fmt.State, flag FmtFlag) {
return return
} }
fmt.Fprint(s, new(printer).exprfmt(n, 0).String()) n.exprfmt(s, 0)
} }
func (p *printer) nodedump(n *Node, flag FmtFlag) *printer { func (p *printer) nodedump(n *Node, flag FmtFlag) *printer {