github.com/dfcfw/lua@v0.0.0-20230325031207-0cc7ffb7b8b9/luar/type.go (about) 1 package luar 2 3 import ( 4 "reflect" 5 6 "github.com/dfcfw/lua" 7 ) 8 9 func checkType(L *lua.LState, idx int) reflect.Type { 10 ud := L.CheckUserData(idx) 11 return ud.Value.(reflect.Type) 12 } 13 14 func typeCall(L *lua.LState) int { 15 ref := checkType(L, 1) 16 17 var value reflect.Value 18 switch ref.Kind() { 19 case reflect.Chan: 20 buffer := L.OptInt(2, 0) 21 22 if buffer < 0 { 23 L.ArgError(2, "negative buffer size") 24 } 25 if ref.ChanDir() != reflect.BothDir { 26 L.RaiseError("unidirectional channel type") 27 } 28 29 value = reflect.MakeChan(ref, buffer) 30 case reflect.Map: 31 value = reflect.MakeMap(ref) 32 case reflect.Slice: 33 length := L.OptInt(2, 0) 34 capacity := L.OptInt(3, length) 35 36 if length < 0 { 37 L.ArgError(2, "negative length") 38 } 39 if capacity < 0 { 40 L.ArgError(3, "negative capacity") 41 } 42 if length > capacity { 43 L.RaiseError("length > capacity") 44 } 45 46 value = reflect.MakeSlice(ref, length, capacity) 47 default: 48 value = reflect.New(ref) 49 } 50 L.Push(New(L, value.Interface())) 51 return 1 52 } 53 54 func typeEq(L *lua.LState) int { 55 type1 := checkType(L, 1) 56 type2 := checkType(L, 2) 57 L.Push(lua.LBool(type1 == type2)) 58 return 1 59 }