diff options
| author | Marc Vertes <mvertes@free.fr> | 2024-03-08 19:29:34 +0100 |
|---|---|---|
| committer | Marc Vertes <mvertes@free.fr> | 2024-03-08 19:29:34 +0100 |
| commit | 8c4fa9d85cd274439dbd7d0a5c699fe1cea557dc (patch) | |
| tree | a8c910cf13aa06e61ee2db40b5dd2f1f63a25b9d /vm/type.go | |
| parent | 828cfd1c8da5e243fd0f34530fb1a7faab49784e (diff) | |
feat: add type representation in vm package
Type and Value types in vm package are now used in place of reflect.Type
and reflect.Value. It allows to remove the dependency on reflect for
parser and compiler packages.
The main purpose of Type is to provide a solution to implement recursive
structs, named types, interfaces and methods, despite the limitations of
Go reflect. The goal is to provide the thinnest layer around reflect.
Diffstat (limited to 'vm/type.go')
| -rw-r--r-- | vm/type.go | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/vm/type.go b/vm/type.go new file mode 100644 index 0000000..d29de48 --- /dev/null +++ b/vm/type.go @@ -0,0 +1,74 @@ +package vm + +import "reflect" + +// Runtime type and value representations (based on reflect). + +// Type is the representation of a runtime type. +type Type struct { + Name string + Rtype reflect.Type +} + +func (t *Type) Elem() *Type { + return &Type{Rtype: t.Rtype.Elem()} +} + +func (t *Type) Out(i int) *Type { + return &Type{Rtype: t.Rtype.Out(i)} +} + +// Value is the representation of a runtime value. +type Value struct { + Type *Type + Data reflect.Value +} + +// NewValue returns an addressable zero value for the specified type. +func NewValue(typ *Type) Value { + return Value{Type: typ, Data: reflect.New(typ.Rtype).Elem()} +} + +// TypeOf returns the runtime type of v. +func TypeOf(v any) *Type { + t := reflect.TypeOf(v) + return &Type{Name: t.Name(), Rtype: t} +} + +// ValueOf returns the runtime value of v. +func ValueOf(v any) Value { + return Value{Data: reflect.ValueOf(v)} +} + +func PointerTo(t *Type) *Type { + return &Type{Rtype: reflect.PointerTo(t.Rtype)} +} + +func ArrayOf(size int, t *Type) *Type { + return &Type{Rtype: reflect.ArrayOf(size, t.Rtype)} +} + +func SliceOf(t *Type) *Type { + return &Type{Rtype: reflect.SliceOf(t.Rtype)} +} + +func FuncOf(arg, ret []*Type, variadic bool) *Type { + a := make([]reflect.Type, len(arg)) + for i, e := range arg { + a[i] = e.Rtype + } + r := make([]reflect.Type, len(ret)) + for i, e := range ret { + r[i] = e.Rtype + } + return &Type{Rtype: reflect.FuncOf(a, r, variadic)} +} + +func StructOf(fields []*Type) *Type { + rf := make([]reflect.StructField, len(fields)) + for i, f := range fields { + rf[i].Name = "X" + f.Name + rf[i].Type = f.Rtype + } + return &Type{Rtype: reflect.StructOf(rf)} +} |
