Implement foreach(), foreachi()

This commit is contained in:
James Roseborough
2007-12-11 01:18:04 +00:00
parent 1923d8e6a0
commit ab8fc4883e
3 changed files with 100 additions and 7 deletions

View File

@@ -36,6 +36,8 @@ public class TableLib extends LFunction {
public static final String[] NAMES = { public static final String[] NAMES = {
"table", "table",
"concat", "concat",
"foreach",
"foreachi",
"getn", "getn",
"insert", "insert",
"maxn", "maxn",
@@ -45,11 +47,13 @@ public class TableLib extends LFunction {
private static final int INSTALL = 0; private static final int INSTALL = 0;
private static final int CONCAT = 1; private static final int CONCAT = 1;
private static final int GETN = 2; private static final int FOREACH = 2;
private static final int INSERT = 3; private static final int FOREACHI = 3;
private static final int MAXN = 4; private static final int GETN = 4;
private static final int REMOVE = 5; private static final int INSERT = 5;
private static final int SORT = 6; private static final int MAXN = 6;
private static final int REMOVE = 7;
private static final int SORT = 8;
public static void install( LTable globals ) { public static void install( LTable globals ) {
LTable table = new LTable(); LTable table = new LTable();
@@ -117,6 +121,21 @@ public class TableLib extends LFunction {
break; break;
} }
/* table.getn (table)
*
* Get length of table t.
*/
case FOREACH:
case FOREACHI:
{
LTable table = vm.totable(2);
LFunction function = vm.tojavafunction(3);
LValue result = table.foreach( vm, function, id==FOREACHI );
vm.resettop();
vm.pushlvalue( result );
break;
}
/* table.getn (table) /* table.getn (table)
* *
* Get length of table t. * Get length of table t.

View File

@@ -700,4 +700,45 @@ public class LTable extends LValue {
return n + slot + 1; return n + slot + 1;
} }
/**
* Executes the given f over all elements of table. For each element, f is
* called with the index and respective value as arguments. If f returns a
* non-nil value, then the loop is broken, and this value is returned as the
* final value of foreach.
*
* @param vm
* @param function
* @param isforeachi is a table.foreachi() call, not a table.foreach() call
* @return
*/
public LValue foreach(LuaState vm, LFunction function, boolean isforeachi) {
for ( int i = 0; i < m_vector.length; ++i ) {
if ( m_vector[ i ] != LNil.NIL ) {
if ( foreachitem( vm, function, LInteger.valueOf(i+1), m_vector[i] ) )
return vm.topointer(1);
}
}
if ( (! isforeachi) && m_hashKeys != null ) {
for ( int i = 0; i < m_hashKeys.length; ++i ) {
if ( m_hashKeys[ i ] != null ) {
if ( foreachitem( vm, function, m_hashKeys[i], m_hashValues[i] ) )
return vm.topointer(1);
}
}
}
return LNil.NIL;
}
private static boolean foreachitem(LuaState vm, LFunction f, LValue key, LValue value) {
vm.resettop();
vm.pushlvalue( f );
vm.pushlvalue( key );
vm.pushlvalue( value );
vm.call(2, 1);
return ! vm.isnil(1);
}
} }

View File

@@ -66,3 +66,36 @@ table.sort(t)
print( table.concat(t,'-'), table.maxn(t), #t ) print( table.concat(t,'-'), table.maxn(t), #t )
table.sort(t,function(a,b) return b<a end) table.sort(t,function(a,b) return b<a end)
print( table.concat(t,'-'), table.maxn(t), #t ) print( table.concat(t,'-'), table.maxn(t), #t )
-- getn
t0 = {}
t1 = { 'one', 'two', 'three' }
t2 = { a='aa', b='bb', c='cc' }
t3 = { 'one', 'two', 'three', a='aa', b='bb', c='cc' }
print( 'getn(t0)', pcall( table.getn, t0 ) )
print( 'getn(t0)', pcall( table.getn, t1 ) )
print( 'getn(t0)', pcall( table.getn, t2 ) )
print( 'getn(t0)', pcall( table.getn, t3 ) )
-- foreach
function test( f, t, result, name )
status, value = pcall( f, t, function(...)
print(name,...)
return result
end )
print( name, 's,v', status, value )
end
function testall( f, t, name )
test( f, t, nil, name..'nil' )
test( f, t, false, name..'fls' )
test( f, t, 100, name..'100' )
end
testall( table.foreach, t0, 'table.foreach(t0)' )
testall( table.foreach, t1, 'table.foreach(t1)' )
testall( table.foreach, t2, 'table.foreach(t2)' )
testall( table.foreach, t3, 'table.foreach(t3)' )
testall( table.foreachi, t0, 'table.foreachi(t0)' )
testall( table.foreachi, t1, 'table.foreachi(t1)' )
testall( table.foreachi, t2, 'table.foreachi(t2)' )
testall( table.foreachi, t3, 'table.foreachi(t3)' )