diff options
Diffstat (limited to 'src/lib/reflect/tostring.go')
-rw-r--r-- | src/lib/reflect/tostring.go | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/src/lib/reflect/tostring.go b/src/lib/reflect/tostring.go new file mode 100644 index 000000000..ca3ada9fd --- /dev/null +++ b/src/lib/reflect/tostring.go @@ -0,0 +1,199 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Reflection library. +// Formatting of types and values for debugging. + +package reflect + +import ( + "reflect"; + "strings"; +) + +export func TypeToString(typ Type, expand bool) string +export func ValueToString(val Value) string + +type HasFields interface { + Field(i int) (name string, typ Type, offset uint64); + Len() int; +} + +func TypeFieldsToString(t HasFields, sep string) string { + var str string; + for i := 0; i < t.Len(); i++ { + str1, typ, offset := t.Field(i); + str1 += " " + TypeToString(typ, false); + if i < t.Len() - 1 { + str1 += sep + " "; + } + str += str1; + } + return str; +} + +func TypeToString(typ Type, expand bool) string { + var str string; + if name := typ.Name(); !expand && name != "" { + return name + } + switch(typ.Kind()) { + case MissingKind: + return "$missing$"; + case Int8Kind: + return "int8"; + case Int16Kind: + return "int16"; + case Int32Kind: + return "int32"; + case Int64Kind: + return "int64"; + case Uint8Kind: + return "uint8"; + case Uint16Kind: + return "uint16"; + case Uint32Kind: + return "uint32"; + case Uint64Kind: + return "uint64"; + case Float32Kind: + return "float32"; + case Float64Kind: + return "float64"; + case Float80Kind: + return "float80"; + case StringKind: + return "string"; + case PtrKind: + p := typ.(PtrType); + return "*" + TypeToString(p.Sub(), false); + case ArrayKind: + a := typ.(ArrayType); + if a.Open() { + str = "[]" + } else { + str = "[" + strings.ltoa(int64(a.Len())) + "]" + } + return str + TypeToString(a.Elem(), false); + case MapKind: + m := typ.(MapType); + str = "map[" + TypeToString(m.Key(), false) + "]"; + return str + TypeToString(m.Elem(), false); + case ChanKind: + c := typ.(ChanType); + switch c.Dir() { + case RecvDir: + str = "<-chan"; + case SendDir: + str = "chan<-"; + case BothDir: + str = "chan"; + default: + panicln("reflect.TypeToString: unknown chan direction"); + } + return str + TypeToString(c.Elem(), false); + case StructKind: + return "struct{" + TypeFieldsToString(typ, ";") + "}"; + case InterfaceKind: + return "interface{" + TypeFieldsToString(typ, ";") + "}"; + case FuncKind: + f := typ.(FuncType); + str = "(" + TypeFieldsToString(f.In(), ",") + ")"; + if f.Out() != nil { + str += "(" + TypeFieldsToString(f.Out(), ",") + ")"; + } + return str; + default: + panicln("reflect.TypeToString: can't print type ", typ.Kind()); + } + return "reflect.TypeToString: can't happen"; +} + +// TODO: want an unsigned one too +func integer(v int64) string { + return strings.ltoa(v); +} + +func floatingpoint(v float64) string { + return strings.dtoa(v); +} + +func ValueToString(val Value) string { + var str string; + typ := val.Type(); + switch(val.Kind()) { + case MissingKind: + return "missing"; + case Int8Kind: + return integer(int64(val.(Int8Value).Get())); + case Int16Kind: + return integer(int64(val.(Int16Value).Get())); + case Int32Kind: + return integer(int64(val.(Int32Value).Get())); + case Int64Kind: + return integer(int64(val.(Int64Value).Get())); + case Uint8Kind: + return integer(int64(val.(Uint8Value).Get())); + case Uint16Kind: + return integer(int64(val.(Uint16Value).Get())); + case Uint32Kind: + return integer(int64(val.(Uint32Value).Get())); + case Uint64Kind: + return integer(int64(val.(Uint64Value).Get())); + case Float32Kind: + return floatingpoint(float64(val.(Float32Value).Get())); + case Float64Kind: + return floatingpoint(float64(val.(Float64Value).Get())); + case Float80Kind: + return "float80"; + case StringKind: + return val.(StringValue).Get(); + case PtrKind: + v := val.(PtrValue); + return TypeToString(typ, false) + "(" + integer(int64(v.Indirect())) + ")"; + case ArrayKind: + t := typ.(ArrayType); + v := val.(ArrayValue); + str += TypeToString(t, false); + str += "{"; + for i := uint64(0); i < v.Len(); i++ { + if i > 0 { + str += ", " + } + str += ValueToString(v.Elem(i)); + } + str += "}"; + return str; + case MapKind: + t := typ.(MapType); + v := val.(ArrayValue); + str = TypeToString(t, false); + str += "{"; + str += "<can't iterate on maps>"; + str += "}"; + return str; + case ChanKind: + return "can't print chans yet"; + case StructKind: + t := typ.(StructType); + v := val.(StructValue); + str += TypeToString(t, false); + str += "{"; + for i := 0; i < v.Len(); i++ { + if i > 0 { + str += ", " + } + str += ValueToString(v.Field(i)); + } + str += "}"; + return str; + case InterfaceKind: + return "can't print interfaces yet"; + case FuncKind: + return "can't print funcs yet"; + default: + panicln("reflect.ValueToString: can't print type ", val.Kind()); + } + return "reflect.ValueToString: can't happen"; +} |