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

+

Reply via email to