1
0
mirror of https://github.com/golang/go synced 2024-11-26 01:57:56 -07:00

reflection type structure. no parsing etc. yet.

main is a simple tester outside the Makefile.

R=rsc
DELTA=455  (455 added, 0 deleted, 0 changed)
OCL=17235
CL=17242
This commit is contained in:
Rob Pike 2008-10-15 17:11:51 -07:00
parent 7cd173a4f8
commit 693a31b88e
4 changed files with 471 additions and 0 deletions

47
usr/r/reflect/Makefile Normal file
View File

@ -0,0 +1,47 @@
# 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.
# DO NOT EDIT. Automatically generated by gobuild.
# gobuild -m reflect print.go type.go
O=6
GC=$(O)g
CC=$(O)c -w
AS=$(O)a
AR=$(O)ar
PKG=$(GOROOT)/pkg/reflect.a
install: $(PKG)
nuke: clean
rm -f $(PKG)
clean:
rm -f *.$O *.a
%.$O: %.go
$(GC) $*.go
%.$O: %.c
$(CC) $*.c
%.$O: %.s
$(AS) $*.s
O1=\
type.$O\
O2=\
print.$O\
$(PKG): a1 a2
a1: $(O1)
$(AR) grc $(PKG) $(O1)
a2: $(O2)
$(AR) grc $(PKG) $(O2)
$(O1): nuke
$(O2): a1

31
usr/r/reflect/main.go Normal file
View File

@ -0,0 +1,31 @@
// 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.
package main
import (
"reflect"
)
func main() {
reflect.Print(reflect.Int8); print("\n");
reflect.Print(reflect.Int16); print("\n");
reflect.Print(reflect.Int32); print("\n");
reflect.Print(reflect.Int64); print("\n");
reflect.Print(reflect.Uint8); print("\n");
reflect.Print(reflect.Uint16); print("\n");
reflect.Print(reflect.Uint32); print("\n");
reflect.Print(reflect.Uint64); print("\n");
reflect.Print(reflect.Float32); print("\n");
reflect.Print(reflect.Float64); print("\n");
reflect.Print(reflect.Float80); print("\n");
reflect.Print(reflect.String); print("\n");
reflect.Print(reflect.PtrInt8); print("\n");
reflect.Print(reflect.ArrayFloat32); print("\n");
reflect.Print(reflect.MapStringInt16); print("\n");
reflect.Print(reflect.ChanArray); print("\n");
reflect.Print(reflect.Structure); print("\n");
reflect.Print(reflect.Function); print("\n");
}

101
usr/r/reflect/print.go Normal file
View File

@ -0,0 +1,101 @@
// 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.
package reflect
import (
"reflect"
)
// Implemented as a function rather than a method to keep the
// Type interface small. TODO: should this return a string?
export func Print(typ Type) {
switch(typ.Kind()) {
case Int8Kind:
print("int8");
case Int16Kind:
print("int16");
case Int32Kind:
print("int32");
case Int64Kind:
print("int64");
case Uint8Kind:
print("uint8");
case Uint16Kind:
print("uint16");
case Uint32Kind:
print("uint32");
case Uint64Kind:
print("uint64");
case Float32Kind:
print("float32");
case Float64Kind:
print("float64");
case Float80Kind:
print("float80");
case StringKind:
print("string");
case PtrKind:
p := typ.(PtrType);
print("*");
Print(p.Sub());
case ArrayKind:
a := typ.(ArrayType);
if a.Len() >= 0 {
print("[", a.Len(), "]")
} else {
print("[]")
}
Print(a.Elem());
case MapKind:
m := typ.(MapType);
print("map[");
Print(m.Key());
print("]");
Print(m.Elem());
case ChanKind:
c := typ.(ChanType);
switch c.Dir() {
case RecvDir:
print("<-chan");
case SendDir:
print("chan<-");
case BothDir:
print("chan");
default:
panicln("reflect.Print: unknown chan direction");
}
Print(c.Elem());
case StructKind:
s := typ.(StructType);
print("struct{");
for i := 0; i < s.Len(); i++ {
n, t := s.Field(i);
print(n, " ");
Print(t);
if i < s.Len() - 1 {
print("; ");
}
}
print("}");
case FuncKind:
f := typ.(FuncType);
print("func ");
if f.Receiver() != nil {
print("(");
Print(f.Receiver());
print(")");
}
print("(");
Print(f.In());
print(")");
if f.Out() != nil {
print("(");
Print(f.Out());
print(")");
}
default:
panicln("can't print type ", typ.Kind());
}
}

292
usr/r/reflect/type.go Normal file
View File

@ -0,0 +1,292 @@
// 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.
package reflect
export type Type interface
export type Value interface{} // TODO: define this
export func LookupTypeName(name string) Type
//export var GlobalTypeStrings = sys.typestrings;
// Cache of types keyed by type name
var types = new(map[string] *Type) // BUG TODO: should be Type not *Type
// Cache of type strings keyed by type name
var strings = new(map[string] string)
export const (
ArrayKind = iota;
ChanKind;
Float32Kind;
Float64Kind;
Float80Kind;
FuncKind;
Int16Kind;
Int32Kind;
Int64Kind;
Int8Kind;
MapKind;
PtrKind;
StringKind;
StructKind;
Uint16Kind;
Uint32Kind;
Uint64Kind;
Uint8Kind;
)
type Type interface {
Kind() int;
}
type BasicType struct{
kind int
}
func (t *BasicType) Kind() int {
return t.kind
}
func NewBasicType(k int) Type {
t := new(BasicType);
t.kind = k;
return t;
}
// Basic types
export var (
Int8 = NewBasicType(Int8Kind);
Int16 = NewBasicType(Int16Kind);
Int32 = NewBasicType(Int32Kind);
Int64 = NewBasicType(Int64Kind);
Uint8 = NewBasicType(Uint8Kind);
Uint16 = NewBasicType(Uint16Kind);
Uint32 = NewBasicType(Uint32Kind);
Uint64 = NewBasicType(Uint64Kind);
Float32 = NewBasicType(Float32Kind);
Float64 = NewBasicType(Float64Kind);
Float80 = NewBasicType(Float80Kind);
String = NewBasicType(StringKind);
)
type StubType struct {
name string;
typ Type;
}
func (t *StubType) Get() Type {
if t.typ == nil {
t.typ = LookupTypeName(t.name)
}
return t.typ
}
export type PtrType interface {
Sub() Type
}
type PtrTypeStruct struct {
sub *StubType
}
func (t *PtrTypeStruct) Kind() int {
return PtrKind
}
func (t *PtrTypeStruct) Sub() Type {
return t.sub.Get()
}
func NewPtrTypeStruct(sub *StubType) *PtrTypeStruct {
t := new(PtrTypeStruct);
t.sub = sub;
return t;
}
export type ArrayType interface {
Len() int;
Elem() Type;
}
type ArrayTypeStruct struct {
elem *StubType;
len int;
}
func (t *ArrayTypeStruct) Kind() int {
return ArrayKind
}
func (t *ArrayTypeStruct) Len() int {
// -1 is open array? TODO
return t.len
}
func (t *ArrayTypeStruct) Elem() Type {
return t.elem.Get()
}
func NewArrayTypeStruct(len int, elem *StubType) *ArrayTypeStruct {
t := new(ArrayTypeStruct);
t.len = len;
t.elem = elem;
return t;
}
export type MapType interface {
Key() Type;
Elem() Type;
}
type MapTypeStruct struct {
key *StubType;
elem *StubType;
}
func (t *MapTypeStruct) Kind() int {
return MapKind
}
func (t *MapTypeStruct) Key() Type {
return t.key.Get()
}
func (t *MapTypeStruct) Elem() Type {
return t.elem.Get()
}
func NewMapTypeStruct(key, elem *StubType) *MapTypeStruct {
t := new(MapTypeStruct);
t.key = key;
t.elem = elem;
return t;
}
export type ChanType interface {
Dir() int;
Elem() Type;
}
export const ( // channel direction
SendDir = 1 << iota;
RecvDir;
BothDir = SendDir | RecvDir;
)
type ChanTypeStruct struct {
elem *StubType;
dir int;
}
func (t *ChanTypeStruct) Kind() int {
return ChanKind
}
func (t *ChanTypeStruct) Dir() int {
// -1 is open array? TODO
return t.dir
}
func (t *ChanTypeStruct) Elem() Type {
return t.elem.Get()
}
func NewChanTypeStruct(dir int, elem *StubType) *ChanTypeStruct {
t := new(ChanTypeStruct);
t.dir = dir;
t.elem = elem;
return t;
}
export type StructType interface {
Field(int) (name string, typ Type);
Len() int;
}
type Field struct {
name string;
typ *StubType;
}
type StructTypeStruct struct {
field *[]Field;
}
func (t *StructTypeStruct) Kind() int {
return StructKind
}
func (t *StructTypeStruct) Field(i int) (name string, typ Type) {
return t.field[i].name, t.field[i].typ.Get()
}
func (t *StructTypeStruct) Len() int {
return len(t.field)
}
func Struct(field *[]Field) *StructTypeStruct {
t := new(StructTypeStruct);
t.field = field;
return t;
}
func NewStructTypeStruct(field *[]Field) *StructTypeStruct {
t := new(StructTypeStruct);
t.field = field;
return t;
}
export type FuncType interface {
Receiver() StructType;
In() StructType;
Out() StructType;
}
type FuncTypeStruct struct {
receiver *StructTypeStruct;
in *StructTypeStruct;
out *StructTypeStruct;
}
func (t *FuncTypeStruct) Kind() int {
return FuncKind
}
func (t *FuncTypeStruct) Receiver() StructType {
return t.receiver
}
func (t *FuncTypeStruct) In() StructType {
return t.in
}
func (t *FuncTypeStruct) Out() StructType {
return t.out
}
func NewFuncTypeStruct(receiver, in, out *StructTypeStruct) *FuncTypeStruct {
t := new(FuncTypeStruct);
t.receiver = receiver;
t.in = in;
t.out = out;
return t;
}
//helpers for early bootstrap and debugging
export func LookupTypeName(name string) Type { return Int8 }
func Stub(n string, t Type) *StubType {
s := new(StubType);
s.name = n;
s.typ = t;
return s;
}
export var PtrInt8 Type = NewPtrTypeStruct(Stub("i", Int8));
export var ArrayFloat32 Type = NewArrayTypeStruct(100, Stub("f", Float32));
export var MapStringInt16 Type = NewMapTypeStruct(Stub("s", String), Stub("i", Int16));
export var ChanArray Type = NewChanTypeStruct(RecvDir, Stub("a", ArrayFloat32));
var F1 = Field{"i", Stub("i", Int64)};
var Fields = []Field{F1};
export var Structure = NewStructTypeStruct(&Fields);
export var Function Type = NewFuncTypeStruct(Structure, Structure, Structure);