]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: implement fmt.Formatter for *Node formats %s, %v, %j
authorRobert Griesemer <gri@golang.org>
Tue, 30 Aug 2016 21:13:41 +0000 (14:13 -0700)
committerRobert Griesemer <gri@golang.org>
Thu, 8 Sep 2016 21:33:52 +0000 (21:33 +0000)
Change-Id: I44ee5843bb9dfd65b9a18091f365355e84888f21
Reviewed-on: https://go-review.googlesource.com/28330
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
src/cmd/compile/internal/gc/esc.go
src/cmd/compile/internal/gc/fmt.go

index 0fd514fbaf49e5d1c0219a8afd42f521ba9befd5..86d05d3db2cb8c23130eaf64aa51fae4fd1d3fe4 100644 (file)
@@ -998,10 +998,10 @@ func escassign(e *EscState, dst, src *Node, step *EscStep) {
        }
 
        if Debug['m'] > 2 {
-               fmt.Printf("%v:[%d] %v escassign: %v(%v)[%v] = %v(%v)[%v]\n",
+               fmt.Printf("%v:[%d] %v escassign: %v(%0j)[%v] = %v(%0j)[%v]\n",
                        linestr(lineno), e.loopdepth, funcSym(Curfn),
-                       Nconv(dst, FmtShort), jconv(dst, FmtShort), dst.Op,
-                       Nconv(src, FmtShort), jconv(src, FmtShort), src.Op)
+                       Nconv(dst, FmtShort), dst, dst.Op,
+                       Nconv(src, FmtShort), src, src.Op)
        }
 
        setlineno(dst)
@@ -1756,8 +1756,8 @@ func escwalkBody(e *EscState, level Level, dst *Node, src *Node, step *EscStep,
        }
 
        if Debug['m'] > 2 {
-               fmt.Printf("escwalk: level:%d depth:%d %.*s op=%v %v(%v) scope:%v[%d] extraloopdepth=%v\n",
-                       level, e.pdepth, e.pdepth, "\t\t\t\t\t\t\t\t\t\t", src.Op, Nconv(src, FmtShort), jconv(src, FmtShort), e.curfnSym(src), srcE.Escloopdepth, extraloopdepth)
+               fmt.Printf("escwalk: level:%d depth:%d %.*s op=%v %v(%0j) scope:%v[%d] extraloopdepth=%v\n",
+                       level, e.pdepth, e.pdepth, "\t\t\t\t\t\t\t\t\t\t", src.Op, Nconv(src, FmtShort), src, e.curfnSym(src), srcE.Escloopdepth, extraloopdepth)
        }
 
        e.pdepth++
