Table unit tests and implementation of table.remove(), table.sort()
This commit is contained in:
@@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
BIN
src/test/res/table.luac
Normal file
Binary file not shown.
Reference in New Issue
Block a user