table.go 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. package lua
  2. const defaultArrayCap = 32
  3. const defaultHashCap = 32
  4. type lValueArraySorter struct {
  5. L *LState
  6. Fn *LFunction
  7. Values []LValue
  8. }
  9. func (lv lValueArraySorter) Len() int {
  10. return len(lv.Values)
  11. }
  12. func (lv lValueArraySorter) Swap(i, j int) {
  13. lv.Values[i], lv.Values[j] = lv.Values[j], lv.Values[i]
  14. }
  15. func (lv lValueArraySorter) Less(i, j int) bool {
  16. if lv.Fn != nil {
  17. lv.L.Push(lv.Fn)
  18. lv.L.Push(lv.Values[i])
  19. lv.L.Push(lv.Values[j])
  20. lv.L.Call(2, 1)
  21. return LVAsBool(lv.L.reg.Pop())
  22. }
  23. return lessThan(lv.L, lv.Values[i], lv.Values[j])
  24. }
  25. func newLTable(acap int, hcap int) *LTable {
  26. if acap < 0 {
  27. acap = 0
  28. }
  29. if hcap < 0 {
  30. hcap = 0
  31. }
  32. tb := &LTable{}
  33. tb.Metatable = LNil
  34. if acap != 0 {
  35. tb.array = make([]LValue, 0, acap)
  36. }
  37. if hcap != 0 {
  38. tb.strdict = make(map[string]LValue, hcap)
  39. }
  40. return tb
  41. }
  42. // Len returns length of this LTable without using __len.
  43. func (tb *LTable) Len() int {
  44. if tb.array == nil {
  45. return 0
  46. }
  47. var prev LValue = LNil
  48. for i := len(tb.array) - 1; i >= 0; i-- {
  49. v := tb.array[i]
  50. if prev == LNil && v != LNil {
  51. return i + 1
  52. }
  53. prev = v
  54. }
  55. return 0
  56. }
  57. // Append appends a given LValue to this LTable.
  58. func (tb *LTable) Append(value LValue) {
  59. if value == LNil {
  60. return
  61. }
  62. if tb.array == nil {
  63. tb.array = make([]LValue, 0, defaultArrayCap)
  64. }
  65. if len(tb.array) == 0 || tb.array[len(tb.array)-1] != LNil {
  66. tb.array = append(tb.array, value)
  67. } else {
  68. i := len(tb.array) - 2
  69. for ; i >= 0; i-- {
  70. if tb.array[i] != LNil {
  71. break
  72. }
  73. }
  74. tb.array[i+1] = value
  75. }
  76. }
  77. // Insert inserts a given LValue at position `i` in this table.
  78. func (tb *LTable) Insert(i int, value LValue) {
  79. if tb.array == nil {
  80. tb.array = make([]LValue, 0, defaultArrayCap)
  81. }
  82. if i > len(tb.array) {
  83. tb.RawSetInt(i, value)
  84. return
  85. }
  86. if i <= 0 {
  87. tb.RawSet(LNumber(i), value)
  88. return
  89. }
  90. i -= 1
  91. tb.array = append(tb.array, LNil)
  92. copy(tb.array[i+1:], tb.array[i:])
  93. tb.array[i] = value
  94. }
  95. // MaxN returns a maximum number key that nil value does not exist before it.
  96. func (tb *LTable) MaxN() int {
  97. if tb.array == nil {
  98. return 0
  99. }
  100. for i := len(tb.array) - 1; i >= 0; i-- {
  101. if tb.array[i] != LNil {
  102. return i + 1
  103. }
  104. }
  105. return 0
  106. }
  107. // Remove removes from this table the element at a given position.
  108. func (tb *LTable) Remove(pos int) LValue {
  109. if tb.array == nil {
  110. return LNil
  111. }
  112. larray := len(tb.array)
  113. if larray == 0 {
  114. return LNil
  115. }
  116. i := pos - 1
  117. oldval := LNil
  118. switch {
  119. case i >= larray:
  120. // nothing to do
  121. case i == larray-1 || i < 0:
  122. oldval = tb.array[larray-1]
  123. tb.array = tb.array[:larray-1]
  124. default:
  125. oldval = tb.array[i]
  126. copy(tb.array[i:], tb.array[i+1:])
  127. tb.array[larray-1] = nil
  128. tb.array = tb.array[:larray-1]
  129. }
  130. return oldval
  131. }
  132. // RawSet sets a given LValue to a given index without the __newindex metamethod.
  133. // It is recommended to use `RawSetString` or `RawSetInt` for performance
  134. // if you already know the given LValue is a string or number.
  135. func (tb *LTable) RawSet(key LValue, value LValue) {
  136. switch v := key.(type) {
  137. case LNumber:
  138. if isArrayKey(v) {
  139. if tb.array == nil {
  140. tb.array = make([]LValue, 0, defaultArrayCap)
  141. }
  142. index := int(v) - 1
  143. alen := len(tb.array)
  144. switch {
  145. case index == alen:
  146. tb.array = append(tb.array, value)
  147. case index > alen:
  148. for i := 0; i < (index - alen); i++ {
  149. tb.array = append(tb.array, LNil)
  150. }
  151. tb.array = append(tb.array, value)
  152. case index < alen:
  153. tb.array[index] = value
  154. }
  155. return
  156. }
  157. case LString:
  158. tb.RawSetString(string(v), value)
  159. return
  160. }
  161. tb.RawSetH(key, value)
  162. }
  163. // RawSetInt sets a given LValue at a position `key` without the __newindex metamethod.
  164. func (tb *LTable) RawSetInt(key int, value LValue) {
  165. if key < 1 || key >= MaxArrayIndex {
  166. tb.RawSetH(LNumber(key), value)
  167. return
  168. }
  169. if tb.array == nil {
  170. tb.array = make([]LValue, 0, 32)
  171. }
  172. index := key - 1
  173. alen := len(tb.array)
  174. switch {
  175. case index == alen:
  176. tb.array = append(tb.array, value)
  177. case index > alen:
  178. for i := 0; i < (index - alen); i++ {
  179. tb.array = append(tb.array, LNil)
  180. }
  181. tb.array = append(tb.array, value)
  182. case index < alen:
  183. tb.array[index] = value
  184. }
  185. }
  186. // RawSetString sets a given LValue to a given string index without the __newindex metamethod.
  187. func (tb *LTable) RawSetString(key string, value LValue) {
  188. if tb.strdict == nil {
  189. tb.strdict = make(map[string]LValue, defaultHashCap)
  190. }
  191. if tb.keys == nil {
  192. tb.keys = []LValue{}
  193. tb.k2i = map[LValue]int{}
  194. }
  195. if value == LNil {
  196. // TODO tb.keys and tb.k2i should also be removed
  197. delete(tb.strdict, key)
  198. } else {
  199. tb.strdict[key] = value
  200. lkey := LString(key)
  201. if _, ok := tb.k2i[lkey]; !ok {
  202. tb.k2i[lkey] = len(tb.keys)
  203. tb.keys = append(tb.keys, lkey)
  204. }
  205. }
  206. }
  207. // RawSetH sets a given LValue to a given index without the __newindex metamethod.
  208. func (tb *LTable) RawSetH(key LValue, value LValue) {
  209. if s, ok := key.(LString); ok {
  210. tb.RawSetString(string(s), value)
  211. return
  212. }
  213. if tb.dict == nil {
  214. tb.dict = make(map[LValue]LValue, len(tb.strdict))
  215. }
  216. if tb.keys == nil {
  217. tb.keys = []LValue{}
  218. tb.k2i = map[LValue]int{}
  219. }
  220. if value == LNil {
  221. // TODO tb.keys and tb.k2i should also be removed
  222. delete(tb.dict, key)
  223. } else {
  224. tb.dict[key] = value
  225. if _, ok := tb.k2i[key]; !ok {
  226. tb.k2i[key] = len(tb.keys)
  227. tb.keys = append(tb.keys, key)
  228. }
  229. }
  230. }
  231. // RawGet returns an LValue associated with a given key without __index metamethod.
  232. func (tb *LTable) RawGet(key LValue) LValue {
  233. switch v := key.(type) {
  234. case LNumber:
  235. if isArrayKey(v) {
  236. if tb.array == nil {
  237. return LNil
  238. }
  239. index := int(v) - 1
  240. if index >= len(tb.array) {
  241. return LNil
  242. }
  243. return tb.array[index]
  244. }
  245. case LString:
  246. if tb.strdict == nil {
  247. return LNil
  248. }
  249. if ret, ok := tb.strdict[string(v)]; ok {
  250. return ret
  251. }
  252. return LNil
  253. }
  254. if tb.dict == nil {
  255. return LNil
  256. }
  257. if v, ok := tb.dict[key]; ok {
  258. return v
  259. }
  260. return LNil
  261. }
  262. // RawGetInt returns an LValue at position `key` without __index metamethod.
  263. func (tb *LTable) RawGetInt(key int) LValue {
  264. if tb.array == nil {
  265. return LNil
  266. }
  267. index := int(key) - 1
  268. if index >= len(tb.array) || index < 0 {
  269. return LNil
  270. }
  271. return tb.array[index]
  272. }
  273. // RawGet returns an LValue associated with a given key without __index metamethod.
  274. func (tb *LTable) RawGetH(key LValue) LValue {
  275. if s, sok := key.(LString); sok {
  276. if tb.strdict == nil {
  277. return LNil
  278. }
  279. if v, vok := tb.strdict[string(s)]; vok {
  280. return v
  281. }
  282. return LNil
  283. }
  284. if tb.dict == nil {
  285. return LNil
  286. }
  287. if v, ok := tb.dict[key]; ok {
  288. return v
  289. }
  290. return LNil
  291. }
  292. // RawGetString returns an LValue associated with a given key without __index metamethod.
  293. func (tb *LTable) RawGetString(key string) LValue {
  294. if tb.strdict == nil {
  295. return LNil
  296. }
  297. if v, vok := tb.strdict[string(key)]; vok {
  298. return v
  299. }
  300. return LNil
  301. }
  302. // ForEach iterates over this table of elements, yielding each in turn to a given function.
  303. func (tb *LTable) ForEach(cb func(LValue, LValue)) {
  304. if tb.array != nil {
  305. for i, v := range tb.array {
  306. if v != LNil {
  307. cb(LNumber(i+1), v)
  308. }
  309. }
  310. }
  311. if tb.strdict != nil {
  312. for k, v := range tb.strdict {
  313. if v != LNil {
  314. cb(LString(k), v)
  315. }
  316. }
  317. }
  318. if tb.dict != nil {
  319. for k, v := range tb.dict {
  320. if v != LNil {
  321. cb(k, v)
  322. }
  323. }
  324. }
  325. }
  326. // This function is equivalent to lua_next ( http://www.lua.org/manual/5.1/manual.html#lua_next ).
  327. func (tb *LTable) Next(key LValue) (LValue, LValue) {
  328. init := false
  329. if key == LNil {
  330. key = LNumber(0)
  331. init = true
  332. }
  333. if init || key != LNumber(0) {
  334. if kv, ok := key.(LNumber); ok && isInteger(kv) && int(kv) >= 0 && kv < LNumber(MaxArrayIndex) {
  335. index := int(kv)
  336. if tb.array != nil {
  337. for ; index < len(tb.array); index++ {
  338. if v := tb.array[index]; v != LNil {
  339. return LNumber(index + 1), v
  340. }
  341. }
  342. }
  343. if tb.array == nil || index == len(tb.array) {
  344. if (tb.dict == nil || len(tb.dict) == 0) && (tb.strdict == nil || len(tb.strdict) == 0) {
  345. return LNil, LNil
  346. }
  347. key = tb.keys[0]
  348. if v := tb.RawGetH(key); v != LNil {
  349. return key, v
  350. }
  351. }
  352. }
  353. }
  354. for i := tb.k2i[key] + 1; i < len(tb.keys); i++ {
  355. key := tb.keys[i]
  356. if v := tb.RawGetH(key); v != LNil {
  357. return key, v
  358. }
  359. }
  360. return LNil, LNil
  361. }