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  }