Improve lua2java code generation.

This commit is contained in:
James Roseborough
2010-07-29 15:10:12 +00:00
parent e3d1330763
commit cd35ad7cbd
4 changed files with 90 additions and 31 deletions

View File

@@ -22,7 +22,10 @@
package org.luaj.luajc;
import java.io.ByteArrayInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.Hashtable;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;
@@ -34,36 +37,69 @@ public class TestLuaJC {
// create the script
public static String name = "script";
public static String script =
"local a='a\\ab\\bf\\fn\\nt\\tv\\vw\\133x\\222y'\n"+
"local t={string.byte(a,1,#a)}\n"+
"print( table.concat(t,',') )\n";
"for i = 1,2 do\n"+
" t[i] = function()\n"+
" return i\n"+
" end\n"+
"end\n";
public static void main(String[] args) throws Exception {
System.out.println(script);
// create an environment to run in
LuaTable _G = JsePlatform.standardGlobals();
// compile into a chunk, or load as a class
LuaValue chunk;
if ( ! (args.length>0 && args[0].equals("nocompile")) ) {
InputStream is = new ByteArrayInputStream( script.getBytes() );
chunk = LuaJC.getInstance().load(is, "script", _G);
} else {
chunk = (LuaValue) Class.forName("script").newInstance();
try {
// create an environment to run in
LuaTable _G = JsePlatform.standardGlobals();
// compile into a chunk, or load as a class
LuaValue chunk;
if ( ! (args.length>0 && args[0].equals("nocompile")) ) {
InputStream is = new ByteArrayInputStream( script.getBytes() );
chunk = LuaJC.getInstance().load(is, "script", _G);
} else {
chunk = (LuaValue) Class.forName("script").newInstance();
}
chunk.setfenv(_G);
// call with arguments
LuaValue[] vargs = new LuaValue[args.length];
for ( int i=0; i<args.length; i++ )
vargs[i] = LuaValue.valueOf(args[i]);
Varargs cargs = LuaValue.varargsOf(vargs);
Varargs v = chunk.invoke(cargs);
// print the result
for ( int i=1; i<=v.narg(); i++ )
System.out.println("result["+i+"]: "+v.arg(i));
} catch ( Throwable e ) {
e.printStackTrace();
saveClasses();
}
chunk.setfenv(_G);
// call with arguments
LuaValue[] vargs = new LuaValue[args.length];
for ( int i=0; i<args.length; i++ )
vargs[i] = LuaValue.valueOf(args[i]);
Varargs cargs = LuaValue.varargsOf(vargs);
Varargs v = chunk.invoke(cargs);
// print the result
for ( int i=1; i<=v.narg(); i++ )
System.out.println("result["+i+"]: "+v.arg(i));
}
private static void saveClasses() throws Exception {
// create the chunk
String chunkname = "script";
String filename = "script";
String destdir = ".";
InputStream is = new ByteArrayInputStream( script.getBytes() );
Hashtable t = LuaJC.getInstance().compileAll(is, chunkname, filename);
// write out the chunk
for ( Enumeration e = t.keys(); e.hasMoreElements(); ) {
String key = (String) e.nextElement();
byte[] bytes = (byte[]) t.get(key);
String destpath = (destdir!=null? destdir+"/": "") + key + ".class";
System.out.println(
"chunk "+chunkname+
" from "+filename+
" written to "+destpath
+" length="+bytes.length+" bytes");
FileOutputStream fos = new FileOutputStream( destpath );
fos.write( bytes );
fos.close();
}
}
}

View File

@@ -27,6 +27,7 @@ import java.io.InputStream;
import junit.framework.TestCase;
import org.luaj.vm2.compiler.LuaC;
import org.luaj.vm2.lua2java.Lua2Java;
import org.luaj.vm2.luajc.LuaJC;
/**
@@ -36,16 +37,27 @@ import org.luaj.vm2.luajc.LuaJC;
*/
public class FragmentsTest extends TestCase {
static final int TEST_TYPE_LUAC = 0;
static final int TEST_TYPE_LUAJC = 1;
static final int TEST_TYPE_LUA2JAVA = 2;
static final int TEST_TYPE = TEST_TYPE_LUA2JAVA;
public void runFragment( Varargs expected, String script ) {
try {
String name = getName();
LuaTable _G = org.luaj.vm2.lib.JsePlatform.standardGlobals();
InputStream is = new ByteArrayInputStream(script.getBytes("UTF-8"));
LuaValue chunk ;
if ( true ) {
switch ( TEST_TYPE ) {
case TEST_TYPE_LUA2JAVA:
chunk = Lua2Java.instance.load(is,name,_G);
break;
case TEST_TYPE_LUAJC:
chunk = LuaJC.getInstance().load(is,name,_G);
} else {
break;
default:
chunk = LuaC.instance.load( is, name, _G );
break;
}
Varargs actual = chunk.invoke();
assertEquals( expected.narg(), actual.narg() );
@@ -135,7 +147,6 @@ public class FragmentsTest extends TestCase {
"local bar = {1000, math.sqrt(9)}\n"+
"return bar[1]+bar[2]\n" );
}
public void testMultiAssign() {
// arargs evaluations are all done before assignments
@@ -339,4 +350,15 @@ public class FragmentsTest extends TestCase {
"local a,b,c = 2,-2.5,0\n" +
"return (a==c), (b==c), (a==a), (a>c), (b>0)\n" );
}
public void testNumericForUpvalues() {
runFragment( LuaValue.valueOf(8),
"for i = 3,4 do\n"+
" i = i + 5\n"+
" local a = function()\n"+
" return i\n"+
" end\n" +
" return a()\n"+
"end\n");
}
}