Implement foreach(), foreachi()
This commit is contained in:
@@ -36,6 +36,8 @@ public class TableLib extends LFunction {
|
||||
public static final String[] NAMES = {
|
||||
"table",
|
||||
"concat",
|
||||
"foreach",
|
||||
"foreachi",
|
||||
"getn",
|
||||
"insert",
|
||||
"maxn",
|
||||
@@ -45,11 +47,13 @@ public class TableLib extends LFunction {
|
||||
|
||||
private static final int INSTALL = 0;
|
||||
private static final int CONCAT = 1;
|
||||
private static final int GETN = 2;
|
||||
private static final int INSERT = 3;
|
||||
private static final int MAXN = 4;
|
||||
private static final int REMOVE = 5;
|
||||
private static final int SORT = 6;
|
||||
private static final int FOREACH = 2;
|
||||
private static final int FOREACHI = 3;
|
||||
private static final int GETN = 4;
|
||||
private static final int INSERT = 5;
|
||||
private static final int MAXN = 6;
|
||||
private static final int REMOVE = 7;
|
||||
private static final int SORT = 8;
|
||||
|
||||
public static void install( LTable globals ) {
|
||||
LTable table = new LTable();
|
||||
@@ -117,6 +121,21 @@ public class TableLib extends LFunction {
|
||||
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)
|
||||
*
|
||||
* Get length of table t.
|
||||
|
||||
@@ -700,4 +700,45 @@ public class LTable extends LValue {
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,3 +66,36 @@ table.sort(t)
|
||||
print( table.concat(t,'-'), table.maxn(t), #t )
|
||||
table.sort(t,function(a,b) return b<a end)
|
||||
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)' )
|
||||
|
||||
|
||||
Reference in New Issue
Block a user