type strings through the reflection library.

R=rsc
DELTA=187  (107 added, 28 deleted, 52 changed)
OCL=18510
CL=18510
diff --git a/src/lib/reflect/test.go b/src/lib/reflect/test.go
index d057251..54fd5ac 100644
--- a/src/lib/reflect/test.go
+++ b/src/lib/reflect/test.go
@@ -88,9 +88,11 @@
 export type T struct { a int; b float64; c string; d *int }
 
 func main() {
+//NOTE: INTERFACES PARSE INCORRECTLY: parser's Fields() stops at '('
 	var s string;
 	var t reflect.Type;
 
+	// Types
 	typedump("missing", "$missing$");
 	typedump("int", "int");
 	typedump("int8", "int8");
@@ -126,6 +128,7 @@
 	typedump("struct {a int8 \"hi \\x00there\\t\\n\\\"\\\\\"; }", "struct{a int8 \"hi \\x00there\\t\\n\\\"\\\\\"}");
 	typedump("struct {f *(args ...)}", "struct{f *(args ...)}");
 
+	// Values
 	valuedump("int8", "8");
 	valuedump("int16", "16");
 	valuedump("int32", "32");
@@ -191,4 +194,56 @@
 		value.(reflect.PtrValue).Sub().(reflect.ArrayValue).Elem(4).(reflect.IntValue).Put(123);
 		assert(reflect.ValueToString(value.(reflect.PtrValue).Sub()), "main.AA·test{1, 2, 3, 4, 123, 6, 7, 8, 9, 10}");
 	}
+
+	var pt reflect.PtrType;
+	var st reflect.StructType;
+	var mt reflect.MapType;
+	var at reflect.ArrayType;
+	var ct reflect.ChanType;
+	var name string;
+	var typ reflect.Type;
+	var tag string;
+	var offset uint64;
+
+	// Type strings
+	t = reflect.ParseTypeString("", "int8");
+	assert(t.String(), "int8");
+
+	t = reflect.ParseTypeString("", "*int8");
+	assert(t.String(), "*int8");
+	pt = t.(reflect.PtrType);
+	assert(pt.Sub().String(), "int8");
+
+	t = reflect.ParseTypeString("", "*struct {c *chan *int32; d float32}");
+	assert(t.String(), "*struct {c *chan *int32; d float32}");
+	pt = t.(reflect.PtrType);
+	assert(pt.Sub().String(), "struct {c *chan *int32; d float32}");
+	st = pt.Sub().(reflect.StructType);
+	name, typ, tag, offset = st.Field(0);
+	assert(typ.String(), "*chan *int32");
+	name, typ, tag, offset = st.Field(1);
+	assert(typ.String(), "float32");
+
+	//TODO! this is bad - can't put a method in an interface!
+	t = reflect.ParseTypeString("", "interface {a int}");
+	assert(t.String(), "interface {a int}");
+
+	t = reflect.ParseTypeString("", "*(a int8, b int32)");
+	assert(t.String(), "*(a int8, b int32)");
+
+	t = reflect.ParseTypeString("", "[32]int32");
+	assert(t.String(), "[32]int32");
+	at = t.(reflect.ArrayType);
+	assert(at.Elem().String(), "int32");
+
+	t = reflect.ParseTypeString("", "map[string]*int32");
+	assert(t.String(), "map[string]*int32");
+	mt = t.(reflect.MapType);
+	assert(mt.Key().String(), "string");
+	assert(mt.Elem().String(), "*int32");
+
+	t = reflect.ParseTypeString("", "chan<-string");
+	assert(t.String(), "chan<-string");
+	ct = t.(reflect.ChanType);
+	assert(ct.Elem().String(), "string");
 }
diff --git a/src/lib/reflect/type.go b/src/lib/reflect/type.go
index 8d5d2bd..6440576 100644
--- a/src/lib/reflect/type.go
+++ b/src/lib/reflect/type.go
@@ -50,22 +50,33 @@
 export type Type interface {
 	Kind()	int;
 	Name()	string;
+	String()	string;
+	SetString(string);	// TODO: remove when no longer needed
 	Size()	uint64;
 }
 
 // Fields and methods common to all types
 type Common struct {
 	kind	int;
+	str	string;
 	name	string;
 	size	uint64;
 }
 
