1 # Copyright (C) 2005-2008, The Perl Foundation.
6 lib/luatable.pir - Lua Table Library
10 This library provides generic functions for table manipulation. It provides
11 all its functions inside the table C<table>.
13 Most functions in the table library assume that the table represents an
14 array or a list. For these functions, when we talk about the "length" of a
15 table we mean the result of the length operator.
17 See "Lua 5.1 Reference Manual", section 5.5 "Table Manipulation",
18 L<http://www.lua.org/manual/5.1/manual.html#5.5>.
26 .HLL 'Lua', 'lua_group'
27 .namespace [ 'Lua::table' ]
30 # print "init Lua Table\n"
32 .local pmc _lua__GLOBAL
33 _lua__GLOBAL = get_hll_global '_G'
37 new _table, 'LuaTable'
39 _lua__GLOBAL[$P1] = _table
41 lua_register($P1, _table)
43 .const .Sub _table_concat = 'concat'
44 _table_concat.'setfenv'(_lua__GLOBAL)
46 _table[$P1] = _table_concat
48 .const .Sub _table_foreach = 'foreach'
49 _table_foreach.'setfenv'(_lua__GLOBAL)
51 _table[$P1] = _table_foreach
53 .const .Sub _table_foreachi = 'foreachi'
54 _table_foreachi.'setfenv'(_lua__GLOBAL)
56 _table[$P1] = _table_foreachi
59 .const .Sub _table_getn = 'getn'
60 _table_getn.'setfenv'(_lua__GLOBAL)
62 _table[$P1] = _table_getn
64 .const .Sub _table_insert = 'insert'
65 _table_insert.'setfenv'(_lua__GLOBAL)
67 _table[$P1] = _table_insert
69 .const .Sub _table_maxn = 'maxn'
70 _table_maxn.'setfenv'(_lua__GLOBAL)
72 _table[$P1] = _table_maxn
74 .const .Sub _table_remove = 'remove'
75 _table_remove.'setfenv'(_lua__GLOBAL)
77 _table[$P1] = _table_remove
79 .const .Sub _table_setn = 'setn'
80 _table_setn.'setfenv'(_lua__GLOBAL)
82 _table[$P1] = _table_setn
84 .const .Sub _table_sort = 'sort'
85 _table_sort.'setfenv'(_lua__GLOBAL)
87 _table[$P1] = _table_sort
91 =item C<table.concat (table [, sep [, i [, j]]])>
93 Returns C<table[i]..sep..table[i+1] ... sep..table[j]>. The default value for
94 C<sep> is the empty string, the default for C<i> is 1, and the default for
95 C<j> is the length of the table. If C<i> is greater than C<j>, returns the
98 Returns C<table[i]..sep..table[i+1] ... sep..table[j]>. The default value for
103 .param pmc table :optional
104 .param pmc sep :optional
105 .param pmc i :optional
106 .param pmc j :optional
107 .param pmc extra :slurpy
112 $S2 = lua_optstring(2, sep, '')
113 lua_checktype(1, table, 'table')
114 $I3 = lua_optint(3, i, 1)
116 last = lua_optint(4, j, $I0)
120 unless $I3 <= last goto L2
122 value = table.'rawget'(idx)
123 $I0 = isa value, 'LuaString'
125 $I0 = isa value, 'LuaNumber'
127 lua_argerror(1, "table contains non-strings")
131 unless $I3 != last goto L4
143 =item C<table.foreach (table, f)>
145 Executes the given C<f> over all elements of C<table>. For each element, C<f>
146 is called with the index and respective value as arguments. If C<f> returns
147 a non-B<nil> value, then the loop is broken, and this value is returned as
148 the final value of C<foreach>.
150 See the C<next> function for extra information about table traversals.
157 .param pmc table :optional
158 .param pmc f :optional
159 .param pmc extra :slurpy
163 lua_checktype(1, table, 'table')
164 lua_checktype(2, f, 'function')
167 $P0 = table.'next'(idx)
171 (res) = f(idx, value)
180 =item C<table.foreachi (table, f)>
182 Executes the given C<f> over the numerical indices of C<table>. For each
183 index, C<f> is called with the index and respective value as arguments.
184 Indices are visited in sequential order, from 1 to C<n>, where C<n> is the
185 size of the table. If C<f> returns a non-B<nil> value, then the loop is
186 broken and this value is returned as the result of C<foreachi>.
192 .sub 'foreachi' :anon
193 .param pmc table :optional
194 .param pmc f :optional
195 .param pmc extra :slurpy
201 lua_checktype(1, table, 'table')
202 lua_checktype(2, f, 'function')
208 unless i <= n goto L2
210 value = table.'rawget'(idx)
211 (res) = f(idx, value)
220 =item C<table.getn (table)>
222 Returns the size of a table.
229 .param pmc table :optional
230 .param pmc extra :slurpy
232 lua_checktype(1, table, 'table')
238 =item C<table.insert (table, [pos,] value)>
240 Inserts element C<value> at position C<pos> in C<table>, shifting up other
241 elements to open space, if necessary. The default value for C<pos> is C<n+1>,
242 where C<n> is the length of the table, so that a call C<table.insert(t,x)>
243 inserts C<x> at the end of table C<t>.
248 .param pmc table :optional
249 .param pmc arg2 :optional
250 .param pmc arg3 :optional
251 .param pmc extra :slurpy
257 lua_checktype(1, table, 'table')
260 unless null arg3 goto L1
265 pos = lua_checknumber(2, arg2)
266 unless pos > e goto L3
272 unless e >= pos goto L2
274 $P0 = table.'rawget'(idx)
276 table.'rawset'(idx, $P0)
280 table.'rawset'(idx, value)
284 =item C<table.maxn (table)>
286 Returns the largest positive numerical index of the given table, or zero if
287 the table has no positive numerical indices. (To do its job this function
288 does a linear traversal of the whole table.)
293 .param pmc table :optional
294 .param pmc extra :slurpy
297 lua_checktype(1, table, 'table')
302 $P0 = table.'next'(idx)
305 $I0 = isa idx, 'LuaNumber'
307 unless idx > max goto L1
315 =item C<table.remove (table [, pos])>
317 Removes from C<table> the element at position C<pos>, shifting down other
318 elements to close the space, if necessary. Returns the value of the removed
319 element. The default value for C<pos> is C<n>, where C<n> is the length of
320 the table, so that a call C<table.remove(t)> removes the last element of
326 .param pmc table :optional
327 .param pmc pos :optional
328 .param pmc extra :slurpy
333 lua_checktype(1, table, 'table')
335 ipos = lua_optint(2, pos, e)
336 # position is outside bounds?
337 unless 1 <= ipos goto L1
346 res = table.'rawget'(idx)
348 unless ipos < e goto L4
351 $P0 = table.'rawget'(idx)
353 table.'rawset'(idx, $P0)
359 table.'rawset'(idx, $P0)
363 =item C<table.setn (table, n)>
370 .param pmc table :optional
371 .param pmc n :optional
372 .param pmc extra :slurpy
373 lua_checktype(1, table, 'table')
374 lua_error("'setn' is obsolete")
378 =item C<table.sort (table [, comp])>
380 Sorts table elements in a given order, I<in-place>, from C<table[1]> to
381 C<table[n]>, where C<n> is the length of the table. If C<comp> is given,
382 then it must be a function that receives two table elements, and returns
383 true when the first is less than the second (so that C<not comp(a[i+1],a[i]>)
384 will be true after the sort). If C<comp> is not given, then the standard Lua
385 operator C<<> is used instead.
387 The sort algorithm is I<not> stable; that is, elements considered equal by
388 the given order may have their relative positions changed by the sort.
393 .param pmc table :optional
394 .param pmc comp :optional
395 .param pmc extra :slurpy
397 lua_checktype(1, table, 'table')
400 $I0 = isa comp, 'LuaNil'
402 lua_checktype(2, comp, 'function')
404 auxsort(table, comp, 1, n)
417 new idx1, 'LuaNumber'
418 new idx2, 'LuaNumber'
421 # sort elements a[l], a[(l+u)/2] and a[u]
424 $P1 = table.'rawget'(idx1)
425 $P2 = table.'rawget'(idx2)
426 $I0 = sort_comp(comp, $P2, $P1) # a[u] < a[l]?
429 table.'rawset'(idx1, $P2)
430 table.'rawset'(idx2, $P1)
433 if tmp == 1 goto L2 # break: only 2 elements
438 $P1 = table.'rawget'(idx1)
439 $P2 = table.'rawget'(idx2)
440 $I0 = sort_comp(comp, $P1, $P2) # a[i]<a[l]?
442 table.'rawset'(idx1, $P2)
443 table.'rawset'(idx2, $P1)
447 $P2 = table.'rawget'(idx2)
448 $I0 = sort_comp(comp, $P2, $P1) # a[u]<a[i]?
450 table.'rawset'(idx1, $P2)
451 table.'rawset'(idx2, $P1)
454 if tmp == 2 goto L2 # break: only 3 elements
456 $P1 = table.'rawget'(idx1) # Pivot
459 $P2 = table.'rawget'(idx2)
460 table.'rawset'(idx1, $P2)
461 table.'rawset'(idx2, $P1)
462 # a[l] <= P == a[u-1] <= a[u], only need to sort from l+1 to u-2 */
465 L6: # invariant: a[l..i] <= P <= a[j..u]
466 # repeat ++i until a[i] >= P
469 $P2 = table.'rawget'(idx2)
470 $I0 = sort_comp(comp, $P2, $P1)
472 unless i >= u goto L6
473 lua_error("invalid order function for sorting")
476 # repeat --j until a[j] <= P
479 $P3 = table.'rawget'(idx1)
480 $I0 = sort_comp(comp, $P1, $P3)
482 unless j <= l goto L7
483 lua_error("invalid order function for sorting")
487 table.'rawset'(idx2, $P3)
488 table.'rawset'(idx1, $P2)
494 $P1 = table.'rawget'(idx1)
495 $P2 = table.'rawget'(idx2)
496 # swap pivot (a[u-1]) with a[i]
497 table.'rawset'(idx1, $P2)
498 table.'rawset'(idx2, $P1)
499 # a[l..i-1] <= a[i] == P <= a[i+1..u]
500 # adjust so that smaller half is in [j..i] and larger one in [l..u]
502 unless i < tmp goto L10
512 # call recursively the smaller one
513 auxsort(table, comp, j, i)
514 # repeat the routine for the larger one
519 .sub 'sort_comp' :anon
546 # vim: expandtab shiftwidth=4 ft=pir: