Commit adcd34c7 authored by Robert Griesemer's avatar Robert Griesemer

cmd/compile: implement fmt.Formatter for *Node formats %s, %v, %j

Change-Id: I44ee5843bb9dfd65b9a18091f365355e84888f21
Reviewed-on: https://go-review.googlesource.com/28330Reviewed-by: default avatarMatthew Dempsky <mdempsky@google.com>
parent b6948ce7
...@@ -998,10 +998,10 @@ func escassign(e *EscState, dst, src *Node, step *EscStep) { ...@@ -998,10 +998,10 @@ func escassign(e *EscState, dst, src *Node, step *EscStep) {
} }
if Debug['m'] > 2 { 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), linestr(lineno), e.loopdepth, funcSym(Curfn),
Nconv(dst, FmtShort), jconv(dst, FmtShort), dst.Op, Nconv(dst, FmtShort), dst, dst.Op,
Nconv(src, FmtShort), jconv(src, FmtShort), src.Op) Nconv(src, FmtShort), src, src.Op)
} }
setlineno(dst) setlineno(dst)
...@@ -1756,8 +1756,8 @@ func escwalkBody(e *EscState, level Level, dst *Node, src *Node, step *EscStep, ...@@ -1756,8 +1756,8 @@ func escwalkBody(e *EscState, level Level, dst *Node, src *Node, step *EscStep,
} }
if Debug['m'] > 2 { if Debug['m'] > 2 {
fmt.Printf("escwalk: level:%d depth:%d %.*s op=%v %v(%v) scope:%v[%d] extraloopdepth=%v\n", 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), jconv(src, FmtShort), e.curfnSym(src), srcE.Escloopdepth, extraloopdepth) 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++ e.pdepth++
......
...@@ -17,17 +17,48 @@ import ( ...@@ -17,17 +17,48 @@ import (
// See the respective function's documentation for details. // See the respective function's documentation for details.
type FmtFlag int type FmtFlag int
const ( const ( // fmt.Format flag/width/prec
FmtLeft FmtFlag = 1 << iota // "-" FmtLeft FmtFlag = 1 << iota // "-" => '-'
FmtSharp // "#" FmtSharp // "#" => '#'
FmtSign // "+" FmtSign // "+" => '+'
FmtUnsigned // "u" FmtUnsigned // "u" => ' '
FmtShort // "h" FmtShort // "h" => hasWidth && width == 1
FmtLong // "l" FmtLong // "l" => hasWidth && width == 2
FmtComma // "," FmtComma // "," => '.' (== hasPrec)
FmtByte // "hh" 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 // Format conversions
// %L int Line numbers // %L int Line numbers
...@@ -213,49 +244,60 @@ var classnames = []string{ ...@@ -213,49 +244,60 @@ var classnames = []string{
"PFUNC", "PFUNC",
} }
// Node details func (n *Node) Format(s fmt.State, format rune) {
func jconv(n *Node, flag FmtFlag) string { switch format {
var p printer 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 { if c == 0 && n.Ullman != 0 {
p.f(" u(%d)", n.Ullman) fmt.Fprintf(s, " u(%d)", n.Ullman)
} }
if c == 0 && n.Addable { 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 { 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 { if n.Lineno != 0 {
p.f(" l(%d)", n.Lineno) fmt.Fprintf(s, " l(%d)", n.Lineno)
} }
if c == 0 && n.Xoffset != BADWIDTH { 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 n.Class != 0 {
if int(n.Class) < len(classnames) { if int(n.Class) < len(classnames) {
p.f(" class(%s)", classnames[n.Class]) fmt.Fprintf(s, " class(%s)", classnames[n.Class])
} else { } else {
p.f(" class(%d?)", n.Class) fmt.Fprintf(s, " class(%d?)", n.Class)
} }
} }
if n.Colas { if n.Colas {
p.f(" colas(%v)", n.Colas) fmt.Fprintf(s, " colas(%v)", n.Colas)
} }
if n.Name != nil && n.Name.Funcdepth != 0 { 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 { 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 { switch n.Esc {
...@@ -263,66 +305,64 @@ func jconv(n *Node, flag FmtFlag) string { ...@@ -263,66 +305,64 @@ func jconv(n *Node, flag FmtFlag) string {
break break
case EscHeap: case EscHeap:
p.s(" esc(h)") fmt.Fprint(s, " esc(h)")
case EscScope: case EscScope:
p.s(" esc(s)") fmt.Fprint(s, " esc(s)")
case EscNone: case EscNone:
p.s(" esc(no)") fmt.Fprint(s, " esc(no)")
case EscNever: case EscNever:
if c == 0 { if c == 0 {
p.s(" esc(N)") fmt.Fprint(s, " esc(N)")
} }
default: default:
p.f(" esc(%d)", n.Esc) fmt.Fprintf(s, " esc(%d)", n.Esc)
} }
if e, ok := n.Opt().(*NodeEscState); ok && e.Escloopdepth != 0 { 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 { if c == 0 && n.Typecheck != 0 {
p.f(" tc(%d)", n.Typecheck) fmt.Fprintf(s, " tc(%d)", n.Typecheck)
} }
if c == 0 && n.IsStatic { if c == 0 && n.IsStatic {
p.s(" static") fmt.Fprint(s, " static")
} }
if n.Isddd { if n.Isddd {
p.f(" isddd(%v)", n.Isddd) fmt.Fprintf(s, " isddd(%v)", n.Isddd)
} }
if n.Implicit { if n.Implicit {
p.f(" implicit(%v)", n.Implicit) fmt.Fprintf(s, " implicit(%v)", n.Implicit)
} }
if n.Embedded != 0 { if n.Embedded != 0 {
p.f(" embedded(%d)", n.Embedded) fmt.Fprintf(s, " embedded(%d)", n.Embedded)
} }
if n.Addrtaken { if n.Addrtaken {
p.s(" addrtaken") fmt.Fprint(s, " addrtaken")
} }
if n.Assigned { if n.Assigned {
p.s(" assigned") fmt.Fprint(s, " assigned")
} }
if n.Bounded { if n.Bounded {
p.s(" bounded") fmt.Fprint(s, " bounded")
} }
if n.NonNil { if n.NonNil {
p.s(" nonnil") fmt.Fprint(s, " nonnil")
} }
if c == 0 && n.Used { if c == 0 && n.Used {
p.f(" used(%v)", n.Used) fmt.Fprintf(s, " used(%v)", n.Used)
} }
return p.String()
} }
// Fmt "%V": Values // Fmt "%V": Values
...@@ -1404,19 +1444,19 @@ func (p *printer) nodedump(n *Node, flag FmtFlag) *printer { ...@@ -1404,19 +1444,19 @@ func (p *printer) nodedump(n *Node, flag FmtFlag) *printer {
switch n.Op { switch n.Op {
default: default:
p.f("%v%v", n.Op, jconv(n, 0)) p.f("%v%j", n.Op, n)
case OREGISTER, OINDREG: 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: 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: case ONAME, ONONAME:
if n.Sym != nil { 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 { } 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 { if recur && n.Type == nil && n.Name != nil && n.Name.Param != nil && n.Name.Param.Ntype != nil {
p.indent() p.indent()
...@@ -1424,10 +1464,10 @@ func (p *printer) nodedump(n *Node, flag FmtFlag) *printer { ...@@ -1424,10 +1464,10 @@ func (p *printer) nodedump(n *Node, flag FmtFlag) *printer {
} }
case OASOP: 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: 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 { if recur && n.Type == nil && n.Name.Param.Ntype != nil {
p.indent() p.indent()
p.f("%v-ntype%v", n.Op, n.Name.Param.Ntype) p.f("%v-ntype%v", n.Op, n.Name.Param.Ntype)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment