Table unit tests and implementation of table.remove(), table.sort()

This commit is contained in:
James Roseborough
2007-10-31 23:24:51 +00:00
parent facb8d1d07
commit 434530b60f
7 changed files with 137 additions and 32 deletions

View File

@@ -663,24 +663,26 @@ public class LuaCompat extends LFunction {
* If i is greater than j, returns the empty string.
*/
private void concat(VM vm) {
LTable table = (LTable) vm.getArg(0);
LString sep = vm.getArgAsLuaString(1);
int i = vm.getArgAsInt(2);
int j = vm.getArgAsInt(3);
LValue[] keys = table.getKeys();
int n = vm.gettop();
LTable table = vm.totable(2);
LString sep = (n>2? vm.tolstring(3): null);
int i = vm.tointeger(4);
int j = vm.tointeger(5);
int len = table.luaLength();
if ( i == 0 )
i = 1;
if ( j == 0 )
j = keys.length;
j = len;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
for ( int k=i; k<=j; k++ ) {
LValue v = table.get(keys[k-1]);
LValue v = table.get(k);
v.luaAsString().write(baos);
if ( k<j )
if ( k<j && sep!=null )
sep.write( baos );
}
vm.setResult( new LString( baos.toByteArray() ) );
vm.settop(0);
vm.pushlstring( baos.toByteArray() );
} catch (IOException e) {
vm.error(e.getMessage());
}
@@ -693,10 +695,10 @@ public class LuaCompat extends LFunction {
* table.insert(t,x) inserts x at the end of table t.
*/
private void insert(VM vm) {
int n = vm.getArgCount();
LTable table = (LTable) vm.getArg(0);
int pos = (n>2? vm.getArgAsInt(1): 0);
LValue value = vm.getArg(n-1);
int n = vm.gettop();
LTable table = vm.totable(2);
int pos = (n>3? vm.tointeger(3): 0);
LValue value = vm.topointer(-1);
table.luaInsertPos( pos, value );
}
@@ -707,8 +709,9 @@ public class LuaCompat extends LFunction {
* indices. (To do its job this function does a linear traversal of the whole table.)
*/
private void maxn(VM vm) {
LTable table = (LTable) vm.getArg(0);
vm.setResult( LInteger.valueOf( table.luaMaxN() ) );
LTable table = vm.totable(2);
vm.settop(0);
vm.pushinteger( table.luaMaxN() );
}
@@ -719,9 +722,9 @@ public class LuaCompat extends LFunction {
* so that a call table.remove(t) removes the last element of table t.
*/
private void remove(VM vm) {
int n = vm.getArgCount();
LTable table = (LTable) vm.getArg(0);
int pos = (n>1? vm.getArgAsInt(1): 0);
int n = vm.gettop();
LTable table = vm.totable(2);
int pos = (n>1? vm.tointeger(3): 0);
table.luaRemovePos( pos );
}
@@ -735,7 +738,8 @@ public class LuaCompat extends LFunction {
* The sort algorithm is not stable; that is, elements considered equal by the given order may have their relative positions changed by the sort.
*/
private void sort(VM vm) {
LTable table = (LTable) vm.getArg(0);
table.luaSort();
LTable table = vm.totable(2);
LValue compare = vm.topointer(3);
table.luaSort( vm, compare );
}
}

View File

@@ -1011,6 +1011,10 @@ public class StackState extends Lua implements VM {
pushlvalue(new LString(bytes, offset, length));
}
public void pushlstring(byte[] byteArray) {
pushlstring(byteArray, 0, byteArray.length);
}
public void pushnil() {
pushlvalue(LNil.NIL);
}

View File

@@ -4,6 +4,7 @@ import java.io.InputStream;
import lua.io.Closure;
import lua.value.LString;
import lua.value.LTable;
import lua.value.LValue;
/**
* <hr>
@@ -938,6 +939,14 @@ public interface VM {
*/
public void pushlstring(byte[] bytes, int offset, int length);
/**
* Push string bytes onto the stack as a string. <span class="apii">[-0, +1,
* <em>m</em>]</span>
*
* Pushes the bytes in byteArray onto the stack as a lua string.
*/
public void pushlstring(byte[] byteArray);
/**
* Push an LValue onto the stack. <span class="apii">[-0, +1,
* <em>m</em>]</span>
@@ -1341,6 +1350,15 @@ public interface VM {
*/
public StackState tothread(int index);
/**
* Get a value from the stack as a lua table. <span class="apii">[-0, +0, <em>-</em>]</span>
*
* <p>
* Converts the value at the given acceptable index to a Lua table
* This value must be a table otherwise, the function returns <code>NIL</code>.
*/
public LTable totable(int index);
/**
* Get the Object from a userdata value. <span class="apii">[-0, +0,
* <em>-</em>]</span>

View File

@@ -1,5 +1,7 @@
package lua.value;
import java.util.Arrays;
import lua.Lua;
import lua.VM;
@@ -513,25 +515,98 @@ public class LTable extends LValue {
return m_vector.length;
}
/*
/**
* Insert element at a position in the list.
* @pos index to insert at, or 0 to insert at end.
*/
public void luaInsertPos(int pos, LValue value) {
if ( pos != 0 )
throw new RuntimeException("luaInsertPos() not implemented");
put( m_arrayEntries + m_hashEntries + 1, value );
}
public void luaSort() {
throw new RuntimeException("luaSort() not implemented");
if ( pos > m_arrayEntries + 1 )
put( pos, value );
else {
final int index = Math.max(0,pos==0? m_arrayEntries: pos-1);
if ( m_arrayEntries + 1 > m_vector.length )
resize( ( m_arrayEntries + 1 ) * 2 );
if ( m_vector[index] != LNil.NIL ) {
System.arraycopy(m_vector, index, m_vector, index+1, m_vector.length-1-index);
}
m_vector[index] = value;
++m_arrayEntries;
}
}
/**
* Remove an element from the list part of the table
* @param pos position to remove, or 0 to remove last element
*/
public void luaRemovePos(int pos) {
throw new RuntimeException("luaRemovePos() not implemented");
if ( pos > m_arrayEntries ) {
put( pos, LNil.NIL );
} else {
final int index = Math.max(0,pos<=0? m_arrayEntries: pos)-1;
if ( index < 0 )
return;
System.arraycopy(m_vector, index+1, m_vector, index, m_vector.length-1-index);
m_vector[m_vector.length-1] = LNil.NIL;
--m_arrayEntries;
}
}
public int luaMaxN() {
throw new RuntimeException("luaMaxN() not implemented");
return m_arrayEntries;
}
// ----------------- sort support -----------------------------
//
// implemented heap sort from wikipedia
//
public void luaSort(VM vm, LValue compare) {
heapSort(m_arrayEntries, vm, compare);
}
private void heapSort(int count, VM vm, LValue cmpfunc) {
heapify(count, vm, cmpfunc);
for ( int end=count-1; end>0; ) {
swap(end, 0);
siftDown(0, --end, vm, cmpfunc);
}
}
private void heapify(int count, VM vm, LValue cmpfunc) {
for ( int start=count/2-1; start>=0; --start )
siftDown(start, count - 1, vm, cmpfunc);
}
private void siftDown(int start, int end, VM vm, LValue cmpfunc) {
for ( int root=start; root*2+1 <= end; ) {
int child = root*2+1;
if (child < end && compare(child, child + 1, vm, cmpfunc))
++child;
if (compare(root, child, vm, cmpfunc)) {
swap(root, child);
root = child;
} else
return;
}
}
private boolean compare(int i, int j, VM vm, LValue cmpfunc) {
if ( cmpfunc != LNil.NIL ) {
vm.pushlvalue(cmpfunc);
vm.pushlvalue(m_vector[i]);
vm.pushlvalue(m_vector[j]);
vm.call(2, 1);
boolean result = vm.toboolean(1);
vm.settop(0);
return result;
} else {
return m_vector[j].luaBinCmpUnknown( Lua.OP_LT, m_vector[i] );
}
}
private void swap(int i, int j) {
LValue tmp = m_vector[i];
m_vector[i] = m_vector[j];
m_vector[j] = tmp;
}
}

View File

@@ -30,7 +30,7 @@ public class LuacRunner {
LuaJava.install();
// new lua state
StackState state = new DebugStackState();
StackState state = new StackState();
VM vm = state;
// load the file

View File

@@ -96,6 +96,10 @@ public class LuaJTest extends TestCase {
runTest( "strlib" );
}
public void testTable() throws IOException, InterruptedException {
runTest( "table" );
}
public void testType() throws IOException, InterruptedException {
runTest( "type" );
}
@@ -120,7 +124,7 @@ public class LuaJTest extends TestCase {
LuaCompat.install();
// new lua state
StackState state = new DebugStackState();
StackState state = new StackState();
// load the file
Proto p = loadScriptResource( state, testName );

BIN
src/test/res/table.luac Normal file

Binary file not shown.