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.
|
* If i is greater than j, returns the empty string.
|
||||||
*/
|
*/
|
||||||
private void concat(VM vm) {
|
private void concat(VM vm) {
|
||||||
LTable table = (LTable) vm.getArg(0);
|
int n = vm.gettop();
|
||||||
LString sep = vm.getArgAsLuaString(1);
|
LTable table = vm.totable(2);
|
||||||
int i = vm.getArgAsInt(2);
|
LString sep = (n>2? vm.tolstring(3): null);
|
||||||
int j = vm.getArgAsInt(3);
|
int i = vm.tointeger(4);
|
||||||
LValue[] keys = table.getKeys();
|
int j = vm.tointeger(5);
|
||||||
|
int len = table.luaLength();
|
||||||
if ( i == 0 )
|
if ( i == 0 )
|
||||||
i = 1;
|
i = 1;
|
||||||
if ( j == 0 )
|
if ( j == 0 )
|
||||||
j = keys.length;
|
j = len;
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
try {
|
try {
|
||||||
for ( int k=i; k<=j; k++ ) {
|
for ( int k=i; k<=j; k++ ) {
|
||||||
LValue v = table.get(keys[k-1]);
|
LValue v = table.get(k);
|
||||||
v.luaAsString().write(baos);
|
v.luaAsString().write(baos);
|
||||||
if ( k<j )
|
if ( k<j && sep!=null )
|
||||||
sep.write( baos );
|
sep.write( baos );
|
||||||
}
|
}
|
||||||
vm.setResult( new LString( baos.toByteArray() ) );
|
vm.settop(0);
|
||||||
|
vm.pushlstring( baos.toByteArray() );
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
vm.error(e.getMessage());
|
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.
|
* table.insert(t,x) inserts x at the end of table t.
|
||||||
*/
|
*/
|
||||||
private void insert(VM vm) {
|
private void insert(VM vm) {
|
||||||
int n = vm.getArgCount();
|
int n = vm.gettop();
|
||||||
LTable table = (LTable) vm.getArg(0);
|
LTable table = vm.totable(2);
|
||||||
int pos = (n>2? vm.getArgAsInt(1): 0);
|
int pos = (n>3? vm.tointeger(3): 0);
|
||||||
LValue value = vm.getArg(n-1);
|
LValue value = vm.topointer(-1);
|
||||||
table.luaInsertPos( pos, value );
|
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.)
|
* indices. (To do its job this function does a linear traversal of the whole table.)
|
||||||
*/
|
*/
|
||||||
private void maxn(VM vm) {
|
private void maxn(VM vm) {
|
||||||
LTable table = (LTable) vm.getArg(0);
|
LTable table = vm.totable(2);
|
||||||
vm.setResult( LInteger.valueOf( table.luaMaxN() ) );
|
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.
|
* so that a call table.remove(t) removes the last element of table t.
|
||||||
*/
|
*/
|
||||||
private void remove(VM vm) {
|
private void remove(VM vm) {
|
||||||
int n = vm.getArgCount();
|
int n = vm.gettop();
|
||||||
LTable table = (LTable) vm.getArg(0);
|
LTable table = vm.totable(2);
|
||||||
int pos = (n>1? vm.getArgAsInt(1): 0);
|
int pos = (n>1? vm.tointeger(3): 0);
|
||||||
table.luaRemovePos( pos );
|
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.
|
* 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) {
|
private void sort(VM vm) {
|
||||||
LTable table = (LTable) vm.getArg(0);
|
LTable table = vm.totable(2);
|
||||||
table.luaSort();
|
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));
|
pushlvalue(new LString(bytes, offset, length));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void pushlstring(byte[] byteArray) {
|
||||||
|
pushlstring(byteArray, 0, byteArray.length);
|
||||||
|
}
|
||||||
|
|
||||||
public void pushnil() {
|
public void pushnil() {
|
||||||
pushlvalue(LNil.NIL);
|
pushlvalue(LNil.NIL);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import java.io.InputStream;
|
|||||||
|
|
||||||
import lua.io.Closure;
|
import lua.io.Closure;
|
||||||
import lua.value.LString;
|
import lua.value.LString;
|
||||||
|
import lua.value.LTable;
|
||||||
import lua.value.LValue;
|
import lua.value.LValue;
|
||||||
/**
|
/**
|
||||||
* <hr>
|
* <hr>
|
||||||
@@ -938,6 +939,14 @@ public interface VM {
|
|||||||
*/
|
*/
|
||||||
public void pushlstring(byte[] bytes, int offset, int length);
|
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,
|
* Push an LValue onto the stack. <span class="apii">[-0, +1,
|
||||||
* <em>m</em>]</span>
|
* <em>m</em>]</span>
|
||||||
@@ -1341,6 +1350,15 @@ public interface VM {
|
|||||||
*/
|
*/
|
||||||
public StackState tothread(int index);
|
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,
|
* Get the Object from a userdata value. <span class="apii">[-0, +0,
|
||||||
* <em>-</em>]</span>
|
* <em>-</em>]</span>
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package lua.value;
|
package lua.value;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
import lua.Lua;
|
import lua.Lua;
|
||||||
import lua.VM;
|
import lua.VM;
|
||||||
|
|
||||||
@@ -513,25 +515,98 @@ public class LTable extends LValue {
|
|||||||
return m_vector.length;
|
return m_vector.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/**
|
||||||
|
* Insert element at a position in the list.
|
||||||
* @pos index to insert at, or 0 to insert at end.
|
* @pos index to insert at, or 0 to insert at end.
|
||||||
*/
|
*/
|
||||||
public void luaInsertPos(int pos, LValue value) {
|
public void luaInsertPos(int pos, LValue value) {
|
||||||
if ( pos != 0 )
|
if ( pos > m_arrayEntries + 1 )
|
||||||
throw new RuntimeException("luaInsertPos() not implemented");
|
put( pos, value );
|
||||||
put( m_arrayEntries + m_hashEntries + 1, value );
|
else {
|
||||||
}
|
final int index = Math.max(0,pos==0? m_arrayEntries: pos-1);
|
||||||
|
if ( m_arrayEntries + 1 > m_vector.length )
|
||||||
public void luaSort() {
|
resize( ( m_arrayEntries + 1 ) * 2 );
|
||||||
throw new RuntimeException("luaSort() not implemented");
|
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) {
|
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() {
|
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();
|
LuaJava.install();
|
||||||
|
|
||||||
// new lua state
|
// new lua state
|
||||||
StackState state = new DebugStackState();
|
StackState state = new StackState();
|
||||||
VM vm = state;
|
VM vm = state;
|
||||||
|
|
||||||
// load the file
|
// load the file
|
||||||
|
|||||||
@@ -96,6 +96,10 @@ public class LuaJTest extends TestCase {
|
|||||||
runTest( "strlib" );
|
runTest( "strlib" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testTable() throws IOException, InterruptedException {
|
||||||
|
runTest( "table" );
|
||||||
|
}
|
||||||
|
|
||||||
public void testType() throws IOException, InterruptedException {
|
public void testType() throws IOException, InterruptedException {
|
||||||
runTest( "type" );
|
runTest( "type" );
|
||||||
}
|
}
|
||||||
@@ -120,7 +124,7 @@ public class LuaJTest extends TestCase {
|
|||||||
LuaCompat.install();
|
LuaCompat.install();
|
||||||
|
|
||||||
// new lua state
|
// new lua state
|
||||||
StackState state = new DebugStackState();
|
StackState state = new StackState();
|
||||||
|
|
||||||
// load the file
|
// load the file
|
||||||
Proto p = loadScriptResource( state, testName );
|
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