mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-07 12:33:42 +00:00
reflect: add support for non-named basic types
This commit is contained in:
+51
-3
@@ -26,6 +26,8 @@ const (
|
||||
Float64
|
||||
Complex64
|
||||
Complex128
|
||||
String
|
||||
UnsafePointer
|
||||
Array
|
||||
Chan
|
||||
Func
|
||||
@@ -33,11 +35,52 @@ const (
|
||||
Map
|
||||
Ptr
|
||||
Slice
|
||||
String
|
||||
Struct
|
||||
UnsafePointer
|
||||
)
|
||||
|
||||
func (k Kind) String() string {
|
||||
switch k {
|
||||
case Bool:
|
||||
return "bool"
|
||||
case Int:
|
||||
return "int"
|
||||
case Int8:
|
||||
return "int8"
|
||||
case Int16:
|
||||
return "int16"
|
||||
case Int32:
|
||||
return "int32"
|
||||
case Int64:
|
||||
return "int64"
|
||||
case Uint:
|
||||
return "uint"
|
||||
case Uint8:
|
||||
return "uint8"
|
||||
case Uint16:
|
||||
return "uint16"
|
||||
case Uint32:
|
||||
return "uint32"
|
||||
case Uint64:
|
||||
return "uint64"
|
||||
case Uintptr:
|
||||
return "uintptr"
|
||||
case Float32:
|
||||
return "float32"
|
||||
case Float64:
|
||||
return "float64"
|
||||
case Complex64:
|
||||
return "complex64"
|
||||
case Complex128:
|
||||
return "complex128"
|
||||
case String:
|
||||
return "string"
|
||||
case UnsafePointer:
|
||||
return "unsafe.Pointer"
|
||||
default:
|
||||
return "T"
|
||||
}
|
||||
}
|
||||
|
||||
// The typecode as used in an interface{}.
|
||||
type Type uintptr
|
||||
|
||||
@@ -50,7 +93,12 @@ func (t Type) String() string {
|
||||
}
|
||||
|
||||
func (t Type) Kind() Kind {
|
||||
return Invalid // TODO
|
||||
if t & 1 == 0 {
|
||||
// Basic type
|
||||
return Kind(t >> 1)
|
||||
} else {
|
||||
return Invalid // TODO
|
||||
}
|
||||
}
|
||||
|
||||
func (t Type) Elem() Type {
|
||||
|
||||
+127
-7
@@ -33,7 +33,14 @@ func (v Value) IsNil() bool {
|
||||
}
|
||||
|
||||
func (v Value) Pointer() uintptr {
|
||||
panic("unimplemented: (reflect.Value).Pointer()")
|
||||
switch v.Type().Kind() {
|
||||
case UnsafePointer:
|
||||
return uintptr(v.value)
|
||||
case Chan, Func, Map, Ptr, Slice:
|
||||
panic("unimplemented: (reflect.Value).Pointer()")
|
||||
default:
|
||||
panic(&ValueError{"Pointer"})
|
||||
}
|
||||
}
|
||||
|
||||
func (v Value) IsValid() bool {
|
||||
@@ -57,27 +64,132 @@ func (v Value) CanSet() bool {
|
||||
}
|
||||
|
||||
func (v Value) Bool() bool {
|
||||
panic("unimplemented: (reflect.Value).Bool()")
|
||||
switch v.Type().Kind() {
|
||||
case Bool:
|
||||
return uintptr(v.value) != 0
|
||||
default:
|
||||
panic(&ValueError{"Bool"})
|
||||
}
|
||||
}
|
||||
|
||||
func (v Value) Int() int64 {
|
||||
panic("unimplemented: (reflect.Value).Int()")
|
||||
switch v.Type().Kind() {
|
||||
case Int:
|
||||
if unsafe.Sizeof(int(0)) <= unsafe.Sizeof(uintptr(0)) {
|
||||
return int64(int(uintptr(v.value)))
|
||||
} else {
|
||||
return int64(*(*int)(v.value))
|
||||
}
|
||||
case Int8:
|
||||
return int64(int8(uintptr(v.value)))
|
||||
case Int16:
|
||||
return int64(int16(uintptr(v.value)))
|
||||
case Int32:
|
||||
if unsafe.Sizeof(int32(0)) <= unsafe.Sizeof(uintptr(0)) {
|
||||
return int64(int32(uintptr(v.value)))
|
||||
} else {
|
||||
return int64(*(*int32)(v.value))
|
||||
}
|
||||
return int64(uintptr(v.value))
|
||||
case Int64:
|
||||
if unsafe.Sizeof(int64(0)) <= unsafe.Sizeof(uintptr(0)) {
|
||||
return int64(uintptr(v.value))
|
||||
} else {
|
||||
return *(*int64)(v.value)
|
||||
}
|
||||
default:
|
||||
panic(&ValueError{"Int"})
|
||||
}
|
||||
}
|
||||
|
||||
func (v Value) Uint() uint64 {
|
||||
panic("unimplemented: (reflect.Value).Uint()")
|
||||
switch v.Type().Kind() {
|
||||
case Uintptr, Uint8, Uint16:
|
||||
return uint64(uintptr(v.value))
|
||||
case Uint:
|
||||
if unsafe.Sizeof(uint(0)) <= unsafe.Sizeof(uintptr(0)) {
|
||||
return uint64(uintptr(v.value))
|
||||
} else {
|
||||
// For systems with 16-bit pointers.
|
||||
return uint64(*(*uint)(v.value))
|
||||
}
|
||||
case Uint32:
|
||||
if unsafe.Sizeof(uint32(0)) <= unsafe.Sizeof(uintptr(0)) {
|
||||
return uint64(uintptr(v.value))
|
||||
} else {
|
||||
// For systems with 16-bit pointers.
|
||||
return uint64(*(*uint32)(v.value))
|
||||
}
|
||||
case Uint64:
|
||||
if unsafe.Sizeof(uint64(0)) <= unsafe.Sizeof(uintptr(0)) {
|
||||
return uint64(uintptr(v.value))
|
||||
} else {
|
||||
// For systems with 16-bit or 32-bit pointers.
|
||||
return *(*uint64)(v.value)
|
||||
}
|
||||
default:
|
||||
panic(&ValueError{"Uint"})
|
||||
}
|
||||
}
|
||||
|
||||
func (v Value) Float() float64 {
|
||||
panic("unimplemented: (reflect.Value).Float()")
|
||||
switch v.Type().Kind() {
|
||||
case Float32:
|
||||
if unsafe.Sizeof(float32(0)) <= unsafe.Sizeof(uintptr(0)) {
|
||||
// The float is directly stored in the interface value on systems
|
||||
// with 32-bit and 64-bit pointers.
|
||||
return float64(*(*float32)(unsafe.Pointer(&v.value)))
|
||||
} else {
|
||||
// The float is stored as an external value on systems with 16-bit
|
||||
// pointers.
|
||||
return float64(*(*float32)(v.value))
|
||||
}
|
||||
case Float64:
|
||||
if unsafe.Sizeof(float64(0)) <= unsafe.Sizeof(uintptr(0)) {
|
||||
// The float is directly stored in the interface value on systems
|
||||
// with 64-bit pointers.
|
||||
return *(*float64)(unsafe.Pointer(&v.value))
|
||||
} else {
|
||||
// For systems with 16-bit and 32-bit pointers.
|
||||
return *(*float64)(v.value)
|
||||
}
|
||||
default:
|
||||
panic(&ValueError{"Float"})
|
||||
}
|
||||
}
|
||||
|
||||
func (v Value) Complex() complex128 {
|
||||
panic("unimplemented: (reflect.Value).Complex()")
|
||||
switch v.Type().Kind() {
|
||||
case Complex64:
|
||||
if unsafe.Sizeof(complex64(0)) <= unsafe.Sizeof(uintptr(0)) {
|
||||
// The complex number is directly stored in the interface value on
|
||||
// systems with 64-bit pointers.
|
||||
return complex128(*(*complex64)(unsafe.Pointer(&v.value)))
|
||||
} else {
|
||||
// The complex number is stored as an external value on systems with
|
||||
// 16-bit and 32-bit pointers.
|
||||
return complex128(*(*complex64)(v.value))
|
||||
}
|
||||
case Complex128:
|
||||
// This is a 128-bit value, which is always stored as an external value.
|
||||
// It may be stored in the pointer directly on very uncommon
|
||||
// architectures with 128-bit pointers, however.
|
||||
return *(*complex128)(v.value)
|
||||
default:
|
||||
panic(&ValueError{"Complex"})
|
||||
}
|
||||
}
|
||||
|
||||
func (v Value) String() string {
|
||||
panic("unimplemented: (reflect.Value).String()")
|
||||
switch v.Type().Kind() {
|
||||
case String:
|
||||
// A string value is always bigger than a pointer as it is made of a
|
||||
// pointer and a length.
|
||||
return *(*string)(v.value)
|
||||
default:
|
||||
// Special case because of the special treatment of .String() in Go.
|
||||
return "<T>"
|
||||
}
|
||||
}
|
||||
|
||||
func (v Value) Bytes() []byte {
|
||||
@@ -147,3 +259,11 @@ func (v Value) SetString(x string) {
|
||||
func MakeSlice(typ Type, len, cap int) Value {
|
||||
panic("unimplemented: reflect.MakeSlice()")
|
||||
}
|
||||
|
||||
type ValueError struct {
|
||||
Method string
|
||||
}
|
||||
|
||||
func (e *ValueError) Error() string {
|
||||
return "reflect: call of reflect.Value." + e.Method + " on invalid type"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user