index 8f8976c97cb5d948729f301c1a489f2d404ff7c8..816ccce1c208b152c0a5350a10e4e5ea4c8d06aa 100644 (file)
@@ -17,17 +17,48 @@ import (
 // See the respective function's documentation for details.
 type FmtFlag int
 
-const (
-       FmtLeft     FmtFlag = 1 << iota // "-"
-       FmtSharp                        // "#"
-       FmtSign                         // "+"
-       FmtUnsigned                     // "u"
-       FmtShort                        // "h"
-       FmtLong                         // "l"
-       FmtComma                        // ","
-       FmtByte                         // "hh"
+const ( //                                          fmt.Format flag/width/prec
+       FmtLeft     FmtFlag = 1 << iota // "-"  =>  '-'
+       FmtSharp                        // "#"  =>  '#'
+       FmtSign                         // "+"  =>  '+'
+       FmtUnsigned                     // "u"  =>  ' '
+       FmtShort                        // "h"  =>  hasWidth && width == 1
+       FmtLong                         // "l"  =>  hasWidth && width == 2
+       FmtComma                        // ","  =>  '.' (== hasPrec)
+       FmtByte                         // "hh" =>  '0'
 )
 
+func fmtFlag(s fmt.State) FmtFlag {
+       var flag FmtFlag
+       if s.Flag('-') {
+               flag |= FmtLeft
+       }
+       if s.Flag('#') {
+               flag |= FmtSharp
+       }
+       if s.Flag('+') {
+               flag |= FmtSign
+       }
+       if s.Flag(' ') {
+               flag |= FmtUnsigned
+       }
+       if w, ok := s.Width(); ok {
+               switch w {
+               case 1:
+                       flag |= FmtShort
+               case 2:
+                       flag |= FmtLong
+               }
+       }
+       if _, ok := s.Precision(); ok {
+               flag |= FmtComma
+       }
+       if s.Flag('0') {
+               flag |= FmtByte
+       }
+       return flag
+}
+
 //
 // Format conversions
 //     %L int          Line numbers
@@ -213,49 +244,60 @@ var classnames = []string{
        "PFUNC",
 }
 
-// Node details
-func jconv(n *Node, flag FmtFlag) string {
-       var p printer
+func (n *Node) Format(s fmt.State, format rune) {
+       switch format {
+       case 's', 'v':
+               fmt.Fprint(s, Nconv(n, fmtFlag(s)))
 
-       c := flag & FmtShort
+       case 'j':
+               n.jconv(s)
+
+       default:
+               fmt.Fprintf(s, "%%!%c(*Node=%p)", format, n)
+       }
+}
+
+// Node details
+func (n *Node) jconv(s fmt.State) {
+       c := fmtFlag(s) & FmtShort
 
        if c == 0 && n.Ullman != 0 {
-               p.f(" u(%d)", n.Ullman)
+               fmt.Fprintf(s, " u(%d)", n.Ullman)
        }
 
        if c == 0 && n.Addable {
-               p.f(" a(%v)", n.Addable)
+               fmt.Fprintf(s, " a(%v)", n.Addable)
        }
 
        if c == 0 && n.Name != nil && n.Name.Vargen != 0 {
-               p.f(" g(%d)", n.Name.Vargen)
+               fmt.Fprintf(s, " g(%d)", n.Name.Vargen)
        }
 
        if n.Lineno != 0 {
-               p.f(" l(%d)", n.Lineno)
+               fmt.Fprintf(s, " l(%d)", n.Lineno)
        }
 
        if c == 0 && n.Xoffset != BADWIDTH {
-               p.f(" x(%d%+d)", n.Xoffset, stkdelta[n])
+               fmt.Fprintf(s, " x(%d%+d)", n.Xoffset, stkdelta[n])
        }
 
        if n.Class != 0 {
                if int(n.Class) < len(classnames) {
-                       p.f(" class(%s)", classnames[n.Class])
+                       fmt.Fprintf(s, " class(%s)", classnames[n.Class])
                } else {
-                       p.f(" class(%d?)", n.Class)
+                       fmt.Fprintf(s, " class(%d?)", n.Class)
                }
        }
 
        if n.Colas {
-               p.f(" colas(%v)", n.Colas)
+               fmt.Fprintf(s, " colas(%v)", n.Colas)
        }
 
        if n.Name != nil && n.Name.Funcdepth != 0 {
-               p.f(" f(%d)", n.Name.Funcdepth)
+               fmt.Fprintf(s, " f(%d)", n.Name.Funcdepth)
        }
        if n.Func != nil && n.Func.Depth != 0 {
-               p.f(" ff(%d)", n.Func.Depth)
+               fmt.Fprintf(s, " ff(%d)", n.Func.Depth)
        }
 
        switch n.Esc {
@@ -263,66 +305,64 @@ func jconv(n *Node, flag FmtFlag) string {
                break
 
        case EscHeap:
-               p.s(" esc(h)")
+               fmt.Fprint(s, " esc(h)")
 
        case EscScope:
-               p.s(" esc(s)")
+               fmt.Fprint(s, " esc(s)")
 
        case EscNone:
-               p.s(" esc(no)")
+               fmt.Fprint(s, " esc(no)")
 
        case EscNever:
                if c == 0 {
-                       p.s(" esc(N)")
+                       fmt.Fprint(s, " esc(N)")
                }
 
        default:
-               p.f(" esc(%d)", n.Esc)
+               fmt.Fprintf(s, " esc(%d)", n.Esc)
        }
 
        if e, ok := n.Opt().(*NodeEscState); ok && e.Escloopdepth != 0 {
-               p.f(" ld(%d)", e.Escloopdepth)
+               fmt.Fprintf(s, " ld(%d)", e.Escloopdepth)
        }
 
        if c == 0 && n.Typecheck != 0 {
-               p.f(" tc(%d)", n.Typecheck)
+               fmt.Fprintf(s, " tc(%d)", n.Typecheck)
        }
 
        if c == 0 && n.IsStatic {
-               p.s(" static")
+               fmt.Fprint(s, " static")
        }
 
        if n.Isddd {
-               p.f(" isddd(%v)", n.Isddd)
+               fmt.Fprintf(s, " isddd(%v)", n.Isddd)
        }
 
        if n.Implicit {
-               p.f(" implicit(%v)", n.Implicit)
+               fmt.Fprintf(s, " implicit(%v)", n.Implicit)
        }
 
        if n.Embedded != 0 {
-               p.f(" embedded(%d)", n.Embedded)
+               fmt.Fprintf(s, " embedded(%d)", n.Embedded)
        }
 
        if n.Addrtaken {
-               p.s(" addrtaken")
+               fmt.Fprint(s, " addrtaken")
        }
 
        if n.Assigned {
-               p.s(" assigned")
+               fmt.Fprint(s, " assigned")
        }
        if n.Bounded {
-               p.s(" bounded")
+               fmt.Fprint(s, " bounded")
        }
        if n.NonNil {
-               p.s(" nonnil")
+               fmt.Fprint(s, " nonnil")
        }
 
        if c == 0 && n.Used {
-               p.f(" used(%v)", n.Used)
+               fmt.Fprintf(s, " used(%v)", n.Used)
        }
-
-       return p.String()
 }
 
 // Fmt "%V": Values
@@ -1404,19 +1444,19 @@ func (p *printer) nodedump(n *Node, flag FmtFlag) *printer {
 
        switch n.Op {
        default:
-               p.f("%v%v", n.Op, jconv(n, 0))
+               p.f("%v%j", n.Op, n)
 
        case OREGISTER, OINDREG:
-               p.f("%v-%v%v", n.Op, obj.Rconv(int(n.Reg)), jconv(n, 0))
+               p.f("%v-%v%j", n.Op, obj.Rconv(int(n.Reg)), n)
 
        case OLITERAL:
-               p.f("%v-%v%v", n.Op, vconv(n.Val(), 0), jconv(n, 0))
+               p.f("%v-%v%j", n.Op, vconv(n.Val(), 0), n)
 
        case ONAME, ONONAME:
                if n.Sym != nil {
-                       p.f("%v-%v%v", n.Op, n.Sym, jconv(n, 0))
+                       p.f("%v-%v%j", n.Op, n.Sym, n)
                } else {
-                       p.f("%v%v", n.Op, jconv(n, 0))
+                       p.f("%v%j", n.Op, n)
                }
                if recur && n.Type == nil && n.Name != nil && n.Name.Param != nil && n.Name.Param.Ntype != nil {
                        p.indent()
@@ -1424,10 +1464,10 @@ func (p *printer) nodedump(n *Node, flag FmtFlag) *printer {
                }
 
        case OASOP:
-               p.f("%v-%v%v", n.Op, Op(n.Etype), jconv(n, 0))
+               p.f("%v-%v%j", n.Op, Op(n.Etype), n)
 
        case OTYPE:
-               p.f("%v %v%v type=%v", n.Op, n.Sym, jconv(n, 0), n.Type)
+               p.f("%v %v%j type=%v", n.Op, n.Sym, n, n.Type)
                if recur && n.Type == nil && n.Name.Param.Ntype != nil {
                        p.indent()
                        p.f("%v-ntype%v", n.Op, n.Name.Param.Ntype)