package se.krka.kahlua.j2se; import se.krka.kahlua.Version; import se.krka.kahlua.converter.KahluaConverterManager; import se.krka.kahlua.converter.KahluaEnumConverter; import se.krka.kahlua.converter.KahluaNumberConverter; import se.krka.kahlua.converter.KahluaTableConverter; import se.krka.kahlua.integration.LuaCaller; import se.krka.kahlua.integration.LuaReturn; import se.krka.kahlua.j2se.interpreter.InteractiveShell; import se.krka.kahlua.luaj.compiler.LuaCompiler; import se.krka.kahlua.vm.KahluaTable; import se.krka.kahlua.vm.KahluaThread; import se.krka.kahlua.vm.LuaClosure; import se.krka.kahlua.vm.Platform; import java.io.*; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; public class Kahlua { private static final String STDIN_FILENAME = "stdin"; private final KahluaConverterManager converterManager = new KahluaConverterManager(); private final J2SEPlatform platform = new J2SEPlatform(); private final KahluaTable env = platform.newEnvironment(); private final LuaCaller caller = new LuaCaller(converterManager); public Kahlua() { } public void execute(String s, String... args) throws IOException { execute(new StringReader(s), STDIN_FILENAME, args); } public void execute(File file, String... args) throws IOException { execute(new FileReader(file), file.getName(), args); } public void execute(Reader reader, String name, String... args) throws IOException { LuaClosure closure = LuaCompiler.loadis(reader, name, env); LuaReturn result = caller.protectedCall(newThread(), closure, args); if (!result.isSuccess()) { System.err.println(result.getErrorString()); System.err.println(result.getLuaStackTrace()); throw result.getJavaException(); } } public static void main(String[] args) throws IOException { final Kahlua kahlua = new Kahlua(); KahluaNumberConverter.install(kahlua.getConverterManager()); KahluaEnumConverter.install(kahlua.getConverterManager()); new KahluaTableConverter(kahlua.getPlatform()).install(kahlua.getConverterManager()); boolean interactive = false; boolean printVersion = false; List<ExceptionRunnable<IOException>> jobs = new ArrayList<ExceptionRunnable<IOException>>(); List<String> argsList = Arrays.asList(args); final Iterator<String> iterator = argsList.iterator(); while (iterator.hasNext()) { final String arg = iterator.next(); if (arg.startsWith("-")) { if (arg.equals("-e")) { if (!iterator.hasNext()) { failWithUsage(); } final String stat = iterator.next(); jobs.add(new ExceptionRunnable() { @Override public void run() throws IOException { kahlua.execute(stat, STDIN_FILENAME); } }); } else if (arg.equals("-v")) { printVersion = true; } else if (arg.equals("-i")) { interactive = true; } else if (arg.equals("--")) { if (iterator.hasNext()) { String fileName = iterator.next(); addFile(kahlua, jobs, iterator, fileName); } else { interactive = true; } } else if (arg.equals("-")) { addStat(kahlua, jobs, iterator); } } else { addFile(kahlua, jobs, iterator, arg); } } if (jobs.isEmpty() && !interactive && !printVersion) { failWithUsage(); } if (printVersion) { System.out.println(Version.VERSION); } for (ExceptionRunnable<IOException> job : jobs) { job.run(); } if (interactive) { new InteractiveShell(kahlua); } } private static void addStat(final Kahlua kahlua, List<ExceptionRunnable<IOException>> jobs, Iterator<String> iterator) { addJob(kahlua, jobs, iterator, STDIN_FILENAME, new InputStreamReader(System.in)); } private static void addJob(final Kahlua kahlua, List<ExceptionRunnable<IOException>> jobs, Iterator<String> iterator, final String filename, final InputStreamReader reader) { final String[] luaArgs = toArray(iterator); jobs.add(new ExceptionRunnable<IOException>() { @Override public void run() throws IOException { kahlua.execute(reader, filename, luaArgs); } }); } private static void addFile(final Kahlua kahlua, List<ExceptionRunnable<IOException>> jobs, Iterator<String> iterator, final String arg) throws FileNotFoundException { addJob(kahlua, jobs, iterator, arg, new FileReader(arg)); } private static String[] toArray(Iterator<String> iterator) { ArrayList<String> list = new ArrayList<String>(); while (iterator.hasNext()) { list.add(iterator.next()); } String[] res = new String[list.size()]; list.toArray(res); return res; } public static void failWithUsage() { System.out.println("usage: kahlua [options] [script [args]]."); System.out.println("Available options are:"); System.out.println(" -e stat execute string 'stat'"); System.out.println(" -i enter interactive mode after executing 'script'"); System.out.println(" -v show version information"); System.out.println(" -- stop handling options"); System.out.println(" - execute stdin and stop handling options"); System.exit(0); } public KahluaConverterManager getConverterManager() { return converterManager; } public Platform getPlatform() { return platform; } public KahluaTable getEnvironment() { return env; } public LuaCaller getCaller() { return caller; } public KahluaThread newThread() { return new KahluaThread(platform, env); } private static interface ExceptionRunnable<T extends Throwable> { void run() throws T; } }