Type coercion for luajava package, make luajava an "addon"
This commit is contained in:
@@ -4,7 +4,6 @@ import java.util.Hashtable;
|
||||
|
||||
import lua.value.LString;
|
||||
import lua.value.LTable;
|
||||
import lua.value.LValue;
|
||||
|
||||
/**
|
||||
** `global state', shared by all threads of this state
|
||||
@@ -42,11 +41,15 @@ public class GlobalState {
|
||||
// TString *tmname[TM_N]; /* array with tag-method names */
|
||||
// } global_State;
|
||||
//
|
||||
public static LValue getGlobalsTable() {
|
||||
LTable table = new LTable();
|
||||
Builtin.addBuiltins( table );
|
||||
LuaJava.addBuiltins( table );
|
||||
table.m_hash.put(new LString("_G"), table);
|
||||
return table;
|
||||
private static LTable _G;
|
||||
|
||||
static {
|
||||
_G = new LTable();
|
||||
Builtin.addBuiltins( _G );
|
||||
_G .m_hash.put(new LString("_G"), _G );
|
||||
}
|
||||
|
||||
public static LTable getGlobalsTable() {
|
||||
return _G;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,125 +0,0 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package lua;
|
||||
|
||||
/** LuaJava-like bindings to Java scripting.
|
||||
*
|
||||
* TODO: coerce types on way in and out, pick method base on arg count ant types.
|
||||
*/
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import lua.value.LFunction;
|
||||
import lua.value.LString;
|
||||
import lua.value.LTable;
|
||||
import lua.value.LValue;
|
||||
|
||||
final class LuaJava extends LFunction {
|
||||
|
||||
static void addBuiltins(LTable table) {
|
||||
LTable luajava = new LTable();
|
||||
for ( int i=0; i<NAMES.length; i++ )
|
||||
luajava.m_hash.put( new LString( NAMES[i] ), new LuaJava(i) );
|
||||
table.m_hash.put( new LString( "luajava" ), luajava );
|
||||
}
|
||||
|
||||
private static final int NEWINSTANCE = 0;
|
||||
private static final int BINDCLASS = 1;
|
||||
private static final int NEW = 2;
|
||||
private static final int CREATEPROXY = 3;
|
||||
private static final int LOADLIB = 4;
|
||||
|
||||
private static final String[] NAMES = { "newInstance", "bindClass", "new", "createProxy", "loadLib" };
|
||||
|
||||
private int id;
|
||||
private LuaJava( int id ) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "builtin."+NAMES[id];
|
||||
}
|
||||
|
||||
// perform a lua call
|
||||
public void luaStackCall(StackState state, int base, int top, int nresults) {
|
||||
switch ( id ) {
|
||||
case NEWINSTANCE:
|
||||
String className = state.stack[base+1].luaAsString();
|
||||
try {
|
||||
Class c = Class.forName(className);
|
||||
Object o = c.newInstance();
|
||||
state.stack[base] = new LInstance( o );
|
||||
state.top = base+1;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
luaUnsupportedOperation();
|
||||
}
|
||||
if (nresults >= 0)
|
||||
state.adjustTop(base + nresults);
|
||||
}
|
||||
|
||||
static class LInstance extends LValue {
|
||||
private Object instance;
|
||||
public LInstance(Object o) {
|
||||
this.instance = o;
|
||||
}
|
||||
public String luaAsString() {
|
||||
return instance.toString();
|
||||
}
|
||||
public void luaGetTable(StackState state, int base, LValue table, LValue key) {
|
||||
Class c = instance.getClass();
|
||||
final String s = key.luaAsString();
|
||||
try {
|
||||
Field f = c.getField(s);
|
||||
Object o = f.get(instance);
|
||||
String v = String.valueOf(o);
|
||||
state.stack[base] = new LString( v );
|
||||
state.top = base + 1;
|
||||
} catch (NoSuchFieldException nsfe) {
|
||||
state.stack[base] = new LMethod(instance,s);
|
||||
state.top = base + 1;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
public void luaSetTable(StackState state, int base, LValue table, LValue key, LValue val) {
|
||||
Class c = instance.getClass();
|
||||
String s = key.luaAsString();
|
||||
try {
|
||||
Field f = c.getField(s);
|
||||
String v = val.luaAsString();
|
||||
f.set(instance,v);
|
||||
state.top = base;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static final class LMethod extends LFunction {
|
||||
private final Object instance;
|
||||
private final String s;
|
||||
private LMethod(Object instance, String s) {
|
||||
this.instance = instance;
|
||||
this.s = s;
|
||||
}
|
||||
|
||||
public void luaStackCall(StackState state, int base, int top, int nresults) {
|
||||
Class c = instance.getClass();
|
||||
try {
|
||||
Method m = c.getMethod(s,new Class[0]);
|
||||
Object o = m.invoke(instance,new Object[0]);
|
||||
String v = String.valueOf(o);
|
||||
state.stack[base] = new LString( v );
|
||||
state.top = base + 1;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -40,7 +40,7 @@ public class LDouble extends LNumber {
|
||||
case Lua.OP_MUL: return new LDouble( lhs * rhs );
|
||||
case Lua.OP_DIV: return new LDouble( lhs / rhs );
|
||||
case Lua.OP_MOD: return new LDouble( lhs % rhs );
|
||||
case Lua.OP_POW: return new LDouble( Math.pow(lhs, rhs) );
|
||||
// case Lua.OP_POW: return new LDouble( Math.pow(lhs, rhs) );
|
||||
}
|
||||
return luaUnsupportedOperation();
|
||||
}
|
||||
@@ -49,6 +49,10 @@ public class LDouble extends LNumber {
|
||||
return (int) m_value;
|
||||
}
|
||||
|
||||
public double luaAsDouble() {
|
||||
return m_value;
|
||||
}
|
||||
|
||||
// binary compares on integers, first dispatch
|
||||
public boolean luaBinCmpUnknown(int opcode, LValue lhs) {
|
||||
return lhs.luaBinCmpDouble( opcode, this.m_value );
|
||||
|
||||
@@ -35,7 +35,7 @@ public class LInteger extends LNumber {
|
||||
case Lua.OP_MUL: return new LInteger( m_value * rhs );
|
||||
case Lua.OP_DIV: return new LInteger( m_value / rhs );
|
||||
case Lua.OP_MOD: return new LInteger( m_value % rhs );
|
||||
case Lua.OP_POW: return new LInteger( (int) Math.pow(m_value, rhs) );
|
||||
// case Lua.OP_POW: return new LInteger( (int) Math.pow(m_value, rhs) );
|
||||
}
|
||||
return luaUnsupportedOperation();
|
||||
}
|
||||
|
||||
@@ -6,17 +6,23 @@ import lua.StackState;
|
||||
public class LString extends LValue {
|
||||
|
||||
final String m_string;
|
||||
final int m_hash;
|
||||
|
||||
public LString(String string) {
|
||||
this.m_string = string;
|
||||
this.m_hash = string.hashCode();
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
return o != null && o instanceof LString && m_string.equals(((LString)o).m_string);
|
||||
if ( o != null && o instanceof LString ) {
|
||||
LString s = (LString) o;
|
||||
return m_hash == s.m_hash && m_string.equals(s.m_string);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return m_string.hashCode();
|
||||
return m_hash;
|
||||
}
|
||||
|
||||
// TODO: what to do with LuaState?
|
||||
|
||||
@@ -7,7 +7,7 @@ abstract
|
||||
public class LValue {
|
||||
|
||||
protected static LValue luaUnsupportedOperation() {
|
||||
throw new java.lang.UnsupportedOperationException();
|
||||
throw new java.lang.RuntimeException( "not supported" );
|
||||
}
|
||||
|
||||
public String id() {
|
||||
@@ -106,6 +106,11 @@ public class LValue {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Return value as a double */
|
||||
public double luaAsDouble() {
|
||||
return luaAsInt();
|
||||
}
|
||||
|
||||
/** Arithmetic negative */
|
||||
public LValue luaUnaryMinus() {
|
||||
return luaUnsupportedOperation();
|
||||
|
||||
Reference in New Issue
Block a user