github.com/hirochachacha/plua@v0.0.0-20170217012138-c82f520cc725/object/reflect/uint.go (about) 1 package reflect 2 3 import ( 4 "reflect" 5 6 "github.com/hirochachacha/plua/internal/tables" 7 "github.com/hirochachacha/plua/object" 8 "github.com/hirochachacha/plua/object/fnutil" 9 ) 10 11 // uintptr also supportted 12 func buildUintMT() { 13 mt := tables.NewTableSize(0, 20) 14 15 mt.Set(object.TM_METATABLE, object.True) 16 mt.Set(object.TM_NAME, object.String("UINT*")) 17 mt.Set(object.TM_TOSTRING, tostring(toUint)) 18 mt.Set(object.TM_INDEX, index(toUint)) 19 20 mt.Set(object.TM_EQ, cmp(func(x, y reflect.Value) bool { return x.Uint() == y.Uint() }, toUint)) 21 mt.Set(object.TM_LT, cmp(func(x, y reflect.Value) bool { return x.Uint() < y.Uint() }, toUint)) 22 mt.Set(object.TM_LE, cmp(func(x, y reflect.Value) bool { return x.Uint() <= y.Uint() }, toUint)) 23 24 mt.Set(object.TM_UNM, unary(func(x reflect.Value) reflect.Value { return reflect.ValueOf(-x.Uint()) }, toUint, mt)) 25 mt.Set(object.TM_BNOT, unary(func(x reflect.Value) reflect.Value { return reflect.ValueOf(^x.Uint()) }, toUint, mt)) 26 27 mt.Set(object.TM_ADD, binary(func(x, y reflect.Value) (reflect.Value, *object.RuntimeError) { 28 return reflect.ValueOf(x.Uint() + y.Uint()), nil 29 }, toUint, mt)) 30 mt.Set(object.TM_SUB, binary(func(x, y reflect.Value) (reflect.Value, *object.RuntimeError) { 31 return reflect.ValueOf(x.Uint() - y.Uint()), nil 32 }, toUint, mt)) 33 mt.Set(object.TM_MUL, binary(func(x, y reflect.Value) (reflect.Value, *object.RuntimeError) { 34 return reflect.ValueOf(x.Uint() * y.Uint()), nil 35 }, toUint, mt)) 36 mt.Set(object.TM_MOD, binary(func(x, y reflect.Value) (reflect.Value, *object.RuntimeError) { 37 z, err := umod(x.Uint(), y.Uint()) 38 return reflect.ValueOf(z), err 39 }, toUint, mt)) 40 mt.Set(object.TM_POW, binary(func(x, y reflect.Value) (reflect.Value, *object.RuntimeError) { 41 return reflect.ValueOf(upow(x.Uint(), y.Uint())), nil 42 }, toUint, mt)) 43 mt.Set(object.TM_DIV, binary(func(x, y reflect.Value) (reflect.Value, *object.RuntimeError) { 44 z, err := udiv(x.Uint(), y.Uint()) 45 return reflect.ValueOf(z), err 46 }, toUint, mt)) 47 mt.Set(object.TM_IDIV, binary(func(x, y reflect.Value) (reflect.Value, *object.RuntimeError) { 48 z, err := udiv(x.Uint(), y.Uint()) 49 return reflect.ValueOf(z), err 50 }, toUint, mt)) 51 mt.Set(object.TM_BAND, binary(func(x, y reflect.Value) (reflect.Value, *object.RuntimeError) { 52 return reflect.ValueOf(x.Uint() & y.Uint()), nil 53 }, toUint, mt)) 54 mt.Set(object.TM_BOR, binary(func(x, y reflect.Value) (reflect.Value, *object.RuntimeError) { 55 return reflect.ValueOf(x.Uint() | y.Uint()), nil 56 }, toUint, mt)) 57 mt.Set(object.TM_BXOR, binary(func(x, y reflect.Value) (reflect.Value, *object.RuntimeError) { 58 return reflect.ValueOf(x.Uint() ^ y.Uint()), nil 59 }, toUint, mt)) 60 mt.Set(object.TM_SHL, binary(func(x, y reflect.Value) (reflect.Value, *object.RuntimeError) { 61 return reflect.ValueOf(x.Uint() << y.Uint()), nil 62 }, toUint, mt)) 63 mt.Set(object.TM_SHR, binary(func(x, y reflect.Value) (reflect.Value, *object.RuntimeError) { 64 return reflect.ValueOf(x.Uint() >> y.Uint()), nil 65 }, toUint, mt)) 66 67 uintMT = mt 68 } 69 70 func toUint(ap *fnutil.ArgParser, n int) (reflect.Value, *object.RuntimeError) { 71 if i64, err := ap.ToGoInt64(n); err == nil { 72 return reflect.ValueOf(uint64(i64)), nil 73 } 74 val, err := toValue(ap, n, "UINT*") 75 if err != nil { 76 return reflect.Value{}, err 77 } 78 switch val.Kind() { 79 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 80 default: 81 return reflect.Value{}, ap.TypeError(n, "UINT*") 82 } 83 return val, nil 84 } 85 86 func upow(x, y uint64) uint64 { 87 prod := uint64(1) 88 for y != 0 { 89 if y&1 != 0 { 90 prod *= x 91 } 92 y >>= 1 93 x *= x 94 } 95 return prod 96 } 97 98 func umod(x, y uint64) (uint64, *object.RuntimeError) { 99 if y == 0 { 100 return 0, &object.RuntimeError{ 101 RawValue: object.String("integer divide by zero"), 102 } 103 } 104 105 rem := x % y 106 107 return rem, nil 108 } 109 110 func udiv(x, y uint64) (uint64, *object.RuntimeError) { 111 if y == 0 { 112 return 0, &object.RuntimeError{ 113 RawValue: object.String("integer divide by zero"), 114 } 115 } 116 117 return x / y, nil 118 }