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 }