github.com/hirochachacha/plua@v0.0.0-20170217012138-c82f520cc725/object/reflect/iface.go (about)

     1  package reflect
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  
     7  	"github.com/hirochachacha/plua/internal/tables"
     8  	"github.com/hirochachacha/plua/object"
     9  	"github.com/hirochachacha/plua/object/fnutil"
    10  )
    11  
    12  func buildIfaceMT() {
    13  	mt := tables.NewTableSize(0, 4)
    14  
    15  	mt.Set(object.TM_METATABLE, object.True)
    16  	mt.Set(object.TM_NAME, object.String("IFACE*"))
    17  	mt.Set(object.TM_TOSTRING, object.GoFunction(itostring))
    18  
    19  	mt.Set(object.TM_INDEX, object.GoFunction(iindex))
    20  
    21  	mt.Set(object.TM_EQ, cmp(func(x, y reflect.Value) bool { return x.Interface() == y.Interface() }, toIface))
    22  
    23  	ifaceMT = mt
    24  }
    25  
    26  func toIface(ap *fnutil.ArgParser, n int) (reflect.Value, *object.RuntimeError) {
    27  	val, err := toValue(ap, n, "IFACE*")
    28  	if err != nil {
    29  		return reflect.Value{}, err
    30  	}
    31  	if val.Kind() != reflect.Interface {
    32  		return reflect.Value{}, ap.TypeError(n, "IFACE*")
    33  	}
    34  	return val, nil
    35  }
    36  
    37  func itostring(th object.Thread, args ...object.Value) ([]object.Value, *object.RuntimeError) {
    38  	ap := fnutil.NewArgParser(th, args)
    39  
    40  	i, err := toIface(ap, 0)
    41  	if err != nil {
    42  		return nil, err
    43  	}
    44  
    45  	return []object.Value{object.String(fmt.Sprintf("go interface (0x%x)", i.Pointer()))}, nil
    46  }
    47  
    48  func iindex(th object.Thread, args ...object.Value) ([]object.Value, *object.RuntimeError) {
    49  	ap := fnutil.NewArgParser(th, args)
    50  
    51  	i, err := toIface(ap, 0)
    52  	if err != nil {
    53  		return nil, err
    54  	}
    55  
    56  	name, err := ap.ToGoString(1)
    57  	if err != nil {
    58  		return nil, err
    59  	}
    60  
    61  	if !isPublic(name) {
    62  		return nil, nil
    63  	}
    64  
    65  	method := i.MethodByName(name)
    66  
    67  	if method.IsValid() {
    68  		return []object.Value{valueOfReflect(method, false)}, nil
    69  	}
    70  
    71  	return nil, nil
    72  }