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
+