Remove support for lua2java within luaj.

This commit is contained in:
James Roseborough
2012-09-08 04:15:06 +00:00
parent f2d1106fe5
commit f224957b87
11 changed files with 19 additions and 1748 deletions

View File

@@ -38,7 +38,6 @@ import org.luaj.vm2.Print;
import org.luaj.vm2.Varargs;
import org.luaj.vm2.lib.DebugLib;
import org.luaj.vm2.lib.jse.JsePlatform;
import org.luaj.vm2.lua2java.Lua2Java;
import org.luaj.vm2.luajc.LuaJC;
@@ -55,7 +54,6 @@ public class lua {
" -l name require library 'name'\n" +
" -i enter interactive mode after executing 'script'\n" +
" -v show version information\n" +
" -j use lua2java source-to-source compiler\n" +
" -b use luajc bytecode-to-bytecode compiler (requires bcel on class path)\n" +
" -n nodebug - do not load debug library by default\n" +
" -p pretty-print the prototype\n" +
@@ -78,7 +76,6 @@ public class lua {
boolean nodebug = false;
boolean print = false;
boolean luajc = false;
boolean lua2java = false;
Vector libs = null;
try {
// stateful argument processing
@@ -99,9 +96,6 @@ public class lua {
case 'b':
luajc = true;
break;
case 'j':
lua2java = true;
break;
case 'l':
if ( ++i >= args.length )
usageExit();
@@ -139,7 +133,6 @@ public class lua {
// new lua state
_G = nodebug? JsePlatform.standardGlobals(): JsePlatform.debugGlobals();
if ( luajc ) LuaJC.install();
if ( lua2java) Lua2Java.install();
for ( int i=0, n=libs!=null? libs.size(): 0; i<n; i++ )
loadLibrary( (String) libs.elementAt(i) );

View File

@@ -1,213 +0,0 @@
/*******************************************************************************
* Copyright (c) 2010 Luaj.org. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import org.luaj.vm2.Lua;
import org.luaj.vm2.ast.Chunk;
import org.luaj.vm2.lib.jse.JsePlatform;
import org.luaj.vm2.lua2java.JavaCodeGen;
import org.luaj.vm2.parser.LuaParser;
/**
* Compile lua sources into java sources.
*/
public class lua2java {
private static final String version = Lua._VERSION + "Copyright (C) 2010 luaj.org";
private static final String usage =
"usage: java -cp luaj-jse.jar lua2java [options] fileordir [, fileordir ...]\n" +
"Available options are:\n" +
" - process stdin\n" +
" -s src source directory\n" +
" -d dir destination directory\n" +
" -p pkg package prefix to apply to all classes\n" +
" -e enc override default character encoding\n" +
" -r recursively compile all\n" +
" -v verbose\n";
private static void usageExit() {
System.out.println(usage);
System.exit(-1);
}
private String srcdir = null;
private String destdir = null;
private String pkgprefix = null;
private String encoding = "ISO8859-1";
private boolean recurse = false;
private boolean verbose = false;
private List files = new ArrayList();
public static void main( String[] args ) throws IOException {
new lua2java( args );
}
private lua2java( String[] args ) throws IOException {
// process args
try {
List seeds = new ArrayList ();
// get stateful args
for ( int i=0; i<args.length; i++ ) {
if ( ! args[i].startsWith("-") ) {
seeds.add(args[i]);
} else {
switch ( args[i].charAt(1) ) {
case 's':
if ( ++i >= args.length )
usageExit();
srcdir = args[i];
break;
case 'd':
if ( ++i >= args.length )
usageExit();
destdir = args[i];
break;
case 'p':
if ( ++i >= args.length )
usageExit();
pkgprefix = args[i];
break;
case 'e':
if ( ++i >= args.length )
usageExit();
encoding = args[i];
break;
case 'r':
recurse = true;
break;
case 'v':
verbose = true;
break;
default:
usageExit();
break;
}
}
}
// echo version
if ( verbose ) {
System.out.println(version);
System.out.println("srcdir: "+srcdir);
System.out.println("destdir: "+destdir);
System.out.println("files: "+seeds);
System.out.println("encoding: "+encoding);
System.out.println("recurse: "+recurse);
}
// need at least one seed
if ( seeds.size() <= 0 ) {
System.err.println(usage);
System.exit(-1);
}
// collect up files to process
for ( int i=0; i<seeds.size(); i++ )
collectFiles( srcdir+"/"+seeds.get(i) );
// check for at least one file
if ( files.size() <= 0 ) {
System.err.println("no files found in "+seeds);
System.exit(-1);
}
// process input files
JsePlatform.standardGlobals();
for ( int i=0,n=files.size(); i<n; i++ )
processFile( (InputFile) files.get(i) );
} catch ( Exception ioe ) {
System.err.println( ioe.toString() );
System.exit(-2);
}
}
private void collectFiles(String path) {
File f = new File(path);
if ( f.isDirectory() && recurse )
scandir(f,pkgprefix);
else if ( f.isFile() ) {
File dir = f.getAbsoluteFile().getParentFile();
if ( dir != null )
scanfile( dir, f, pkgprefix );
}
}
private void scandir(File dir, String javapackage) {
File[] f = dir.listFiles();
for ( int i=0; i<f.length; i++ )
scanfile( dir, f[i], javapackage );
}
private void scanfile(File dir, File f, String javapackage) {
if ( f.exists() ) {
if ( f.isDirectory() && recurse )
scandir( f, (javapackage!=null? javapackage+"."+f.getName(): f.getName()) );
else if ( f.isFile() && f.getName().endsWith(".lua") )
files.add( new InputFile(dir,f,javapackage) );
}
}
class InputFile {
public File infile;
public File outdir;
public File outfile;
public String javapackage;
public String javaclassname;
public InputFile(File dir, File f, String javapackage) {
String outdirpath = javapackage!=null? destdir+"/"+javapackage.replace('.', '/'): destdir;
this.javaclassname = f.getName().substring(0,f.getName().lastIndexOf('.'));
this.javapackage = javapackage;
this.infile = f;
this.outdir = new File(outdirpath);
this.outfile = new File(outdirpath+"/"+this.javaclassname+".java");
}
}
private void processFile( InputFile inf ) {
inf.outdir.mkdirs();
try {
if ( verbose )
System.out.println(
"pkg="+inf.javapackage+" file="+inf.javaclassname+".java dest="+inf.outfile+" src="+inf.infile);
FileInputStream in = new FileInputStream(inf.infile);
FileOutputStream out = new FileOutputStream(inf.outfile);
PrintWriter pw = new PrintWriter(out);
LuaParser parser = new LuaParser(in,encoding);
Chunk chunk = parser.Chunk();
new JavaCodeGen(chunk,pw,inf.javapackage,inf.javaclassname);
pw.close();
out.close();
in.close();
} catch ( Exception e ) {
e.printStackTrace( System.err );
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,189 +0,0 @@
/*******************************************************************************
* Copyright (c) 2010 Luaj.org. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
******************************************************************************/
package org.luaj.vm2.lua2java;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.luaj.vm2.Lua;
import org.luaj.vm2.ast.Block;
import org.luaj.vm2.ast.Chunk;
import org.luaj.vm2.ast.FuncBody;
import org.luaj.vm2.ast.NameScope;
import org.luaj.vm2.ast.Variable;
import org.luaj.vm2.ast.Visitor;
import org.luaj.vm2.ast.Exp.BinopExp;
import org.luaj.vm2.ast.Exp.VarargsExp;
import org.luaj.vm2.ast.Stat.Return;
import org.luaj.vm2.lib.LibFunction;
public class JavaScope extends NameScope {
private static final int MAX_CONSTNAME_LEN = 8;
public static final Set<String> SPECIALS = new HashSet<String>();
private static final String[] specials = {
// keywords used by our code generator
"name", "opcode", "env", // "arg",
// java keywords
"abstract", "continue", "for", "new", "switch",
"assert", "default", "goto", "package", "synchronized",
"boolean", "do", "if", "private", "this",
"break", "double", "implements", "protected", "throw",
"byte", "else", "import", "public", "throws",
"case", "enum", "instanceof", "return", "transient",
"catch", "extends", "int", "short", "try",
"char", "final", "interface", "static", "void",
"class", "finally", "long", "strictfp", "volatile",
"const", "float", "native", "super", "while",
// java literals
"false", "null", "true",
};
static {
for ( int i=0; i<specials.length; i++ )
SPECIALS.add(specials[i]);
java.lang.reflect.Field[] fields = LibFunction.class.getFields();
for ( int i=0, n=fields.length; i<n; i++ )
SPECIALS.add(fields[i].getName());
java.lang.reflect.Method[] methods = LibFunction.class.getMethods();
for ( int i=0, n=methods.length; i<n; i++ )
SPECIALS.add(methods[i].getName());
}
public int nreturns;
public boolean needsbinoptmp;
public boolean usesvarargs;
final Set<String> staticnames;
final Set<String> javanames = new HashSet<String>();
final Map<Object,String> astele2javaname = new HashMap<Object,String>();
private JavaScope(Set<String> staticnames, JavaScope outerScope) {
super(outerScope);
this.staticnames = staticnames;
}
public static JavaScope newJavaScope(Chunk chunk) {
return new JavaScope(new HashSet<String>(), null).initialize(chunk.block, -1);
}
public JavaScope pushJavaScope(FuncBody body) {
return new JavaScope(staticnames, this).initialize(body.block, 0);
}
public JavaScope popJavaScope() {
return (JavaScope) outerScope;
}
final String getJavaName(Variable nv) {
for ( JavaScope s = this; s != null; s = (JavaScope) s.outerScope )
if ( s.astele2javaname.containsKey(nv) )
return (String) s.astele2javaname.get(nv);
return allocateJavaName( nv, nv.name );
}
final private String allocateJavaName(Object astele, String proposal) {
for ( int i=0; true; i++ ) {
String jname = proposal+(i==0? "": "$"+i);
if ( ! isJavanameInScope(jname) && ! SPECIALS.contains(jname) && !staticnames.contains(jname) ) {
javanames.add(jname);
astele2javaname.put(astele,jname);
return jname;
}
}
}
public void setJavaName(Variable astele, String javaname) {
javanames.add(javaname);
astele2javaname.put(astele,javaname);
}
private boolean isJavanameInScope(String javaname) {
for ( JavaScope s = this; s != null; s = (JavaScope) s.outerScope )
if ( s.javanames.contains(javaname) )
return true;
return false;
}
public String createConstantName(String proposal) {
proposal = toLegalJavaName(proposal);
for ( int i=0; true; i++ ) {
String jname = proposal+(i==0? "": "$"+i);
if ( ! isJavanameInScope(jname) && ! SPECIALS.contains(jname) && !staticnames.contains(jname) ) {
javanames.add(jname);
staticnames.add(jname);
return jname;
}
}
}
public static String toLegalJavaName(String string) {
String better = string.replaceAll("[^\\w]", "_");
if ( better.length() > MAX_CONSTNAME_LEN )
better = better.substring(0,MAX_CONSTNAME_LEN);
if ( better.length() == 0 || !Character.isJavaIdentifierStart( better.charAt(0) ) )
better = "_"+better;
return better;
}
private JavaScope initialize(Block block, int nreturns) {
NewScopeVisitor v = new NewScopeVisitor(nreturns);
block.accept( v );
this.nreturns = v.nreturns;
this.needsbinoptmp = v.needsbinoptmp;
this.usesvarargs = v.usesvarargs;
return this;
}
class NewScopeVisitor extends Visitor {
int nreturns = 0;
boolean needsbinoptmp = false;
boolean usesvarargs = false;
NewScopeVisitor(int nreturns) {
this.nreturns = nreturns;
}
public void visit(FuncBody body) {}
public void visit(Return s) {
int n = s.nreturns();
nreturns = (nreturns<0||n<0? -1: Math.max(n,nreturns));
super.visit(s);
}
public void visit(BinopExp exp) {
switch ( exp.op ) {
case Lua.OP_AND: case Lua.OP_OR:
needsbinoptmp = true;
break;
}
super.visit(exp);
}
public void visit(VarargsExp exp) {
usesvarargs = true;
}
}
}

View File

@@ -1,165 +0,0 @@
package org.luaj.vm2.lua2java;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.Arrays;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import javax.tools.ToolProvider;
import javax.tools.JavaCompiler.CompilationTask;
import org.luaj.vm2.LoadState;
import org.luaj.vm2.LuaFunction;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.LoadState.LuaCompiler;
import org.luaj.vm2.ast.Chunk;
import org.luaj.vm2.compiler.LuaC;
import org.luaj.vm2.parser.LuaParser;
public class Lua2Java implements LuaCompiler {
public static final Lua2Java instance = new Lua2Java();
public static final void install() {
LoadState.compiler = instance;
}
private Lua2Java() {
}
public LuaFunction load(InputStream stream, String filename, LuaValue env) throws IOException {
// get first byte
if ( ! stream.markSupported() )
stream = new BufferedInputStream( stream );
stream.mark( 1 );
int firstByte = stream.read();
stream.reset();
// we can only sompile sources
if ( firstByte != '\033' ) {
final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
if (compiler == null)
LuaValue.error("no java compiler");
// break into package and class
if ( filename.endsWith( ".lua") )
filename = filename.substring(0, filename.length()-4);
String s = filename.replace('\\', '/').replace('/','.').replaceAll("[^\\w]", "_");
int p = s.lastIndexOf('.');
final String packageName = p>=0? s.substring(0,p): null;
final String className = toClassname( s.substring(p+1) );
// open output file
final String pkgSubdir = (packageName!=null? packageName.replace('.','/'): "");
final String srcDirRoot = "lua2java/src";
final String binDirRoot = "lua2java/classes";
final String srcDirname = srcDirRoot+"/"+pkgSubdir;
final String binDirname = binDirRoot+"/"+pkgSubdir;
final String srcFilename = srcDirname + "/" + className + ".java";
// make directories
new File(srcDirname).mkdirs();
new File(binDirname).mkdirs();
// generate java source
try {
LuaParser parser = new LuaParser(stream,"ISO8859-1");
Chunk chunk = parser.Chunk();
File source = new File(srcFilename);
Writer writer = new OutputStreamWriter( new FileOutputStream(source) );
new JavaCodeGen(chunk,writer,packageName,className);
writer.close();
// set up output location
StandardJavaFileManager fm = compiler.getStandardFileManager( null, null, null);
fm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(new File[] { new File(binDirRoot) }));
// compile the file
CompilationTask task = compiler.getTask(null, fm, null, null, null, fm.getJavaFileObjects(source));
boolean success = task.call().booleanValue();
// instantiate, config and return
if (success) {
// create instance
ClassLoader cl = new ClassLoader() {
public Class findClass(String classname) throws ClassNotFoundException {
if ( classname.startsWith(className) ) {
File f = new File( binDirname+"/"+classname+".class");
long n = f.length();
byte[] b = new byte[(int) n];
try {
DataInputStream dis = new DataInputStream( new FileInputStream(f) );
dis.readFully(b);
} catch ( Exception e ) {
throw new RuntimeException("failed to read class bytes: "+e );
}
return defineClass(classname, b, 0, b.length);
}
return super.findClass(classname);
}
};
Class clazz = cl.loadClass(className);
Object instance = clazz.newInstance();
LuaFunction value = (LuaFunction) instance;
return value;
} else {
}
} catch ( Exception e ) {
LuaValue.error("compile task failed: "+e);
}
// report compilation error
LuaValue.error("compile task failed:");
return null;
}
// fall back to plain compiler
return LuaC.instance.load( stream, filename, env);
}
/** Convert lua filename to valid class name */
public static final String toClassname( String filename ) {
int n=filename.length();
int j=n;
if ( filename.endsWith(".lua") )
j -= 4;
for ( int k=0; k<j; k++ ) {
char c = filename.charAt(k);
if ( (!isClassnamePart(c)) || (c=='/') || (c=='\\') ) {
StringBuffer sb = new StringBuffer(j);
for ( int i=0; i<j; i++ ) {
c = filename.charAt(i);
sb.append(
(isClassnamePart(c))? c:
((c=='/') || (c=='\\'))? '.': '_' );
}
return sb.toString();
}
}
return n==j? filename: filename.substring(0,j);
}
private static final boolean isClassnamePart(char c) {
if ( (c>='a'&&c<='z') || (c>='A'&&c<='Z') || (c>='0'&&c<='9') )
return true;
switch ( c ) {
case '.':
case '$':
case '_':
return true;
default:
return false;
}
}
}