diff --git a/src/main/java/lua/GlobalState.java b/src/main/java/lua/GlobalState.java index 850f4108..67ade62c 100644 --- a/src/main/java/lua/GlobalState.java +++ b/src/main/java/lua/GlobalState.java @@ -45,6 +45,7 @@ public class GlobalState { public static LValue getGlobalsTable() { LTable table = new LTable(); Builtin.addBuiltins( table ); + LuaJava.addBuiltins( table ); table.m_hash.put(new LString("_G"), table); return table; } diff --git a/src/main/java/lua/LuaJava.java b/src/main/java/lua/LuaJava.java new file mode 100644 index 00000000..96ec3cb1 --- /dev/null +++ b/src/main/java/lua/LuaJava.java @@ -0,0 +1,125 @@ +/** + * + */ +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= 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); + } + } + } +} \ No newline at end of file diff --git a/src/test/java/SampleClass.java b/src/test/java/SampleClass.java new file mode 100644 index 00000000..4c7c67be --- /dev/null +++ b/src/test/java/SampleClass.java @@ -0,0 +1,22 @@ + +public class SampleClass { + + public String s; + public String t; + + public SampleClass() { + } + + public SampleClass(String a, String b) { + s = a; + t = b; + } + + public String getS() { + return s; + } + + public void setS(String s) { + this.s = s; + } +} diff --git a/src/test/res/compile.sh b/src/test/res/compile.sh index 4cf64760..f569c37a 100644 --- a/src/test/res/compile.sh +++ b/src/test/res/compile.sh @@ -1,7 +1,7 @@ #!/bin/bash LUA_HOME=/cygdrive/c/programs/lua5.1 TESTS="test1 test2 test3 test4 test5" -TESTS="test6" +TESTS="test7" for x in $TESTS do echo compiling $x diff --git a/src/test/res/test7.lua b/src/test/res/test7.lua new file mode 100644 index 00000000..f249083e --- /dev/null +++ b/src/test/res/test7.lua @@ -0,0 +1,11 @@ +obj = luajava.newInstance("java.lang.Object") +print( obj ) + +obj = luajava.newInstance("SampleClass") +print( obj ) +obj.s = "Hello" +print( obj.s ) +print( obj.getS() ) + +obj.setS( "World" ) +print( obj.s )