+func (c *Common) Kind() int {
+	return c.kind
+}
+
 func (c *Common) Name() string {
 	return c.name
 }
 
-func (c *Common) Kind() int {
-	return c.kind
+func (c *Common) String() string {
+	return c.str
+}
+
+func (c *Common) SetString(s string) {
+	c.str = s
 }
 
 func (c *Common) Size() uint64 {
@@ -79,7 +90,7 @@
 }
 
 func NewBasicType(name string, kind int, size uint64) Type {
-	return &BasicType{ Common{kind, name, size} }
+	return &BasicType{ Common{kind, name, name, size} }
 }
 
 // Prebuilt basic types
@@ -134,8 +145,8 @@
 	sub	*StubType;
 }
 
-func NewPtrTypeStruct(name string, sub *StubType) *PtrTypeStruct {
-	return &PtrTypeStruct{ Common{PtrKind, name, ptrsize}, sub}
+func NewPtrTypeStruct(name, typestring string, sub *StubType) *PtrTypeStruct {
+	return &PtrTypeStruct{ Common{PtrKind, typestring, name, ptrsize}, sub}
 }
 
 func (t *PtrTypeStruct) Sub() Type {
@@ -157,8 +168,8 @@
 	len	uint64;
 }
 
-func NewArrayTypeStruct(name string, open bool, len uint64, elem *StubType) *ArrayTypeStruct {
-	return &ArrayTypeStruct{ Common{ArrayKind, name, 0}, elem, open, len}
+func NewArrayTypeStruct(name, typestring string, open bool, len uint64, elem *StubType) *ArrayTypeStruct {
+	return &ArrayTypeStruct{ Common{ArrayKind, typestring, name, 0}, elem, open, len}
 }
 
 func (t *ArrayTypeStruct) Size() uint64 {
@@ -194,8 +205,8 @@
 	elem	*StubType;
 }
 
-func NewMapTypeStruct(name string, key, elem *StubType) *MapTypeStruct {
-	return &MapTypeStruct{ Common{MapKind, name, 0}, key, elem}
+func NewMapTypeStruct(name, typestring string, key, elem *StubType) *MapTypeStruct {
+	return &MapTypeStruct{ Common{MapKind, typestring, name, 0}, key, elem}
 }
 
 func (t *MapTypeStruct) Size() uint64 {
@@ -230,8 +241,8 @@
 	dir	int;
 }
 
-func NewChanTypeStruct(name string, dir int, elem *StubType) *ChanTypeStruct {
-	return &ChanTypeStruct{ Common{ChanKind, name, 0}, elem, dir}
+func NewChanTypeStruct(name, typestring string, dir int, elem *StubType) *ChanTypeStruct {
+	return &ChanTypeStruct{ Common{ChanKind, typestring, name, 0}, elem, dir}
 }
 
 func (t *ChanTypeStruct) Size() uint64 {
@@ -267,8 +278,8 @@
 	field	*[]Field;
 }
 
-func NewStructTypeStruct(name string, field *[]Field) *StructTypeStruct {
-	return &StructTypeStruct{ Common{StructKind, name, 0}, field}
+func NewStructTypeStruct(name, typestring string, field *[]Field) *StructTypeStruct {
+	return &StructTypeStruct{ Common{StructKind, typestring, name, 0}, field}
 }
 
 // TODO: not portable; depends on 6g
@@ -318,8 +329,8 @@
 	field	*[]Field;
 }
 
-func NewInterfaceTypeStruct(name string, field *[]Field) *InterfaceTypeStruct {
-	return &InterfaceTypeStruct{ Common{InterfaceKind, name, interfacesize}, field }
+func NewInterfaceTypeStruct(name, typestring string, field *[]Field) *InterfaceTypeStruct {
+	return &InterfaceTypeStruct{ Common{InterfaceKind, typestring, name, interfacesize}, field }
 }
 
 func (t *InterfaceTypeStruct) Field(i int) (name string, typ Type, tag string, offset uint64) {
@@ -343,8 +354,8 @@
 	out	*StructTypeStruct;
 }
 
-func NewFuncTypeStruct(name string, in, out *StructTypeStruct) *FuncTypeStruct {
-	return &FuncTypeStruct{ Common{FuncKind, name, 0}, in, out }
+func NewFuncTypeStruct(name, typestring string, in, out *StructTypeStruct) *FuncTypeStruct {
+	return &FuncTypeStruct{ Common{FuncKind, typestring, name, 0}, in, out }
 }
 
 func (t *FuncTypeStruct) Size() uint64 {
@@ -543,6 +554,7 @@
 type Parser struct {
 	str	string;	// string being parsed
 	token	string;	// the token being parsed now
+	tokstart	int;	// starting position of token
 	index	int;	// next character position in str
 }
 
@@ -551,6 +563,7 @@
 	token := "";
 	for ; p.index < len(p.str) && p.str[p.index] == ' '; p.index++ {
 	}
+	p.tokstart = p.index;
 	if p.index >= len(p.str) {
 		p.token = "";
 		return;
@@ -608,7 +621,7 @@
 
 func (p *Parser) Type(name string) *StubType
 
-func (p *Parser) Array(name string) *StubType {
+func (p *Parser) Array(name string, tokstart int) *StubType {
 	size := uint64(0);
 	open := true;
 	if p.token != "]" {
@@ -628,10 +641,10 @@
 	}
 	p.Next();
 	elemtype := p.Type("");
-	return NewStubType(name, NewArrayTypeStruct(name, open, size, elemtype));
+	return NewStubType(name, NewArrayTypeStruct(name, p.str[tokstart:p.index], open, size, elemtype));
 }
 
-func (p *Parser) Map(name string) *StubType {
+func (p *Parser) Map(name string, tokstart int) *StubType {
 	if p.token != "[" {
 		return MissingStub
 	}
@@ -642,10 +655,10 @@
 	}
 	p.Next();
 	elemtype := p.Type("");
-	return NewStubType(name, NewMapTypeStruct(name, keytype, elemtype));
+	return NewStubType(name, NewMapTypeStruct(name, p.str[tokstart:p.index], keytype, elemtype));
 }
 
-func (p *Parser) Chan(name string, dir int) *StubType {
+func (p *Parser) Chan(name string, tokstart, dir int) *StubType {
 	if p.token == "<-" {
 		if dir != BothDir {
 			return MissingStub
@@ -654,7 +667,7 @@
 		dir = SendDir;
 	}
 	elemtype := p.Type("");
-	return NewStubType(name, NewChanTypeStruct(name, dir, elemtype));
+	return NewStubType(name, NewChanTypeStruct(name, p.str[tokstart:p.index], dir, elemtype));
 }
 
 // Parse array of fields for struct, interface, and func arguments
@@ -685,59 +698,65 @@
 	return a[0:nf];
 }
 
-func (p *Parser) Struct(name string) *StubType {
+func (p *Parser) Struct(name string, tokstart int) *StubType {
 	f := p.Fields(";");
 	if p.token != "}" {
 		return MissingStub;
 	}
+	ts := p.str[tokstart:p.index];
 	p.Next();
-	return NewStubType(name, NewStructTypeStruct(name, f));
+	return NewStubType(name, NewStructTypeStruct(name, ts, f));
 }
 
-func (p *Parser) Interface(name string) *StubType {
+func (p *Parser) Interface(name string, tokstart int) *StubType {
 	f := p.Fields(";");
 	if p.token != "}" {
 		return MissingStub;
 	}
+	ts := p.str[tokstart:p.index];
 	p.Next();
-	return NewStubType(name, NewInterfaceTypeStruct(name, f));
+	return NewStubType(name, NewInterfaceTypeStruct(name, ts, f));
 }
 
-func (p *Parser) Func(name string) *StubType {
+func (p *Parser) Func(name string, tokstart int) *StubType {
 	// may be 1 or 2 parenthesized lists
-	f1 := NewStructTypeStruct("", p.Fields(","));
+	f1 := NewStructTypeStruct("", "", p.Fields(","));
 	if p.token != ")" {
 		return MissingStub;
 	}
+	end := p.index;
 	p.Next();
 	if p.token != "(" {
 		// 1 list: the in parameters only
-		return NewStubType(name, NewFuncTypeStruct(name, f1, nil));
+		return NewStubType(name, NewFuncTypeStruct(name, p.str[tokstart:end], f1, nil));
 	}
 	p.Next();
-	f2 := NewStructTypeStruct("", p.Fields(","));
+	f2 := NewStructTypeStruct("", "", p.Fields(","));
 	if p.token != ")" {
 		return MissingStub;
 	}
+	end = p.index;
 	p.Next();
 	// 2 lists: the in and out parameters are present
-	return NewStubType(name, NewFuncTypeStruct(name, f1, f2));
+	return NewStubType(name, NewFuncTypeStruct(name, p.str[tokstart:end], f1, f2));
 }
 
 func (p *Parser) Type(name string) *StubType {
 	dir := BothDir;
+	tokstart := p.tokstart;
 	switch {
 	case p.token == "":
 		return nil;
 	case p.token == "*":
 		p.Next();
-		return NewStubType(name, NewPtrTypeStruct(name, p.Type("")));
+		sub := p.Type("");
+		return NewStubType(name, NewPtrTypeStruct(name, p.str[tokstart:p.index], sub));
 	case p.token == "[":
 		p.Next();
-		return p.Array(name);
+		return p.Array(name, tokstart);
 	case p.token == "map":
 		p.Next();
-		return p.Map(name);
+		return p.Map(name, tokstart);
 	case p.token == "<-":
 		p.Next();
 		dir = RecvDir;
@@ -747,24 +766,24 @@
 		fallthrough;
 	case p.token == "chan":
 		p.Next();
-		return p.Chan(name, dir);
+		return p.Chan(name, tokstart, dir);
 	case p.token == "struct":
 		p.Next();
 		if p.token != "{" {
 			return MissingStub
 		}
 		p.Next();
-		return p.Struct(name);
+		return p.Struct(name, tokstart);
 	case p.token == "interface":
 		p.Next();
 		if p.token != "{" {
 			return MissingStub
 		}
 		p.Next();
-		return p.Interface(name);
+		return p.Interface(name, tokstart);
 	case p.token == "(":
 		p.Next();
-		return p.Func(name);
+		return p.Func(name, tokstart);
 	case isdigit(p.token[0]):
 		p.Next();
 		return MissingStub;
diff --git a/src/lib/reflect/value.go b/src/lib/reflect/value.go
index 5c9c727..527f1ff 100644
--- a/src/lib/reflect/value.go
+++ b/src/lib/reflect/value.go
@@ -11,34 +11,8 @@
 	"reflect";
 )
 
-
 type Addr uint64	// TODO: where are ptrint/intptr etc?
 
-export type Value interface {
-	Kind()	int;
-	Type()	Type;
-}
-
-// Common fields and functionality for all values
-
-type Common struct {
-	kind	int;
-	typ	Type;
-	addr	Addr;
-}
-
-func (c *Common) Kind() int {
-	return c.kind
-}
-
-func (c *Common) Type() Type {
-	return c.typ
-}
-
-func NewValueAddr(typ Type, addr Addr) Value
-
-type Creator *(typ Type, addr Addr) Value
-
 // Conversion functions, implemented in assembler
 func AddrToPtrAddr(Addr) *Addr
 func AddrToPtrInt(Addr) *int
@@ -60,6 +34,39 @@
 func AddrToPtrString(Addr) *string
 func AddrToPtrBool(Addr) *bool
 
+export type Empty interface {}	// TODO(r): Delete when no longer needed?
+
+export type Value interface {
+	Kind()	int;
+	Type()	Type;
+	Unreflect()	Empty;
+}
+
+// Common fields and functionality for all values
+
+type Common struct {
+	kind	int;
+	typ	Type;
+	addr	Addr;
+}
+
+func (c *Common) Kind() int {
+	return c.kind
+}
+
+func (c *Common) Type() Type {
+	return c.typ
+}
+
+func (c *Common) Unreflect() Empty {
+	return sys.unreflect(*AddrToPtrAddr(c.addr), c.typ.String());
+}
+
+func NewValueAddr(typ Type, addr Addr) Value
+
+type Creator *(typ Type, addr Addr) Value
+
+
 // -- Missing
 
 export type MissingValue interface {
@@ -743,8 +750,6 @@
 	return NewValueAddr(typ, PtrUint8ToAddr(&data[0]));
 }
 
-export type Empty interface {}
-
 export func NewValue(e Empty) Value {
 	value, typestring  := sys.reflect(e);
 	typ := ParseTypeString("", typestring);