Simplify bindings.
This commit is contained in:
@@ -76,17 +76,17 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
||||
public LuaValue call(LuaValue arg) {
|
||||
env.set( "_G", env );
|
||||
env.set( "_VERSION", VERSION );
|
||||
bind1( env, new String[] {
|
||||
bind( env, BaseLib1.class, new String[] {
|
||||
"getfenv", // ( [f] ) -> env
|
||||
"getmetatable", // ( object ) -> table
|
||||
} );
|
||||
bind2( env, new String[] {
|
||||
bind( env, BaseLib2.class, new String[] {
|
||||
"collectgarbage", // ( opt [,arg] ) -> value
|
||||
"error", // ( message [,level] ) -> ERR
|
||||
"rawequal", // (v1, v2) -> boolean
|
||||
"setfenv", // (f, table) -> void
|
||||
} );
|
||||
bindv( env, new String[] {
|
||||
bind( env, BaseLibV.class, new String[] {
|
||||
"assert", // ( v [,message] ) -> v, message | ERR
|
||||
"dofile", // ( filename ) -> result1, ...
|
||||
"load", // ( func [,chunkname] ) -> chunk | nil, msg
|
||||
@@ -113,6 +113,11 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
||||
next = env.get("next");
|
||||
inext = env.get("__inext");
|
||||
|
||||
// inject base lib
|
||||
((BaseLibV) env.get("print")).baselib = this;
|
||||
((BaseLibV) env.get("pairs")).baselib = this;
|
||||
((BaseLibV) env.get("ipairs")).baselib = this;
|
||||
|
||||
// set the default resource finder if not set already
|
||||
if ( FINDER == null )
|
||||
FINDER = this;
|
||||
@@ -128,7 +133,8 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
||||
return c.getResourceAsStream(filename.startsWith("/")? filename: "/"+filename);
|
||||
}
|
||||
|
||||
protected LuaValue oncall1(int opcode, LuaValue arg) {
|
||||
public static final class BaseLib1 extends OneArgFunction {
|
||||
public LuaValue call(LuaValue arg) {
|
||||
switch ( opcode ) {
|
||||
case 0: { // "getfenv", // ( [f] ) -> env
|
||||
LuaValue f = getfenvobj(arg);
|
||||
@@ -141,8 +147,10 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
||||
}
|
||||
return NIL;
|
||||
}
|
||||
}
|
||||
|
||||
protected LuaValue oncall2(int opcode, LuaValue arg1, LuaValue arg2) {
|
||||
public static final class BaseLib2 extends TwoArgFunction {
|
||||
public LuaValue call(LuaValue arg1, LuaValue arg2) {
|
||||
switch ( opcode ) {
|
||||
case 0: // "collectgarbage", // ( opt [,arg] ) -> value
|
||||
String s = arg1.optjstring("collect");
|
||||
@@ -173,8 +181,9 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
||||
}
|
||||
return NIL;
|
||||
}
|
||||
}
|
||||
|
||||
private LuaValue getfenvobj(LuaValue arg) {
|
||||
private static LuaValue getfenvobj(LuaValue arg) {
|
||||
if ( arg.isclosure() )
|
||||
return arg;
|
||||
int level = arg.optint(1);
|
||||
@@ -185,7 +194,9 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
||||
return f;
|
||||
}
|
||||
|
||||
protected Varargs oncallv(int opcode, Varargs args) {
|
||||
public static final class BaseLibV extends VarArgFunction {
|
||||
public BaseLib baselib;
|
||||
public Varargs invoke(Varargs args) {
|
||||
switch ( opcode ) {
|
||||
case 0: // "assert", // ( v [,message] ) -> v, message | ERR
|
||||
if ( !args.arg1().toboolean() ) error("assertion failed!");
|
||||
@@ -270,12 +281,12 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
||||
{
|
||||
LuaValue tostring = LuaThread.getGlobals().get("tostring");
|
||||
for ( int i=1, n=args.narg(); i<=n; i++ ) {
|
||||
if ( i>1 ) STDOUT.write( '\t' );
|
||||
if ( i>1 ) baselib.STDOUT.write( '\t' );
|
||||
LuaString s = tostring.call( args.arg(i) ).strvalue();
|
||||
int z = s.indexOf((byte)0, 0);
|
||||
STDOUT.write( s.m_bytes, s.m_offset, z>=0? z: s.m_length );
|
||||
baselib.STDOUT.write( s.m_bytes, s.m_offset, z>=0? z: s.m_length );
|
||||
}
|
||||
STDOUT.println();
|
||||
baselib.STDOUT.println();
|
||||
return NONE;
|
||||
}
|
||||
case 8: // "select", // (f, ...) -> value1, ...
|
||||
@@ -335,9 +346,9 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
||||
}
|
||||
}
|
||||
case 16: // "pairs" (t) -> iter-func, t, nil
|
||||
return varargsOf( next, args.checktable(1) );
|
||||
return varargsOf( baselib.next, args.checktable(1) );
|
||||
case 17: // "ipairs", // (t) -> iter-func, t, 0
|
||||
return varargsOf( inext, args.checktable(1), ZERO );
|
||||
return varargsOf( baselib.inext, args.checktable(1), ZERO );
|
||||
case 18: // "next" ( table, [index] ) -> next-index, next-value
|
||||
return args.arg1().next(args.arg(2));
|
||||
case 19: // "inext" ( table, [int-index] ) -> next-index, next-value
|
||||
@@ -345,6 +356,7 @@ public class BaseLib extends OneArgFunction implements ResourceFinder {
|
||||
}
|
||||
return NONE;
|
||||
}
|
||||
}
|
||||
|
||||
public static Varargs loadFile(String filename) throws IOException {
|
||||
InputStream is = FINDER.findResource(filename);
|
||||
|
||||
@@ -111,17 +111,19 @@ public class DebugLib extends OneArgFunction {
|
||||
|
||||
public LuaValue call(LuaValue arg) {
|
||||
LuaTable t = new LuaTable();
|
||||
bindv(t, NAMES);
|
||||
bind(t, DebugLibV.class, NAMES);
|
||||
env.set("debug", t);
|
||||
return t;
|
||||
}
|
||||
|
||||
protected Varargs oncallv(int opcode, Varargs args) {
|
||||
public static final class DebugLibV extends VarArgFunction {
|
||||
protected DebugLib debuglib;
|
||||
public Varargs invoke(Varargs args) {
|
||||
switch ( opcode ) {
|
||||
case DEBUG: return _debug(args);
|
||||
case GETFENV: return _getfenv(args);
|
||||
case GETHOOK: return _gethook(args);
|
||||
case GETINFO: return _getinfo(args);
|
||||
case GETINFO: return _getinfo(args,this);
|
||||
case GETLOCAL: return _getlocal(args);
|
||||
case GETMETATABLE: return _getmetatable(args);
|
||||
case GETREGISTRY: return _getregistry(args);
|
||||
@@ -135,6 +137,7 @@ public class DebugLib extends OneArgFunction {
|
||||
default: return NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------ Debug Info management --------------------------
|
||||
//
|
||||
@@ -406,7 +409,7 @@ public class DebugLib extends OneArgFunction {
|
||||
return object;
|
||||
}
|
||||
|
||||
protected Varargs _getinfo(Varargs args) {
|
||||
protected static Varargs _getinfo(Varargs args, LuaValue level0func) {
|
||||
int a=1;
|
||||
LuaThread thread = args.isthread(a)? args.checkthread(a++): LuaThread.getRunning();
|
||||
LuaValue func = args.arg(a++);
|
||||
@@ -419,7 +422,7 @@ public class DebugLib extends OneArgFunction {
|
||||
int level = func.checkint();
|
||||
di = level>0?
|
||||
ds.getDebugInfo(level-1):
|
||||
new DebugInfo( this );
|
||||
new DebugInfo( level0func );
|
||||
} else {
|
||||
di = ds.findDebugInfo( func.checkfunction() );
|
||||
}
|
||||
|
||||
@@ -21,14 +21,42 @@
|
||||
******************************************************************************/
|
||||
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;
|
||||
|
||||
abstract public class LibFunction extends LuaFunction {
|
||||
|
||||
protected int opcode;
|
||||
protected String name;
|
||||
|
||||
protected LibFunction() {
|
||||
}
|
||||
|
||||
public String tojstring() {
|
||||
return name != null? name: super.tojstring();
|
||||
}
|
||||
|
||||
protected void bind(LuaValue env, Class factory, String[] names ) {
|
||||
bind( env, factory, names, 0 );
|
||||
}
|
||||
|
||||
protected void bind(LuaValue env, Class factory, String[] names, int firstopcode ) {
|
||||
try {
|
||||
for ( int i=0, n=names.length; i<n; i++ ) {
|
||||
LibFunction f = (LibFunction) factory.newInstance();
|
||||
f.opcode = firstopcode + i;
|
||||
f.name = names[i];
|
||||
f.env = env;
|
||||
env.set(f.name, f);
|
||||
}
|
||||
} catch ( Exception e ) {
|
||||
throw new LuaError( "bind failed: "+e );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void bind0(LuaValue env, String[] names) {
|
||||
bind(env, names, 0, 0);
|
||||
}
|
||||
@@ -100,8 +128,6 @@ abstract public class LibFunction extends LuaFunction {
|
||||
|
||||
/** Binding to a one-arg function */
|
||||
private static class ZeroArgBinding extends LibFunction {
|
||||
private final String name;
|
||||
private final int opcode;
|
||||
private final LibFunction delegate;
|
||||
|
||||
private ZeroArgBinding(String name, int opcode, LibFunction delegate) {
|
||||
@@ -137,8 +163,6 @@ abstract public class LibFunction extends LuaFunction {
|
||||
|
||||
/** Binding to a one-arg function */
|
||||
private static class OneArgBinding extends LibFunction {
|
||||
private final String name;
|
||||
private final int opcode;
|
||||
private final LibFunction delegate;
|
||||
|
||||
private OneArgBinding(String name, int opcode, LibFunction delegate) {
|
||||
@@ -174,8 +198,6 @@ abstract public class LibFunction extends LuaFunction {
|
||||
|
||||
/** Binding to a two-arg function */
|
||||
private static class TwoArgBinding extends LibFunction {
|
||||
private final String name;
|
||||
private final int opcode;
|
||||
private final LibFunction delegate;
|
||||
|
||||
private TwoArgBinding(String name, int opcode, LibFunction delegate) {
|
||||
@@ -211,8 +233,6 @@ abstract public class LibFunction extends LuaFunction {
|
||||
|
||||
/** Binding to a three-arg function */
|
||||
private static class ThreeArgBinding extends LibFunction {
|
||||
private final String name;
|
||||
private final int opcode;
|
||||
private final LibFunction delegate;
|
||||
|
||||
private ThreeArgBinding(String name, int opcode, LibFunction delegate) {
|
||||
@@ -248,8 +268,6 @@ abstract public class LibFunction extends LuaFunction {
|
||||
|
||||
/** Binding to a var-arg function */
|
||||
private static class VarArgBinding extends LibFunction {
|
||||
private final String name;
|
||||
private final int opcode;
|
||||
private final LibFunction delegate;
|
||||
|
||||
private VarArgBinding(String name, int opcode, LibFunction delegate) {
|
||||
|
||||
@@ -49,20 +49,23 @@ public class MathLib extends OneArgFunction {
|
||||
LuaTable t = new LuaTable(0,30);
|
||||
t.set( "pi", Math.PI );
|
||||
t.set( "huge", LuaDouble.POSINF );
|
||||
bind1( t, new String[] {
|
||||
bind( t, MathLib1.class, new String[] {
|
||||
"abs", "ceil", "cos", "deg",
|
||||
"exp", "floor", "rad", "sin",
|
||||
"sqrt", "tan" } );
|
||||
bind2( t, new String[] {
|
||||
bind( t, MathLib2.class, new String[] {
|
||||
"fmod", "ldexp", "pow", "random", } );
|
||||
bindv( t, new String[] {
|
||||
bind( t, MathLibV.class, new String[] {
|
||||
"frexp", "max", "min", "modf",
|
||||
"randomseed" } );
|
||||
((MathLib2) t.get("random" )).mathlib = this;
|
||||
((MathLibV) t.get("randomseed")).mathlib = this;
|
||||
env.set("math", t);
|
||||
return t;
|
||||
}
|
||||
|
||||
public LuaValue oncall1(int opcode, LuaValue arg) {
|
||||
public static final class MathLib1 extends OneArgFunction {
|
||||
public LuaValue call(LuaValue arg) {
|
||||
switch ( opcode ) {
|
||||
case 0: return valueOf(Math.abs(arg.todouble()));
|
||||
case 1: return valueOf(Math.ceil(arg.todouble()));
|
||||
@@ -77,8 +80,11 @@ public class MathLib extends OneArgFunction {
|
||||
}
|
||||
return NIL;
|
||||
}
|
||||
}
|
||||
|
||||
public LuaValue oncall2(int opcode,LuaValue arg1,LuaValue arg2) {
|
||||
public static final class MathLib2 extends TwoArgFunction {
|
||||
protected MathLib mathlib;
|
||||
public LuaValue call(LuaValue arg1, LuaValue arg2) {
|
||||
switch ( opcode ) {
|
||||
case 0: { // fmod
|
||||
double x = arg1.checkdouble();
|
||||
@@ -97,19 +103,20 @@ public class MathLib extends OneArgFunction {
|
||||
return dpow(arg1.todouble(), arg2.todouble());
|
||||
}
|
||||
case 3: { // random
|
||||
if ( random == null )
|
||||
random = new Random();
|
||||
if ( mathlib.random == null )
|
||||
mathlib.random = new Random();
|
||||
if ( arg1.isnil() )
|
||||
return valueOf( random.nextDouble() );
|
||||
return valueOf( mathlib.random.nextDouble() );
|
||||
int m = arg1.toint();
|
||||
if ( arg2.isnil() )
|
||||
return valueOf( 1 + random.nextInt(m) );
|
||||
return valueOf( 1 + mathlib.random.nextInt(m) );
|
||||
else
|
||||
return valueOf( m + random.nextInt(arg2.toint()-m) );
|
||||
return valueOf( m + mathlib.random.nextInt(arg2.toint()-m) );
|
||||
}
|
||||
}
|
||||
return NIL;
|
||||
}
|
||||
}
|
||||
|
||||
/** compute power using installed math library, or default if there is no math library installed */
|
||||
public static LuaValue dpow(double a, double b) {
|
||||
@@ -148,7 +155,9 @@ public class MathLib extends OneArgFunction {
|
||||
return p;
|
||||
}
|
||||
|
||||
public Varargs oncallv(int opcode,Varargs args) {
|
||||
public static final class MathLibV extends VarArgFunction {
|
||||
protected MathLib mathlib;
|
||||
public Varargs invoke(Varargs args) {
|
||||
switch ( opcode ) {
|
||||
case 0: { // frexp
|
||||
double x = args.checkdouble(1);
|
||||
@@ -178,10 +187,11 @@ public class MathLib extends OneArgFunction {
|
||||
}
|
||||
case 4: { // randomseed
|
||||
long seed = args.checklong(1);
|
||||
random = new Random(seed);
|
||||
mathlib.random = new Random(seed);
|
||||
return NONE;
|
||||
}
|
||||
}
|
||||
return NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,9 +41,9 @@ public class StringLib extends OneArgFunction {
|
||||
|
||||
public LuaValue call(LuaValue arg) {
|
||||
LuaTable t = new LuaTable();
|
||||
bind1(t, new String[] {
|
||||
bind(t, StringLib1.class, new String[] {
|
||||
"dump", "len", "lower", "reverse", "upper", } );
|
||||
bindv(t, new String[] {
|
||||
bind(t, StringLibV.class, new String[] {
|
||||
"byte", "char", "find", "format",
|
||||
"gmatch", "gsub", "match", "rep",
|
||||
"sub"} );
|
||||
@@ -52,19 +52,21 @@ public class StringLib extends OneArgFunction {
|
||||
return t;
|
||||
}
|
||||
|
||||
protected LuaValue oncall1(int opcode, LuaValue arg) {
|
||||
public static final class StringLib1 extends OneArgFunction {
|
||||
public LuaValue call(LuaValue arg) {
|
||||
switch ( opcode ) {
|
||||
case 0: return dump(arg); // dump (function)
|
||||
case 1: return len(arg); // len (function)
|
||||
case 1: return StringLib.len(arg); // len (function)
|
||||
case 2: return lower(arg); // lower (function)
|
||||
case 3: return reverse(arg); // reverse (function)
|
||||
case 4: return upper(arg); // upper (function)
|
||||
}
|
||||
return NIL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected Varargs oncallv(int opcode, Varargs args) {
|
||||
public static final class StringLibV extends VarArgFunction {
|
||||
public Varargs invoke(Varargs args) {
|
||||
switch ( opcode ) {
|
||||
case 0: return StringLib.byte_( args );
|
||||
case 1: return StringLib.char_( args );
|
||||
@@ -78,6 +80,7 @@ public class StringLib extends OneArgFunction {
|
||||
}
|
||||
return NONE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* string.byte (s [, i [, j]])
|
||||
|
||||
@@ -32,11 +32,11 @@ public class TableLib extends OneArgFunction {
|
||||
|
||||
public LuaValue call(LuaValue arg) {
|
||||
LuaTable t = new LuaTable();
|
||||
bind1(t, new String[] {
|
||||
bind(t, TableLib1.class, new String[] {
|
||||
"getn", // (table) -> number
|
||||
"maxn", // (table) -> number
|
||||
} );
|
||||
bindv(t, new String[] {
|
||||
bind(t, TableLibV.class, new String[] {
|
||||
"remove", // (table [, pos]) -> removed-ele
|
||||
"concat", // (table [, sep [, i [, j]]]) -> string
|
||||
"insert", // (table, [pos,] value) -> prev-ele
|
||||
@@ -48,15 +48,18 @@ public class TableLib extends OneArgFunction {
|
||||
return t;
|
||||
}
|
||||
|
||||
protected LuaValue oncall1(int opcode, LuaValue arg) {
|
||||
public static final class TableLib1 extends OneArgFunction {
|
||||
public LuaValue call(LuaValue arg) {
|
||||
switch ( opcode ) {
|
||||
case 0: return arg.checktable().getn();
|
||||
case 1: return valueOf( arg.checktable().maxn());
|
||||
}
|
||||
return NIL;
|
||||
}
|
||||
}
|
||||
|
||||
protected Varargs oncallv(int opcode, Varargs args) {
|
||||
public 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);
|
||||
@@ -91,3 +94,4 @@ public class TableLib extends OneArgFunction {
|
||||
return NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user