Refactor table library to match lua 5.2

This commit is contained in:
James Roseborough
2012-09-10 04:59:45 +00:00
parent 6ba1f86b7b
commit f8b7e1ee1c
9 changed files with 125 additions and 74 deletions

View File

@@ -280,9 +280,7 @@ public class LuaDouble extends LuaNumber {
return LuaString.valueOf(tojstring());
}
public LuaValue checkvalidkey() {
if ( Double.isNaN(v) )
throw new LuaError("table index expected, got nan");
return this;
public boolean isvalidkey() {
return !Double.isNaN(v);
}
}

View File

@@ -85,8 +85,8 @@ public class LuaNil extends LuaValue {
return argerror("value");
}
public LuaValue checkvalidkey() {
return typerror("table index");
public boolean isvalidkey() {
return false;
}
// optional argument conversions - nil alwas falls badk to default value

View File

@@ -272,7 +272,8 @@ public class LuaTable extends LuaValue {
/** caller must ensure key is not nil */
public void set( LuaValue key, LuaValue value ) {
key.checkvalidkey();
if (!key.isvalidkey() && !metatag(NEWINDEX).isfunction())
typerror("table index");
if ( m_metatable==null || ! rawget(key).isnil() || ! settable(this,key,value) )
rawset(key, value);
}

View File

@@ -1027,13 +1027,12 @@ public class LuaValue extends Varargs {
*/
public LuaValue checknotnil() { return this; }
/** Check that this is a valid key in a table index operation, or throw {@link LuaError} if not
* @return {@code this} if valid as a table key
* @throws LuaError if not valid as a table key
/** Return true if this is a valid key in a table index operation.
* @return true if valid as a table key, otherwise false
* @see #isnil()
* @see #isinttype()
*/
public LuaValue checkvalidkey() { return this; }
public boolean isvalidkey() { return true; }
/**
* Throw a {@link LuaError} with a particular message

View File

@@ -24,6 +24,7 @@ package org.luaj.vm2.lib;
import org.luaj.vm2.LuaError;
import org.luaj.vm2.LuaFunction;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.Varargs;
/**
* Subclass of {@link LuaFunction} common to Java functions exposed to lua.
@@ -190,4 +191,29 @@ abstract public class LibFunction extends LuaFunction {
protected static LuaValue[] newupl(LuaValue v) {
return new LuaValue[] { v };
}
public LuaValue call() {
return typerror("value");
}
public LuaValue call(LuaValue a) {
return call();
}
public LuaValue call(LuaValue a, LuaValue b) {
return call(a);
}
public LuaValue call(LuaValue a, LuaValue b, LuaValue c) {
return call(a,b);
}
public LuaValue call(LuaValue a, LuaValue b, LuaValue c, LuaValue d) {
return call(a,b,c);
}
public Varargs invoke(Varargs args) {
switch(args.narg()) {
case 0: return call();
case 1: return call(args.arg1());
case 2: return call(args.arg1(),args.arg(2));
case 3: return call(args.arg1(),args.arg(2),args.arg(3));
default: return call(args.arg1(),args.arg(2),args.arg(3),args.arg(4));
}
}
}

View File

@@ -58,66 +58,91 @@ import org.luaj.vm2.Varargs;
*/
public class TableLib extends OneArgFunction {
public TableLib() {
}
private LuaTable init(LuaValue env) {
LuaTable t = new LuaTable();
bind(t, TableLib.class, new String[] {}, 1 );
bind(t, TableLibV.class, new String[] {
"remove", "concat", "insert", "sort", "unpack", } );
env.set("table", t);
PackageLib.instance.LOADED.set("table", t);
return t;
}
public LuaValue call(LuaValue arg) {
switch ( opcode ) {
case 0: // init library
return init(arg);
}
public LuaValue call(LuaValue env) {
LuaTable table = new LuaTable();
table.set("concat", new concat());
table.set("insert", new insert());
table.set("pack", new pack());
table.set("remove", new remove());
table.set("sort", new sort());
table.set("unpack", new unpack());
env.set("table", table);
return NIL;
}
static final class TableLibV extends VarArgFunction {
public Varargs invoke(Varargs args) {
switch ( opcode ) {
case 0: { // "remove" (table [, pos]) -> removed-ele
LuaTable table = args.checktable(1);
int pos = args.narg()>1? args.checkint(2): 0;
return table.remove(pos);
}
case 1: { // "concat" (table [, sep [, i [, j]]]) -> string
LuaTable table = args.checktable(1);
return table.concat(
args.optstring(2,LuaValue.EMPTYSTRING),
args.optint(3,1),
args.isvalue(4)? args.checkint(4): table.length() );
}
case 2: { // "insert" (table, [pos,] value) -> prev-ele
final LuaTable table = args.checktable(1);
final int pos = args.narg()>2? args.checkint(2): 0;
final LuaValue value = args.arg( args.narg()>2? 3: 2 );
table.insert( pos, value );
return NONE;
}
case 3: { // "sort" (table [, comp]) -> void
LuaTable table = args.checktable(1);
LuaValue compare = (args.isnoneornil(2)? NIL: args.checkfunction(2));
table.sort( compare );
return NONE;
}
case 4: // "unpack", // (list [,i [,j]]) -> result1, ...
{
LuaTable t = args.checktable(1);
switch (args.narg()) {
case 1: return t.unpack();
case 2: return t.unpack(args.checkint(2));
default: return t.unpack(args.checkint(2), args.checkint(3));
}
}
}
static class TableLibFunction extends LibFunction {
public LuaValue call() {
return argerror(1, "table expected, got no value");
}
}
// "concat" (table [, sep [, i [, j]]]) -> string
static class concat extends TableLibFunction {
public LuaValue call(LuaValue list) {
return list.checktable().concat(EMPTYSTRING,1,list.length());
}
public LuaValue call(LuaValue list, LuaValue sep) {
return list.checktable().concat(sep.checkstring(),1,list.length());
}
public LuaValue call(LuaValue list, LuaValue sep, LuaValue i) {
return list.checktable().concat(sep.checkstring(),i.checkint(),list.length());
}
public LuaValue call(LuaValue list, LuaValue sep, LuaValue i, LuaValue j) {
return list.checktable().concat(sep.checkstring(),i.checkint(),j.checkint());
}
}
// "insert" (table, [pos,] value) -> prev-ele
static class insert extends TableLibFunction {
public LuaValue call(LuaValue list) {
return argerror(2, "value expected");
}
public LuaValue call(LuaValue table, LuaValue value) {
table.checktable().insert(table.length()+1,value);
return NONE;
}
public LuaValue call(LuaValue table, LuaValue pos, LuaValue value) {
table.checktable().insert(pos.checkint(),value);
return NONE;
}
}
// "pack" (...) -> table
static class pack extends VarArgFunction {
public Varargs invoke(Varargs args) {
LuaValue t = tableOf(args, 1);
t.set("n", args.narg());
return t;
}
}
// "remove" (table [, pos]) -> removed-ele
static class remove extends TableLibFunction {
public LuaValue call(LuaValue list) {
return list.checktable().remove(0);
}
public LuaValue call(LuaValue list, LuaValue pos) {
return list.checktable().remove(pos.checkint());
}
}
// "sort" (table [, comp])
static class sort extends TwoArgFunction {
public LuaValue call(LuaValue table, LuaValue compare) {
table.checktable().sort(compare.isnil()? NIL: compare.checkfunction());
return NONE;
}
}
// "unpack", // (list [,i [,j]]) -> result1, ...
static class unpack extends VarArgFunction {
public Varargs invoke(Varargs args) {
LuaTable t = args.checktable(1);
switch (args.narg()) {
case 1: return t.unpack();
case 2: return t.unpack(args.checkint(2));
default: return t.unpack(args.checkint(2), args.checkint(3));
}
}
}
}

View File

@@ -198,6 +198,8 @@ public class lua {
}
private static Varargs setGlobalArg(String chunkname, String[] args, int i, LuaValue _G) {
if (args == null)
return LuaValue.NONE;
LuaTable arg = LuaValue.tableOf();
for ( int j=0; j<args.length; j++ )
arg.set( j-i, LuaValue.valueOf(args[j]) );