github.com/shawnclovie/gopher-lua@v0.0.0-20200520092726-90b44ec0e2f2/tablelib.go (about) 1 package lua 2 3 import ( 4 "sort" 5 ) 6 7 func OpenTable(L *LState) int { 8 tabmod := L.RegisterModule(TabLibName, tableFuncs) 9 L.Push(tabmod) 10 return 1 11 } 12 13 var tableFuncs = map[string]LGFunction{ 14 "getn": tableGetN, 15 "concat": tableConcat, 16 "insert": tableInsert, 17 "maxn": tableMaxN, 18 "remove": tableRemove, 19 "sort": tableSort, 20 } 21 22 func tableSort(L *LState) int { 23 tbl := L.CheckTable(1) 24 sorter := lValueArraySorter{L, nil, tbl.array} 25 if L.GetTop() != 1 { 26 sorter.Fn = L.CheckFunction(2) 27 } 28 sort.Sort(sorter) 29 return 0 30 } 31 32 func tableGetN(L *LState) int { 33 L.Push(LNumber(L.CheckTable(1).Len())) 34 return 1 35 } 36 37 func tableMaxN(L *LState) int { 38 L.Push(LNumber(L.CheckTable(1).MaxN())) 39 return 1 40 } 41 42 func tableRemove(L *LState) int { 43 tbl := L.CheckTable(1) 44 if L.GetTop() == 1 { 45 L.Push(tbl.Remove(-1)) 46 } else { 47 L.Push(tbl.Remove(L.CheckInt(2))) 48 } 49 return 1 50 } 51 52 func tableConcat(L *LState) int { 53 tbl := L.CheckTable(1) 54 sep := LString(L.OptString(2, "")) 55 i := L.OptInt(3, 1) 56 j := L.OptInt(4, tbl.Len()) 57 if L.GetTop() == 3 { 58 if i > tbl.Len() || i < 1 { 59 L.Push(emptyLString) 60 return 1 61 } 62 } 63 i = intMax(intMin(i, tbl.Len()), 1) 64 j = intMin(intMin(j, tbl.Len()), tbl.Len()) 65 if i > j { 66 L.Push(emptyLString) 67 return 1 68 } 69 //TODO should flushing? 70 retbottom := L.GetTop() 71 for ; i <= j; i++ { 72 v := tbl.RawGetInt(i) 73 if !LVCanConvToString(v) { 74 L.RaiseError("invalid value (%s) at index %d in table for concat", v.Type().String(), i) 75 } 76 L.Push(v) 77 if i != j { 78 L.Push(sep) 79 } 80 } 81 L.Push(stringConcat(L, L.GetTop()-retbottom, L.reg.Top()-1)) 82 return 1 83 } 84 85 func tableInsert(L *LState) int { 86 tbl := L.CheckTable(1) 87 nargs := L.GetTop() 88 if nargs == 1 { 89 L.RaiseError("wrong number of arguments") 90 } 91 92 if L.GetTop() == 2 { 93 tbl.Append(L.Get(2)) 94 return 0 95 } 96 tbl.Insert(int(L.CheckInt(2)), L.CheckAny(3)) 97 return 0 98 } 99 100 //