github.com/dfcfw/lua@v0.0.0-20230325031207-0cc7ffb7b8b9/luar/slice.go (about) 1 package luar 2 3 import ( 4 "reflect" 5 6 "github.com/dfcfw/lua" 7 ) 8 9 func sliceIndex(L *lua.LState) int { 10 ref, mt := check(L, 1) 11 key := L.CheckAny(2) 12 13 switch converted := key.(type) { 14 case lua.LNumber: 15 index := int(converted) 16 if index < 1 || index > ref.Len() { 17 L.ArgError(2, "index out of range") 18 } 19 val := ref.Index(index - 1) 20 if (val.Kind() == reflect.Struct || val.Kind() == reflect.Array) && val.CanAddr() { 21 val = val.Addr() 22 } 23 L.Push(New(L, val.Interface())) 24 case lua.LString: 25 if fn := mt.method(string(converted)); fn != nil { 26 L.Push(fn) 27 return 1 28 } 29 return 0 30 default: 31 L.ArgError(2, "must be a number or string") 32 } 33 return 1 34 } 35 36 func sliceNewIndex(L *lua.LState) int { 37 ref, _ := check(L, 1) 38 index := L.CheckInt(2) 39 value := L.CheckAny(3) 40 41 if index < 1 || index > ref.Len() { 42 L.ArgError(2, "index out of range") 43 } 44 val, err := lValueToReflect(L, value, ref.Type().Elem(), nil) 45 if err != nil { 46 L.ArgError(3, err.Error()) 47 } 48 ref.Index(index - 1).Set(val) 49 return 0 50 } 51 52 func sliceLen(L *lua.LState) int { 53 ref, _ := check(L, 1) 54 55 L.Push(lua.LNumber(ref.Len())) 56 return 1 57 } 58 59 func sliceCall(L *lua.LState) int { 60 ref, _ := check(L, 1) 61 62 i := 0 63 fn := func(L *lua.LState) int { 64 if i >= ref.Len() { 65 return 0 66 } 67 item := ref.Index(i).Interface() 68 L.Push(lua.LNumber(i + 1)) 69 L.Push(New(L, item)) 70 i++ 71 return 2 72 } 73 74 L.Push(L.NewFunction(fn)) 75 return 1 76 } 77 78 func sliceAdd(L *lua.LState) int { 79 ref, _ := check(L, 1) 80 item := L.CheckAny(2) 81 82 hint := ref.Type().Elem() 83 value, err := lValueToReflect(L, item, hint, nil) 84 if err != nil { 85 L.ArgError(2, err.Error()) 86 } 87 88 ref = reflect.Append(ref, value) 89 L.Push(New(L, ref.Interface())) 90 return 1 91 }