}
func NewBasicLit(pos src.XPos, val constant.Value) Node {
+ if val == nil || val.Kind() == constant.Unknown {
+ base.FatalfAt(pos, "bad value: %v", val)
+ }
+
n := &BasicLit{val: val}
n.op = OLITERAL
n.pos = pos
- n.SetType(idealType(val.Kind()))
+ n.SetType(types.UntypedTypes[val.Kind()])
n.SetTypecheck(1)
return n
}
case ONIL:
fmt.Fprint(s, "nil")
- case OLITERAL: // this is a bit of a mess
- if !exportFormat && n.Sym() != nil {
+ case OLITERAL:
+ if n.Sym() != nil {
fmt.Fprint(s, n.Sym())
return
}
- needUnparen := false
- if n.Type() != nil && !n.Type().IsUntyped() {
- // Need parens when type begins with what might
- // be misinterpreted as a unary operator: * or <-.
- if n.Type().IsPtr() || (n.Type().IsChan() && n.Type().ChanDir() == types.Crecv) {
- fmt.Fprintf(s, "(%v)(", n.Type())
- } else {
- fmt.Fprintf(s, "%v(", n.Type())
- }
- needUnparen = true
- }
-
- if n.Type() == types.UntypedRune {
- switch x, ok := constant.Uint64Val(n.Val()); {
- case !ok:
- fallthrough
- default:
- fmt.Fprintf(s, "('\\x00' + %v)", n.Val())
+ typ := n.Type()
+ val := n.Val()
- case x < utf8.RuneSelf:
+ // Special case for rune constants.
+ if typ == types.RuneType || typ == types.UntypedRune {
+ if x, ok := constant.Uint64Val(val); ok && x <= utf8.MaxRune {
fmt.Fprintf(s, "%q", x)
-
- case x < 1<<16:
- fmt.Fprintf(s, "'\\u%04x'", x)
-
- case x <= utf8.MaxRune:
- fmt.Fprintf(s, "'\\U%08x'", x)
+ return
}
- } else {
- fmt.Fprint(s, types.FmtConst(n.Val(), s.Flag('#')))
}
- if needUnparen {
- fmt.Fprintf(s, ")")
+ // Only include typ if it's neither the default nor untyped type
+ // for the constant value.
+ if k := val.Kind(); typ == types.Types[types.DefaultKinds[k]] || typ == types.UntypedTypes[k] {
+ fmt.Fprint(s, val)
+ } else {
+ fmt.Fprintf(s, "%v(%v)", typ, val)
}
case ODCLFUNC:
panic("unreachable")
}
-func idealType(ct constant.Kind) *types.Type {
- switch ct {
- case constant.String:
- return types.UntypedString
- case constant.Bool:
- return types.UntypedBool
- case constant.Int:
- return types.UntypedInt
- case constant.Float:
- return types.UntypedFloat
- case constant.Complex:
- return types.UntypedComplex
- }
- base.Fatalf("unexpected Ctype: %v", ct)
- return nil
-}
-
var OKForConst [types.NTYPE]bool
// Int64Val returns n as an int64.
"bytes"
"encoding/binary"
"fmt"
- "go/constant"
"strconv"
"strings"
"sync"
return name, ""
}
-// Val
-
-func FmtConst(v constant.Value, sharp bool) string {
- if !sharp && v.Kind() == constant.Complex {
- real, imag := constant.Real(v), constant.Imag(v)
-
- var re string
- sre := constant.Sign(real)
- if sre != 0 {
- re = real.String()
- }
-
- var im string
- sim := constant.Sign(imag)
- if sim != 0 {
- im = imag.String()
- }
-
- switch {
- case sre == 0 && sim == 0:
- return "0"
- case sre == 0:
- return im + "i"
- case sim == 0:
- return re
- case sim < 0:
- return fmt.Sprintf("(%s%si)", re, im)
- default:
- return fmt.Sprintf("(%s+%si)", re, im)
- }
- }
-
- return v.String()
-}
-
// TypeHash computes a hash value for type t to use in type switch statements.
func TypeHash(t *Type) uint32 {
p := t.LinkString()
"cmd/internal/objabi"
"cmd/internal/src"
"fmt"
+ "go/constant"
"internal/types/errors"
"sync"
)
UntypedComplex = newType(TIDEAL)
)
+// UntypedTypes maps from a constant.Kind to its untyped Type
+// representation.
+var UntypedTypes = [...]*Type{
+ constant.Bool: UntypedBool,
+ constant.String: UntypedString,
+ constant.Int: UntypedInt,
+ constant.Float: UntypedFloat,
+ constant.Complex: UntypedComplex,
+}
+
+// DefaultKinds maps from a constant.Kind to its default Kind.
+var DefaultKinds = [...]Kind{
+ constant.Bool: TBOOL,
+ constant.String: TSTRING,
+ constant.Int: TINT,
+ constant.Float: TFLOAT64,
+ constant.Complex: TCOMPLEX128,
+}
+
// A Type represents a Go type.
//
// There may be multiple unnamed types with identical structure. However, there must