diff options
author | Rob Pike <r@golang.org> | 2008-10-15 17:11:51 -0700 |
---|---|---|
committer | Rob Pike <r@golang.org> | 2008-10-15 17:11:51 -0700 |
commit | c5864b86e6d7aa686eb8f40ef37a7a44626b0f65 (patch) | |
tree | 6cd1dda76eaa8d077c849e36ba3ee9b48e3c5776 /usr/r | |
parent | 995a1aa3367f11d7bc3e7fb78629c43aeacdda70 (diff) | |
download | golang-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/Makefile | 47 | ||||
-rw-r--r-- | usr/r/reflect/main.go | 31 | ||||
-rw-r--r-- | usr/r/reflect/print.go | 101 | ||||
-rw-r--r-- | usr/r/reflect/type.go | 292 |
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); |