package tb; import drjava.util.Tree; import net.luaos.tb.common.Solution; import org.luaj.vm2.Globals; import org.luaj.vm2.LuaTable; import org.luaj.vm2.LuaValue; import org.luaj.vm2.compiler.LuaC; import org.luaj.vm2.lib.jse.JsePlatform; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; public class sol_lua extends Solution { String code; public sol_lua() {} public sol_lua(String code) { this.code = code; } public void fromTree(Tree tree) { code = tree.getString(0); } public Tree toTree() { return new Tree(this).add(code); } public String compute(String input) { return callLuaSolution(createLuaEnvironment(), code, input); } public static String callLuaSolution(LuaTable _G, String code, String input) { if (input != null) _G.set("input", input); // compile into a chunk, or load as a class InputStream is = new ByteArrayInputStream(code.getBytes()); LuaValue chunk = null; try { chunk = LuaC.instance.load(is, "script", _G); } catch (IOException e) { // not gonna happen anyway throw new RuntimeException(e); } // Check correct type (probably optional) chunk.checkclosure(); // The chunk can be called with arguments as desired. LuaValue result = chunk.call(); return luaResultToString(result); } public static String luaResultToString(LuaValue result) { return result.isnil() ? null : result.toString(); } /** If this is changed, make sure the environment is extendable (not a singleton!) * Or change the caller site to make a clone first. */ public static LuaTable createLuaEnvironment() { // create an environment to run in LuaTable _G = new LuaTable(); //JsePlatform.standardGlobals(); Globals standardGlobals = JsePlatform.standardGlobals(); _G.set("_G", _G); _G.set("print", standardGlobals.get("print")); _G.set("pairs", standardGlobals.get("pairs")); return _G; } }