Type coercion for luajava package, make luajava an "addon"
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src/main/java"/>
|
||||
<classpathentry kind="src" path="src/addon/java"/>
|
||||
<classpathentry kind="src" path="src/test/java"/>
|
||||
<classpathentry kind="src" path="src/test/res"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
|
||||
65
src/addon/java/lua/addon/luajava/CoerceJavaToLua.java
Normal file
65
src/addon/java/lua/addon/luajava/CoerceJavaToLua.java
Normal file
@@ -0,0 +1,65 @@
|
||||
package lua.addon.luajava;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import lua.addon.luajava.LuaJava.LInstance;
|
||||
import lua.value.LBoolean;
|
||||
import lua.value.LDouble;
|
||||
import lua.value.LInteger;
|
||||
import lua.value.LNil;
|
||||
import lua.value.LString;
|
||||
import lua.value.LValue;
|
||||
|
||||
public class CoerceJavaToLua {
|
||||
|
||||
public static interface Coercion {
|
||||
public LValue coerce( Object javaValue );
|
||||
};
|
||||
|
||||
private static Map<Class,Coercion> COERCIONS = new HashMap<Class,Coercion>();
|
||||
|
||||
static {
|
||||
Coercion boolCoercion = new Coercion() {
|
||||
public LValue coerce( Object javaValue ) {
|
||||
Boolean b = (Boolean) javaValue;
|
||||
return b.booleanValue()? LBoolean.TRUE: LBoolean.FALSE;
|
||||
}
|
||||
} ;
|
||||
Coercion intCoercion = new Coercion() {
|
||||
public LValue coerce( Object javaValue ) {
|
||||
Number n = (Number) javaValue;
|
||||
return new LInteger( n.intValue() );
|
||||
}
|
||||
} ;
|
||||
Coercion doubleCoercion = new Coercion() {
|
||||
public LValue coerce( Object javaValue ) {
|
||||
Number n = (Number) javaValue;
|
||||
return new LDouble( n.doubleValue() );
|
||||
}
|
||||
} ;
|
||||
Coercion stringCoercion = new Coercion() {
|
||||
public LValue coerce( Object javaValue ) {
|
||||
return new LString( javaValue.toString() );
|
||||
}
|
||||
} ;
|
||||
COERCIONS.put( Boolean.class, boolCoercion );
|
||||
COERCIONS.put( Byte.class, intCoercion );
|
||||
COERCIONS.put( Short.class, intCoercion );
|
||||
COERCIONS.put( Integer.class, intCoercion );
|
||||
COERCIONS.put( Float.class, doubleCoercion );
|
||||
COERCIONS.put( Double.class, doubleCoercion );
|
||||
COERCIONS.put( String.class, stringCoercion );
|
||||
}
|
||||
|
||||
public static LValue coerce(Object o) {
|
||||
if ( o == null )
|
||||
return LNil.NIL;
|
||||
Class clazz = o.getClass();
|
||||
Coercion c = COERCIONS.get( clazz );
|
||||
if ( c != null )
|
||||
return c.coerce( o );
|
||||
return new LInstance( o, o.getClass() );
|
||||
}
|
||||
|
||||
}
|
||||
144
src/addon/java/lua/addon/luajava/CoerceLuaToJava.java
Normal file
144
src/addon/java/lua/addon/luajava/CoerceLuaToJava.java
Normal file
@@ -0,0 +1,144 @@
|
||||
package lua.addon.luajava;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import lua.StackState;
|
||||
import lua.addon.luajava.LuaJava.LInstance;
|
||||
import lua.value.LBoolean;
|
||||
import lua.value.LDouble;
|
||||
import lua.value.LInteger;
|
||||
import lua.value.LNil;
|
||||
import lua.value.LNumber;
|
||||
import lua.value.LString;
|
||||
import lua.value.LValue;
|
||||
|
||||
public class CoerceLuaToJava {
|
||||
|
||||
public static interface Coercion {
|
||||
public Object coerce( LValue value );
|
||||
public int score( LValue value );
|
||||
};
|
||||
|
||||
private static Map<Class,Coercion> COERCIONS = new HashMap<Class,Coercion>();
|
||||
private static Coercion OBJECT_COERCION;
|
||||
|
||||
static {
|
||||
Coercion boolCoercion = new Coercion() {
|
||||
public Object coerce(LValue value) {
|
||||
return value.luaAsBoolean()? Boolean.TRUE: Boolean.FALSE;
|
||||
}
|
||||
public int score(LValue value) {
|
||||
if ( value instanceof LBoolean || value == LNil.NIL )
|
||||
return 0;
|
||||
if ( value instanceof LNumber )
|
||||
return 1;
|
||||
return 4;
|
||||
}
|
||||
};
|
||||
Coercion intCoercion = new Coercion() {
|
||||
public Object coerce(LValue value) {
|
||||
return Integer.valueOf( value.luaAsInt() );
|
||||
}
|
||||
public int score(LValue value) {
|
||||
if ( value instanceof LInteger )
|
||||
return 0;
|
||||
if ( value instanceof LNumber )
|
||||
return 1;
|
||||
if ( value instanceof LBoolean || value == LNil.NIL )
|
||||
return 2;
|
||||
return 4;
|
||||
}
|
||||
};
|
||||
Coercion stringCoercion = new Coercion() {
|
||||
public Object coerce(LValue value) {
|
||||
return value.luaAsString();
|
||||
}
|
||||
public int score(LValue value) {
|
||||
if ( value instanceof LInstance )
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
Coercion objectCoercion = new Coercion() {
|
||||
public Object coerce(LValue value) {
|
||||
if ( value instanceof LInstance )
|
||||
return ((LInstance)value).instance;
|
||||
if ( value instanceof LString )
|
||||
return value.luaAsString();
|
||||
if ( value instanceof LInteger )
|
||||
return Integer.valueOf(value.luaAsInt());
|
||||
if ( value instanceof LDouble )
|
||||
return Double.valueOf(value.luaAsDouble());
|
||||
if ( value instanceof LBoolean )
|
||||
return Boolean.valueOf(value.luaAsBoolean());
|
||||
if ( value == LNil.NIL )
|
||||
return null;
|
||||
return value;
|
||||
}
|
||||
public int score(LValue value) {
|
||||
if ( value instanceof LString )
|
||||
return 0;
|
||||
return 0x10;
|
||||
}
|
||||
};
|
||||
COERCIONS.put( Boolean.TYPE, boolCoercion );
|
||||
COERCIONS.put( Boolean.class, boolCoercion );
|
||||
COERCIONS.put( Byte.TYPE, intCoercion );
|
||||
COERCIONS.put( Byte.class, intCoercion );
|
||||
COERCIONS.put( Short.TYPE, intCoercion );
|
||||
COERCIONS.put( Short.class, intCoercion );
|
||||
COERCIONS.put( Integer.TYPE, intCoercion );
|
||||
COERCIONS.put( Integer.class, intCoercion );
|
||||
COERCIONS.put( Long.TYPE, intCoercion );
|
||||
COERCIONS.put( Long.class, intCoercion );
|
||||
COERCIONS.put( String.class, stringCoercion );
|
||||
COERCIONS.put( Object.class, objectCoercion );
|
||||
}
|
||||
|
||||
static Object coerceArg(LValue v, Class type) {
|
||||
Coercion co = COERCIONS.get( type );
|
||||
if ( co != null )
|
||||
return co.coerce( v );
|
||||
if ( v instanceof LInstance )
|
||||
return ((LInstance) v).instance;
|
||||
return v;
|
||||
}
|
||||
|
||||
static Object[] coerceArgs(StackState state, int base, int nargs, Class[] parameterTypes) {
|
||||
int n = parameterTypes.length;
|
||||
Object[] args = new Object[n];
|
||||
for ( int i=0; i<n && i<nargs; i++ )
|
||||
args[i] = coerceArg( state.stack[base+i], parameterTypes[i] );
|
||||
return args;
|
||||
}
|
||||
|
||||
/*
|
||||
* Score parameter types for match with supplied parameter list
|
||||
*
|
||||
* 1) exact number of args
|
||||
* 2) java has more args
|
||||
* 3) java has less args
|
||||
* 4) types coerce well
|
||||
*/
|
||||
static int scoreParamTypes(LValue[] stack, int base, int nargs, Class[] paramTypes) {
|
||||
int njava = paramTypes.length;
|
||||
int score = (njava == nargs? 0: njava > nargs? 0x4000: 0x8000);
|
||||
for ( int i=0; i<nargs && i<njava; i++ ) {
|
||||
LValue v = stack[base+i];
|
||||
Class c = paramTypes[i];
|
||||
Coercion co = COERCIONS.get( c );
|
||||
if ( co != null ) {
|
||||
score += co.score( v );
|
||||
} else if ( v instanceof LInstance ) {
|
||||
Object o = ((LInstance) v).instance;
|
||||
if ( ! c.isAssignableFrom(o.getClass()) )
|
||||
score += 0x10000;
|
||||
} else {
|
||||
score += 0x100;
|
||||
}
|
||||
}
|
||||
return score;
|
||||
}
|
||||
|
||||
}
|
||||
182
src/addon/java/lua/addon/luajava/LuaJava.java
Normal file
182
src/addon/java/lua/addon/luajava/LuaJava.java
Normal file
@@ -0,0 +1,182 @@
|
||||
package lua.addon.luajava;
|
||||
|
||||
|
||||
/** 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.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import lua.GlobalState;
|
||||
import lua.StackState;
|
||||
import lua.value.LFunction;
|
||||
import lua.value.LString;
|
||||
import lua.value.LTable;
|
||||
import lua.value.LValue;
|
||||
|
||||
public final class LuaJava extends LFunction {
|
||||
|
||||
public static void install() {
|
||||
LTable luajava = new LTable();
|
||||
for ( int i=0; i<NAMES.length; i++ )
|
||||
luajava.m_hash.put( new LString( NAMES[i] ), new LuaJava(i) );
|
||||
GlobalState.getGlobalsTable().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 "luajava."+NAMES[id];
|
||||
}
|
||||
|
||||
// perform a lua call
|
||||
public void luaStackCall(StackState state, int base, int top, int nresults) {
|
||||
String className;
|
||||
switch ( id ) {
|
||||
case BINDCLASS:
|
||||
className = state.stack[base+1].luaAsString();
|
||||
try {
|
||||
Class clazz = Class.forName(className);
|
||||
state.stack[base] = new LInstance( clazz, clazz );
|
||||
state.top = base+1;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
break;
|
||||
case NEWINSTANCE:
|
||||
className = state.stack[base+1].luaAsString();
|
||||
try {
|
||||
Class clazz = Class.forName(className);
|
||||
Constructor[] cons = clazz.getConstructors();
|
||||
Constructor con = cons[0];
|
||||
Class[] paramTypes = con.getParameterTypes();
|
||||
int paramsBase = base + 2;
|
||||
int nargs = top - paramsBase;
|
||||
int score = CoerceLuaToJava.scoreParamTypes( state.stack, paramsBase, nargs, paramTypes );
|
||||
for ( int i=1; i<cons.length; i++ ) {
|
||||
Constructor c = cons[i];
|
||||
Class[] p = c.getParameterTypes();
|
||||
int s = CoerceLuaToJava.scoreParamTypes( state.stack, paramsBase, nargs, p );
|
||||
if ( s < score ) {
|
||||
con = c;
|
||||
paramTypes = p;
|
||||
score = s;
|
||||
}
|
||||
}
|
||||
Object[] args = CoerceLuaToJava.coerceArgs( state, paramsBase, nargs, paramTypes );
|
||||
Object o = con.newInstance( args );
|
||||
state.stack[base] = new LInstance( o, clazz );
|
||||
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 {
|
||||
Object instance;
|
||||
private Class clazz;
|
||||
public LInstance(Object o, Class clazz) {
|
||||
this.instance = o;
|
||||
this.clazz = clazz;
|
||||
}
|
||||
public String luaAsString() {
|
||||
return instance.toString();
|
||||
}
|
||||
public void luaGetTable(StackState state, int base, LValue table, LValue key) {
|
||||
final String s = key.luaAsString();
|
||||
try {
|
||||
Field f = clazz.getField(s);
|
||||
Object o = f.get(instance);
|
||||
LValue v = CoerceJavaToLua.coerce( o );
|
||||
state.stack[base] = v;
|
||||
state.top = base + 1;
|
||||
} catch (NoSuchFieldException nsfe) {
|
||||
state.stack[base] = new LMethod(instance,clazz,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);
|
||||
Object v = CoerceLuaToJava.coerceArg(val, f.getType());
|
||||
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 Class clazz;
|
||||
private final String s;
|
||||
private LMethod(Object instance, Class clazz, String s) {
|
||||
this.instance = instance;
|
||||
this.clazz = clazz;
|
||||
this.s = s;
|
||||
}
|
||||
public String toString() {
|
||||
return clazz.getName()+"."+s+"()";
|
||||
}
|
||||
public void luaStackCall(StackState state, int base, int top, int nresults) {
|
||||
try {
|
||||
Method[] meths = clazz.getMethods();
|
||||
Method meth = null;
|
||||
Class[] paramTypes = null;
|
||||
int score = Integer.MAX_VALUE;
|
||||
int paramsBase = base + 2;
|
||||
int nargs = top - paramsBase;
|
||||
for ( int i=0; i<meths.length; i++ ) {
|
||||
Method m = meths[i];
|
||||
String name = m.getName();
|
||||
if ( s.equals(name) ) {
|
||||
Class[] p = m.getParameterTypes();
|
||||
int s = CoerceLuaToJava.scoreParamTypes( state.stack, paramsBase, nargs, p );
|
||||
if ( s < score ) {
|
||||
meth = m;
|
||||
paramTypes = p;
|
||||
score = s;
|
||||
}
|
||||
}
|
||||
}
|
||||
Object[] args = CoerceLuaToJava.coerceArgs( state, paramsBase, nargs, paramTypes );
|
||||
Object result = meth.invoke( instance, args );
|
||||
state.stack[base] = CoerceJavaToLua.coerce(result);
|
||||
state.top = base + 1;
|
||||
state.adjustTop(base+nresults);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
49
src/test/java/LuaJavaAppRunner.java
Normal file
49
src/test/java/LuaJavaAppRunner.java
Normal file
@@ -0,0 +1,49 @@
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import lua.GlobalState;
|
||||
import lua.StackState;
|
||||
import lua.addon.luajava.LuaJava;
|
||||
import lua.io.Closure;
|
||||
import lua.io.LoadState;
|
||||
import lua.io.Proto;
|
||||
import lua.value.LString;
|
||||
|
||||
/**
|
||||
* Program to run a compiled lua chunk for test purposes,
|
||||
* but with the LuaJava add-ons added in
|
||||
*
|
||||
* @author jim_roseborough
|
||||
*/
|
||||
public class LuaJavaAppRunner {
|
||||
|
||||
public static void main( String[] args ) throws IOException {
|
||||
|
||||
// add LuaJava bindings
|
||||
LuaJava.install();
|
||||
|
||||
// get script name
|
||||
String script = (args.length>0? args[0]: "/swingapp.luac");
|
||||
System.out.println("loading '"+script+"'");
|
||||
|
||||
// new lua state
|
||||
StackState state = new StackState();
|
||||
|
||||
// push args onto stack
|
||||
for ( int i=1; i<args.length; i++ )
|
||||
state.push(new LString(args[i]));
|
||||
|
||||
// load the file
|
||||
InputStream is = LuaJavaAppRunner.class.getResourceAsStream( script );
|
||||
Proto p = LoadState.undump(state, is, script);
|
||||
|
||||
// create closure to execute
|
||||
Closure c = new Closure( state, p );
|
||||
state.push( c );
|
||||
for ( int i=0; i<args.length; i++ )
|
||||
state.push( new LString(args[i]) );
|
||||
state.docall(args.length, 0);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
@@ -19,7 +18,7 @@ public class LuacRunner {
|
||||
public static void main( String[] args ) throws IOException {
|
||||
|
||||
// get script name
|
||||
String script = (args.length>0? args[0]: "src/test/res/test1.luac");
|
||||
String script = (args.length>0? args[0]: "/test1.luac");
|
||||
System.out.println("loading '"+script+"'");
|
||||
|
||||
// new lua state
|
||||
@@ -30,7 +29,7 @@ public class LuacRunner {
|
||||
state.push(new LString(args[i]));
|
||||
|
||||
// load the file
|
||||
InputStream is = new FileInputStream( script );
|
||||
InputStream is = LuacRunner.class.getResourceAsStream( script );
|
||||
Proto p = LoadState.undump(state, is, script);
|
||||
|
||||
// create closure to execute
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/bash
|
||||
LUA_HOME=/cygdrive/c/programs/lua5.1
|
||||
TESTS="test1 test2 test3 test4 test5"
|
||||
TESTS="test7"
|
||||
TESTS="test1 test2 test3 test4 test5 swingapp"
|
||||
TESTS="swingapp"
|
||||
for x in $TESTS
|
||||
do
|
||||
echo compiling $x
|
||||
|
||||
20
src/test/res/swingapp.lua
Normal file
20
src/test/res/swingapp.lua
Normal file
@@ -0,0 +1,20 @@
|
||||
|
||||
frame = luajava.newInstance( "javax.swing.JFrame", "Texts" );
|
||||
pane = luajava.newInstance( "javax.swing.JPanel" );
|
||||
borderFactory = luajava.bindClass( "javax.swing.BorderFactory" )
|
||||
border = borderFactory:createEmptyBorder( 30, 30, 10, 30 )
|
||||
pane:setBorder( border )
|
||||
label = luajava.newInstance( "javax.swing.JLabel", "This is a Label" );
|
||||
|
||||
|
||||
layout = luajava.newInstance( "java.awt.GridLayout", 2, 2 );
|
||||
pane:setLayout( layout )
|
||||
pane:add( label )
|
||||
pane:setBounds( 20, 30, 10, 30 )
|
||||
|
||||
borderLayout = luajava.bindClass( "java.awt.BorderLayout" )
|
||||
frame:getContentPane():add(pane, borderLayout.CENTER )
|
||||
jframe = luajava.bindClass( "javax.swing.JFrame" )
|
||||
frame:setDefaultCloseOperation(jframe.EXIT_ON_CLOSE)
|
||||
frame:pack()
|
||||
frame:setVisible(true)
|
||||
BIN
src/test/res/swingapp.luac
Normal file
BIN
src/test/res/swingapp.luac
Normal file
Binary file not shown.
@@ -1,5 +1,84 @@
|
||||
for cycle = 1,100 do
|
||||
|
||||
a = 123 + 456
|
||||
print( a )
|
||||
|
||||
i = 777
|
||||
while i<780 do
|
||||
print(i)
|
||||
i = i+1
|
||||
end
|
||||
|
||||
a,b = 0,1
|
||||
while true do -- infinite loop
|
||||
print( b )
|
||||
a,b = b,a+b
|
||||
if a>10 then break end -- exit the loop if the condition is true
|
||||
end
|
||||
|
||||
for count = 336,330,-2 do print(count) end -- numerical iteration
|
||||
|
||||
function sum(a,b,c,d) -- "sum" method
|
||||
local d = d or 0
|
||||
return a+b+c+d -- return sum
|
||||
end
|
||||
print( sum( 1, 2, 3, 4 ) )
|
||||
print( sum( 5, 6, 7 ) )
|
||||
print( sum( 9, 10, 11, 12, 13, 14 ) )
|
||||
print( sum( sum(1,2,3,4), sum(5,6,7), sum(9,10,11,12,13,14), 15 ) )
|
||||
|
||||
|
||||
function f0() print( "f0:" ) end
|
||||
function f1(a) print( "f1:", a ) end
|
||||
function f2(a,b) print( "f2:", a, b ) end
|
||||
function f3(a,b,c) print( "f3:", a, b, c ) end
|
||||
function f4(a,b,c,d) print( "f4:", a, b, c, d ) end
|
||||
|
||||
f0() f0( "a1/1" ) f0( "a1/2", "a2/2" ) f0( "a1/3", "a2/3", "a3/3" ) f0( "a1/4", "a2/4", "a3/4", "a4/4" )
|
||||
f1() f1( "a1/1" ) f1( "a1/2", "a2/2" ) f1( "a1/3", "a2/3", "a3/3" ) f1( "a1/4", "a2/4", "a3/4", "a4/4" )
|
||||
f2() f2( "a1/1" ) f2( "a1/2", "a2/2" ) f2( "a1/3", "a2/3", "a3/3" ) f2( "a1/4", "a2/4", "a3/4", "a4/4" )
|
||||
f3() f3( "a1/1" ) f3( "a1/2", "a2/2" ) f3( "a1/3", "a2/3", "a3/3" ) f3( "a1/4", "a2/4", "a3/4", "a4/4" )
|
||||
f4() f4( "a1/1" ) f4( "a1/2", "a2/2" ) f4( "a1/3", "a2/3", "a3/3" ) f4( "a1/4", "a2/4", "a3/4", "a4/4" )
|
||||
|
||||
function g0(a,b,c,d) return end
|
||||
function g1(a,b,c,d) return d end
|
||||
function g2(a,b,c,d) return c, d end
|
||||
function g3(a,b,c,d) return b, c, d end
|
||||
function g4(a,b,c,d) return a, b, c, d end
|
||||
|
||||
z = g0("c0.1/4", "c0.2/4", "c0.3/4", "c0.4/4")
|
||||
print( "z0:", z )
|
||||
z = g2("c2.1/4", "c2.2/4", "c2.3/4", "c2.4/4")
|
||||
print( "z2:", z )
|
||||
z = g4("c4.1/4", "c4.2/4", "c4.3/4", "c4.4/4")
|
||||
print( "z4:", z )
|
||||
|
||||
a,b,c,d = g0( "c0.1/4", "c0.2/4", "c0.3/4", "c0.4/4" )
|
||||
print( "g0:", a, b, c, d, "(eol)" )
|
||||
a,b,c,d = g2( "b2.1/4", "b2.2/4", "b2.3/4", "b2.4/4" )
|
||||
print( "g2:", a, b, c, d, "(eol)" )
|
||||
a,b,c,d = g4( "b4.1/4", "b4.2/4", "b4.3/4", "b4.4/4" )
|
||||
print( "g4:", a, b, c, d, "(eol)" )
|
||||
|
||||
function func(a,b,c)
|
||||
return a, b, c
|
||||
end
|
||||
|
||||
print( func(11, 12, 13) )
|
||||
print( func(23, 22, 21) )
|
||||
print( func(func(32,33,34), func(45,46,47), func(58,59,50)) )
|
||||
|
||||
function p(a,...)
|
||||
print("a",a)
|
||||
-- print("...",...)
|
||||
-- print("...,a",...,a)
|
||||
-- print("a,...",a,...)
|
||||
end
|
||||
p()
|
||||
p("q")
|
||||
p("q","r")
|
||||
p("q","r","s")
|
||||
|
||||
|
||||
|
||||
end
|
||||
Binary file not shown.
BIN
src/test/res/test7.luac
Normal file
BIN
src/test/res/test7.luac
Normal file
Binary file not shown.
Reference in New Issue
Block a user