Commit 97ba3c82 authored by Robert Griesemer's avatar Robert Griesemer

cmd/compile: implement fmt.Formatter for Val formats %s, %v

Change-Id: Id56e886793161b48b445439e9a12109142064d3f
Reviewed-on: https://go-review.googlesource.com/28332Reviewed-by: default avatarMatthew Dempsky <mdempsky@google.com>
parent 9e1f6a32
...@@ -556,7 +556,7 @@ func overflow(v Val, t *Type) { ...@@ -556,7 +556,7 @@ func overflow(v Val, t *Type) {
} }
if doesoverflow(v, t) { if doesoverflow(v, t) {
Yyerror("constant %s overflows %v", vconv(v, 0), t) Yyerror("constant %s overflows %v", v, t)
} }
} }
......
...@@ -382,7 +382,7 @@ func dumpasmhdr() { ...@@ -382,7 +382,7 @@ func dumpasmhdr() {
} }
switch n.Op { switch n.Op {
case OLITERAL: case OLITERAL:
fmt.Fprintf(b, "#define const_%s %v\n", n.Sym.Name, vconv(n.Val(), FmtSharp)) fmt.Fprintf(b, "#define const_%s %#v\n", n.Sym.Name, n.Val())
case OTYPE: case OTYPE:
t := n.Type t := n.Type
......
...@@ -378,74 +378,87 @@ func (n *Node) jconv(s fmt.State) { ...@@ -378,74 +378,87 @@ func (n *Node) jconv(s fmt.State) {
} }
} }
func (v Val) Format(s fmt.State, format rune) {
switch format {
case 's', 'v':
v.vconv(s)
default:
fmt.Fprintf(s, "%%!%c(Val)", format)
}
}
// Fmt "%V": Values // Fmt "%V": Values
func vconv(v Val, flag FmtFlag) string { func (v Val) vconv(s fmt.State) {
var p printer flag := fmtFlag(s)
switch u := v.U.(type) { switch u := v.U.(type) {
case *Mpint: case *Mpint:
if !u.Rune { if !u.Rune {
if flag&FmtSharp != 0 { if flag&FmtSharp != 0 {
return bconv(u, FmtSharp) fmt.Fprint(s, bconv(u, FmtSharp))
return
} }
return bconv(u, 0) fmt.Fprint(s, bconv(u, 0))
return
} }
switch x := u.Int64(); { switch x := u.Int64(); {
case ' ' <= x && x < utf8.RuneSelf && x != '\\' && x != '\'': case ' ' <= x && x < utf8.RuneSelf && x != '\\' && x != '\'':
p.f("'%c'", int(x)) fmt.Fprintf(s, "'%c'", int(x))
case 0 <= x && x < 1<<16: case 0 <= x && x < 1<<16:
p.f("'\\u%04x'", uint(int(x))) fmt.Fprintf(s, "'\\u%04x'", uint(int(x)))
case 0 <= x && x <= utf8.MaxRune: case 0 <= x && x <= utf8.MaxRune:
p.f("'\\U%08x'", uint64(x)) fmt.Fprintf(s, "'\\U%08x'", uint64(x))
default: default:
p.f("('\\x00' + %v)", u) fmt.Fprintf(s, "('\\x00' + %v)", u)
} }
case *Mpflt: case *Mpflt:
if flag&FmtSharp != 0 { if flag&FmtSharp != 0 {
return fconv(u, 0) fmt.Fprint(s, fconv(u, 0))
return
} }
return fconv(u, FmtSharp) fmt.Fprint(s, fconv(u, FmtSharp))
return
case *Mpcplx: case *Mpcplx:
switch { switch {
case flag&FmtSharp != 0: case flag&FmtSharp != 0:
p.f("(%v+%vi)", &u.Real, &u.Imag) fmt.Fprintf(s, "(%v+%vi)", &u.Real, &u.Imag)
case v.U.(*Mpcplx).Real.CmpFloat64(0) == 0: case v.U.(*Mpcplx).Real.CmpFloat64(0) == 0:
p.f("%vi", fconv(&u.Imag, FmtSharp)) fmt.Fprintf(s, "%vi", fconv(&u.Imag, FmtSharp))
case v.U.(*Mpcplx).Imag.CmpFloat64(0) == 0: case v.U.(*Mpcplx).Imag.CmpFloat64(0) == 0:
return fconv(&u.Real, FmtSharp) fmt.Fprint(s, fconv(&u.Real, FmtSharp))
case v.U.(*Mpcplx).Imag.CmpFloat64(0) < 0: case v.U.(*Mpcplx).Imag.CmpFloat64(0) < 0:
p.f("(%v%vi)", fconv(&u.Real, FmtSharp), fconv(&u.Imag, FmtSharp)) fmt.Fprintf(s, "(%v%vi)", fconv(&u.Real, FmtSharp), fconv(&u.Imag, FmtSharp))
default: default:
p.f("(%v+%vi)", fconv(&u.Real, FmtSharp), fconv(&u.Imag, FmtSharp)) fmt.Fprintf(s, "(%v+%vi)", fconv(&u.Real, FmtSharp), fconv(&u.Imag, FmtSharp))
} }
case string: case string:
return strconv.Quote(u) fmt.Fprint(s, strconv.Quote(u))
case bool: case bool:
t := "false"
if u { if u {
return "true" t = "true"
} }
return "false" fmt.Fprint(s, t)
case *NilVal: case *NilVal:
return "nil" fmt.Fprint(s, "nil")
default: default:
p.f("<ctype=%d>", v.Ctype()) fmt.Fprintf(s, "<ctype=%d>", v.Ctype())
} }
return p.String()
} }
/* /*
...@@ -1139,13 +1152,13 @@ func (p *printer) exprfmt(n *Node, prec int) *printer { ...@@ -1139,13 +1152,13 @@ func (p *printer) exprfmt(n *Node, prec int) *printer {
// 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, vconv(n.Val(), 0)) return p.f("(%v)(%v)", n.Type, n.Val())
} else { } else {
return p.f("%v(%v)", n.Type, vconv(n.Val(), 0)) return p.f("%v(%v)", n.Type, n.Val())
} }
} }
return p.s(vconv(n.Val(), 0)) return p.f("%s", n.Val())
// 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
...@@ -1463,7 +1476,7 @@ func (p *printer) nodedump(n *Node, flag FmtFlag) *printer { ...@@ -1463,7 +1476,7 @@ func (p *printer) nodedump(n *Node, flag FmtFlag) *printer {
p.f("%v-%v%j", n.Op, obj.Rconv(int(n.Reg)), n) p.f("%v-%v%j", n.Op, obj.Rconv(int(n.Reg)), n)
case OLITERAL: case OLITERAL:
p.f("%v-%v%j", n.Op, vconv(n.Val(), 0), n) p.f("%v-%v%j", n.Op, n.Val(), n)
case ONAME, ONONAME: case ONAME, ONONAME:
if n.Sym != nil { if n.Sym != nil {
......
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