package se.krka.kahluax.compiler;
import se.krka.kahlua.vm.LuaClosure;
import se.krka.kahlua.vm.LuaPrototype;
import se.krka.kahlua.vm.LuaTable;
import java.io.*;
public class LuaCompiler {
public LuaClosure compile(InputStream input, LuaTable env, String name) throws LuaCompileException, IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(input));
String line = "";
StringBuilder sb = new StringBuilder();
while ((line = br.readLine()) != null) {
sb.append(line).append("\n");
}
return compile(sb.toString(), env, name);
}
public LuaClosure compile(String input, LuaTable env, String name) throws LuaCompileException, IOException {
byte data[] = nativeCompile(input, name);
verifyData(data);
ByteArrayInputStream bais = new ByteArrayInputStream(data);
return LuaPrototype.loadByteCode(bais, env);
}
private void verifyData(byte[] data) throws LuaCompileException {
if (data.length == 0) {
throw new LuaCompileException("Compilation Error: No data received");
}
if (data[0] != 27) {
String s;
try {
s = new String(data, "UTF-8");
} catch (java.io.UnsupportedEncodingException e) {
s = new String(data);
}
throw new LuaCompileException("Compilation Error: " + s);
}
}
private static String determineOS() {
String osName = System.getProperty("os.name").toLowerCase();
if (osName != null) {
if (osName.startsWith("mac os x")) {
return "os_macosx";
}
if (osName.startsWith("windows")) {
return "os_windows";
}
if (osName.startsWith("linux")) {
return "os_linux";
}
if (osName.startsWith("sun")) {
return "os_sun";
}
return "os_" + osName;
}
return "os_unknown";
}
private static String determineArch() {
String osArch = System.getProperty("os.arch").toLowerCase();
if (osArch != null) {
if (osArch.equals("i386")) {
return "arch_i386";
}
if (osArch.equals("x86")) {
return "arch_i386";
}
if (osArch.startsWith("amd64") || osArch.startsWith("x86_64")) {
return "arch_x86_64";
}
if (osArch.equals("ppc")) {
return "arch_ppc";
}
if (osArch.startsWith("ppc")) {
return "arch_ppc_64";
}
if (osArch.startsWith("sparc")) {
return "arch_sparc";
}
return "arch_" + osArch;
}
return "arch_unknown";
}
static {
String os = determineOS();
String arch = determineArch();
String type = os + "_" + arch;
if (os.equals("os_linux")) {
if (arch.equals("arch_i386")) {
type = "linux32";
} else if (arch.equals("arch_x86_64")) {
type = "linux64";
}
} else if (os.equals("os_windows")) {
type = "win32";
} else if (os.equals("os_macosx")) {
// implement later
}
System.loadLibrary("JavaLuac_" + type);
}
/**
* Performs the actual compilation using a JNI call to luac
* @param src the source code to compile
* @param name the name of the source code
* @return the ready to run lua byte code
* @throws LuaCompileException if compilation fails for some reason (e.g. syntax error)
*/
public native byte[] nativeCompile(String src, String name) throws LuaCompileException;
}