Author: fperrad Date: Sun Jan 15 23:23:56 2006 New Revision: 11208 Added: trunk/languages/lua/t/table.t Modified: trunk/MANIFEST trunk/languages/lua/lib/luabasic.pir trunk/languages/lua/lib/luapir.pir trunk/languages/lua/lib/luatable.pir trunk/languages/lua/t/basic.t Log: Lua Libraries : - add table.concat(), table.foreach(), table.foreachi() - add next() - and tests
Modified: trunk/MANIFEST ============================================================================== --- trunk/MANIFEST (original) +++ trunk/MANIFEST Sun Jan 15 23:23:56 2006 @@ -977,6 +977,7 @@ languages/lua/t/pmc/thread.t languages/lua/t/pmc/userdata.t [lua] languages/lua/t/repeat.t [lua] languages/lua/t/string.t [lua] +languages/lua/t/table.t [lua] languages/lua/t/tables.t [lua] languages/lua/t/while.t [lua] languages/m4/BUGS [m4] Modified: trunk/languages/lua/lib/luabasic.pir ============================================================================== --- trunk/languages/lua/lib/luabasic.pir (original) +++ trunk/languages/lua/lib/luabasic.pir Sun Jan 15 23:23:56 2006 @@ -418,15 +418,22 @@ in numeric order, use a numerical for or The behavior of C<next> is I<undefined> if, during the traversal, you assign any value to a non-existent field in the table. -NOT YET IMPLEMENTED. +STILL INCOMPLETE (see next in luapir.pir). =cut .sub _lua_next :anon .param pmc table .param pmc index :optional + .local pmc idx + .local pmc value checktype(table, "table") - not_implemented() + (idx, value) = next(table, index) + $I0 = isa idx, "LuaNil" + if $I0 goto L1 + .return (idx, value) +L1: + .return (idx) # nil .end =item C<pairs (t)> @@ -537,16 +544,16 @@ NOT YET IMPLEMENTED. Gets the real value of C<table[index]>, without invoking any metamethod. C<table> must be a table; C<index> is any value different from B<nil>. -NOT YET IMPLEMENTED. - =cut .sub _lua_rawget :anon .param pmc table .param pmc index + .local pmc ret checktype(table, "table") checkany(index) - not_implemented() + ret = table[index] + .return (ret) .end =item C<rawset (table, index, value)> @@ -555,8 +562,6 @@ Sets the real value of C<table[index]> t metamethod. C<table> must be a table, C<index> is any value different from B<nil>, and C<value> is any Lua value. -NOT YET IMPLEMENTED. - =cut .sub _lua_rawset :anon @@ -566,7 +571,8 @@ NOT YET IMPLEMENTED. checktype(table, "table") checkany(index) checkany(value) - not_implemented() + table[index] = value + .return () .end =item C<require (packagename)> @@ -764,14 +770,28 @@ Returns all elements from the given list except that the above code can be written only for a fixed I<n>. The number I<n> is the size of the list, as defined for the C<table.getn> function. -NOT YET IMPLEMENTED. - =cut .sub _lua_unpack :anon .param pmc list + .local pmc ret checktype(list, "table") - not_implemented() + $I0 = getn(list) + new ret, .Array + set ret, $I0 + new $P1, .LuaNumber + $P1 = 1.0 + $I1 = 0 +L0: + unless $I1 <= $I0 goto L1 + $P2 = list[$P1] +# ret[$I1] = $P2 + push ret, $P2 + add $P1, 1.0 + add $I1, 1 + goto L0 +L1: + .return (ret :flat) .end =item C<xpcall (f, err)> Modified: trunk/languages/lua/lib/luapir.pir ============================================================================== --- trunk/languages/lua/lib/luapir.pir (original) +++ trunk/languages/lua/lib/luapir.pir Sun Jan 15 23:23:56 2006 @@ -26,6 +26,7 @@ lib/luapir.pir - Lua PIR Library error(extramsg) .end + =item C<checkany (arg)> =cut @@ -37,6 +38,7 @@ lib/luapir.pir - Lua PIR Library L1: .end + =item C<checknumber (arg)> =cut @@ -57,6 +59,7 @@ L0: tag_error($S0, "number") .end + =item C<checkstring (arg)> =cut @@ -69,6 +72,7 @@ L0: .return (val) .end + =item C<checktype (arg, type)> =cut @@ -85,6 +89,7 @@ L0: tag_error($S0, type) .end + =item C<error (message)> =cut @@ -97,16 +102,40 @@ L0: throw ex .end + =item C<getn (table)> =cut .sub getn .param pmc table - not_implemented() + .const .LuaString n = "n" + $P0 = table[n] + if_null $P0, L0 + $I0 = isa $P0, "LuaNumber" + unless $I0, L0 + $I1 = $P0 + unless $I1 >= 0 goto L0 + .return ($I1) +L0: + $I1 = 0 + new $P1, .LuaNumber + $P1 = 1 +L1: + $P0 = table[$P1] + $I0 = isa $P0, "LuaNil" + if $I0 goto L2 +# $I0 = defined $P0 +# unless $I0, L2 + add $I1, 1 + add $P1, 1 + goto L1 +L2: + .return ($I1) .end -=item C<getn (table)> + +=item C<mkarg (argv)> Support variable number of arguments function call. @@ -116,7 +145,6 @@ Support variable number of arguments fun .param pmc argv .local pmc ret .local pmc key - .local pmc n .local pmc curr .local int argc .local int i @@ -132,12 +160,35 @@ L1: ret[key] = curr goto L1 L2: - new n, .LuaString - n = "n" + .const .LuaString n = "n" ret[n] = key .return (ret) .end + +=item C<next (table, index)> + +=cut + +.sub next + .param pmc table + .param pmc index + .local pmc value + $I0 = defined index + if $I0 goto L1 + new index, .LuaNumber + index = 0 +L1: + add index, 1 + value = table[index] + $I0 = isa value, "LuaNil" + if $I0 goto L2 + .return (index, value) +L2: + .return (value) # nil +.end + + =item C<not_implemented ()> =cut @@ -149,6 +200,7 @@ L2: throw ex .end + =item C<optint (arg)> =cut @@ -165,6 +217,7 @@ L0: .return (default) .end + =item C<optstring (arg)> =cut @@ -181,6 +234,7 @@ L0: .return (default) .end + =item C<setn (table, n)> =cut @@ -188,7 +242,10 @@ L0: .sub setn .param pmc table .param int n - not_implemented() + .const .LuaString key_n = "n" + new $P0, .LuaNumber + $P0 = n + table[key_n] = $P0 .end #.sub tostring Modified: trunk/languages/lua/lib/luatable.pir ============================================================================== --- trunk/languages/lua/lib/luatable.pir (original) +++ trunk/languages/lua/lib/luatable.pir Sun Jan 15 23:23:56 2006 @@ -112,8 +112,6 @@ C<sep> is the empty string, the default C<j> is the size of the table. If C<i> is greater than C<j>, returns the empty string. -NOT YET IMPLEMENTED. - =cut .sub _table_concat :anon @@ -121,11 +119,39 @@ NOT YET IMPLEMENTED. .param pmc sep :optional .param pmc i :optional .param pmc j :optional + .local pmc idx + .local pmc value + .local pmc ret $S0 = optstring(sep, "") $I0 = optint(i, 1) $I1 = optint(j, 0) checktype(table, "table") - not_implemented() + unless $I1 == 0 goto L1 + $I1 = getn(table) +L1: + $S1 = "" + new idx, .LuaNumber +L2: + unless $I0 <= $I1 goto L3 + idx = $I0 + value = table[idx] + $I2 = isa value, "LuaString" + if $I2 goto L4 + $I2 = isa value, "LuaNumber" + if $I2 goto L4 + argerror("table contains non-strings") +L4: + $S2 = value + concat $S1, $S2 + unless $I0 != $I1 goto L5 + concat $S1, $S0 +L5: + add $I0, 1 + goto L2 +L3: + new ret, .LuaString + ret = $S1 + .return (ret) .end =item C<table.foreach (table, f)> @@ -137,16 +163,29 @@ the final value of C<foreach>. See the C<next> function for extra information about table traversals. -NOT YET IMPLEMENTED. +STILL INCOMPLETE (see next in luapir.pir). =cut .sub _table_foreach :anon .param pmc table .param pmc f + .local pmc idx + .local pmc value + .local pmc ret checktype(table, "table") checktype(f, "Sub") - not_implemented() + new idx, .LuaNil +L1: + (idx, value) = next(table, idx) + $I0 = isa idx, "LuaNil" + unless $I0 goto L2 + .return () +L2: + (ret) = f(idx, value) + $I0 = defined ret + unless $I0 goto L1 + .return (ret) .end =item C<table.foreachi (table, f)> @@ -157,20 +196,35 @@ Indices are visited in sequential order, size of the table. If C<f> returns a non-B<nil> value, then the loop is broken and this value is returned as the result of C<foreachi>. -NOT YET IMPLEMENTED. - =cut .sub _table_foreachi :anon .param pmc table .param pmc f + .local pmc index + .local pmc value + .local pmc ret + .local int i + .local int n checktype(table, "table") checktype(f, "Sub") - $I0 = getn(table) - not_implemented() + n = getn(table) + i = 0 + new index, .LuaNumber +L1: + add i, 1 + unless i <= n goto L2 + index = i + value = table[index] + (ret) = f(index, value) + $I0 = defined ret + unless $I0 goto L1 + .return (ret) +L2: + .return () .end -=item C<table.getn (table)> +=item C<table.getn (table)> Returns the size of a table, when seen as a list. If the table has an C<n> field with a numeric value, this value is the size of the table. Otherwise, @@ -178,7 +232,7 @@ if there was a previous call to C<table. value is returned. Otherwise, the size is one less the first integer index with a B<nil> value. -NOT YET IMPLEMENTED. +STILL INCOMPLETE (see getn in luapir.pir). =cut @@ -264,7 +318,7 @@ Updates the size of a table. If the tabl value, that value is changed to the given C<n>. Otherwise, it updates an internal state so that subsequent calls to C<table.getn(table)> return C<n>. -NOT YET IMPLEMENTED. +STILL INCOMPLETE (see setn in luapir.pir). =cut @@ -280,6 +334,7 @@ NOT YET IMPLEMENTED. =head1 AUTHORS +Francois Perrad =cut Modified: trunk/languages/lua/t/basic.t ============================================================================== --- trunk/languages/lua/t/basic.t (original) +++ trunk/languages/lua/t/basic.t Sun Jan 15 23:23:56 2006 @@ -21,7 +21,7 @@ use strict; use FindBin; use lib "$FindBin::Bin"; -use Parrot::Test tests => 9; +use Parrot::Test tests => 12; use Test::More; language_output_like( 'lua', << 'CODE', << 'OUTPUT', "function assert(false, msg)"); @@ -42,6 +42,23 @@ CODE /assertion failed!/ OUTPUT +language_output_is( 'lua', << 'CODE', << 'OUTPUT', "function next (array)"); +t = {"a","b","c"} +a = next(t, nil) +print(a) +a = next(t, 1) +print(a) +a = next(t, 2) +print(a) +a = next(t, 3) +print(a) +CODE +1 +2 +3 +nil +OUTPUT + language_output_is( 'lua', << 'CODE', << 'OUTPUT', "function pcall"); r = pcall(assert, true) print(r) @@ -55,6 +72,21 @@ false false OUTPUT +language_output_is( 'lua', << 'CODE', << 'OUTPUT', "function rawget"); +t = {a = "letter a", b = "letter b"} +print(rawget(t, "a")) +CODE +letter a +OUTPUT + +language_output_is( 'lua', << 'CODE', << 'OUTPUT', "function rawset"); +t = {} +rawset(t, "a", "letter a") +print(t.a) +CODE +letter a +OUTPUT + language_output_is( 'lua', << 'CODE', << 'OUTPUT', "function type"); print(type("Hello world")) print(type(10.4*3)) Added: trunk/languages/lua/t/table.t ============================================================================== --- (empty file) +++ trunk/languages/lua/t/table.t Sun Jan 15 23:23:56 2006 @@ -0,0 +1,113 @@ +#! perl -w +# Copyright: 2006 The Perl Foundation. All Rights Reserved. +# $Id: table.t 11084 2006-01-11 13:12:49Z fperrad $ + +=head1 NAME + +t/table.t - Lua Table Library + +=head1 SYNOPSIS + + % perl -I../lib -Ilua/t lua/t/table.t + +=head1 DESCRIPTION + +Tests Lua Table Library +(implemented in F<languages/lua/lib/luatable.pir>). + +See "Lua 5.0 Reference Manual", section 5.4 "Table Manipulation". + +See "Programming in Lua", section 19 "The Table Library". + +=cut + +use strict; +use FindBin; +use lib "$FindBin::Bin"; + +use Parrot::Test tests => 8; +use Test::More; + +language_output_is( 'lua', << 'CODE', << 'OUTPUT', "function concat"); +t = {"a","b","c","d","e"} +print(table.concat(t)) +print(table.concat(t,",")) +print(table.concat(t,",",2)) +print(table.concat(t,",",2,4)) +print(table.concat(t,",",4,2)) +CODE +abcde +a,b,c,d,e +b,c,d,e +b,c,d + +OUTPUT + +language_output_is( 'lua', << 'CODE', << 'OUTPUT', "function concat (number)"); +t = {"a","b",3,"d","e"} +print(table.concat(t,",")) +CODE +a,b,3,d,e +OUTPUT + +language_output_like( 'lua', << 'CODE', << 'OUTPUT', "function concat (out of range)"); +t = {"a","b","c","d","e"} +print(table.concat(t,",",2,7)) +CODE +/table contains non-strings/ +OUTPUT + +language_output_like( 'lua', << 'CODE', << 'OUTPUT', "function concat (non-string)"); +t = {"a","b",true,"d","e"} +print(table.concat(t,",")) +CODE +/table contains non-strings/ +OUTPUT + +language_output_is( 'lua', << 'CODE', << 'OUTPUT', "function foreach (array)"); +t = {"a","b","c"} +table.foreach(t, print) +CODE +1 a +2 b +3 c +OUTPUT + +language_output_is( 'lua', << 'CODE', << 'OUTPUT', "function foreachi (array)"); +t = {"a","b","c"} +table.foreachi(t, print) +CODE +1 a +2 b +3 c +OUTPUT + +language_output_is( 'lua', << 'CODE', << 'OUTPUT', "function getn"); +print(table.getn{10,2,4}) +print(table.getn{10,2,nil}) +print(table.getn{10,2,nil; n=3}) +print(table.getn{n=1000}) +CODE +3 +2 +3 +1000 +OUTPUT + +language_output_is( 'lua', << 'CODE', << 'OUTPUT', "function setn"); +a = {} +print(table.getn(a)) +table.setn(a, 10000) +print(table.getn(a)) + +b = {n=10} +print(table.getn(b)) +table.setn(b, 10000) +print(table.getn(b)) +CODE +0 +10000 +10 +10000 +OUTPUT +