summaryrefslogtreecommitdiff
path: root/usr/r
diff options
context:
space:
mode:
authorRob Pike <r@golang.org>2008-10-15 17:11:51 -0700
committerRob Pike <r@golang.org>2008-10-15 17:11:51 -0700
commitc5864b86e6d7aa686eb8f40ef37a7a44626b0f65 (patch)
tree6cd1dda76eaa8d077c849e36ba3ee9b48e3c5776 /usr/r
parent995a1aa3367f11d7bc3e7fb78629c43aeacdda70 (diff)
downloadgolang-c5864b86e6d7aa686eb8f40ef37a7a44626b0f65.tar.gz
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
Diffstat (limited to 'usr/r')
-rw-r--r--usr/r/reflect/Makefile47
-rw-r--r--usr/r/reflect/main.go31
-rw-r--r--usr/r/reflect/print.go101
-rw-r--r--usr/r/reflect/type.go292
4 files changed, 471 insertions, 0 deletions
diff --git a/usr/r/reflect/Makefile b/usr/r/reflect/Makefile
new file mode 100644
index 000000000..626ab5caf
--- /dev/null
+++ b/usr/r/reflect/Makefile
@@ -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
+
diff --git a/usr/r/reflect/main.go b/usr/r/reflect/main.go
new file mode 100644
index 000000000..c4f5783d1
--- /dev/null
+++ b/usr/r/reflect/main.go
@@ -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");
+}
diff --git a/usr/r/reflect/print.go b/usr/r/reflect/print.go
new file mode 100644
index 000000000..beb9407cc
--- /dev/null
+++ b/usr/r/reflect/print.go
@@ -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());
+ }
+}
diff --git a/usr/r/reflect/type.go b/usr/r/reflect/type.go
new file mode 100644
index 000000000..6d3f1440c
--- /dev/null
+++ b/usr/r/reflect/type.go
@@ -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);