Skip to content

Instantly share code, notes, and snippets.

@bagobor
Created December 5, 2015 19:00
Show Gist options
  • Save bagobor/361b1b9a226974984072 to your computer and use it in GitHub Desktop.
Save bagobor/361b1b9a226974984072 to your computer and use it in GitHub Desktop.
lua chunk
#pragma once
#include <string>
#include <lua/lua.hpp>
#include <luabind/luabind.hpp>
#include <luabind/detail/policy.hpp>
#include <luabind/out_value_policy.hpp>
#include <luabind/operator.hpp>
class lua_chunk {
public:
lua_chunk(lua_State* L, const std::string& script) {
lua_chunk::L = L;
compile(script);
}
lua_chunk(lua_State* L) {
lua_chunk::L = L;
}
bool compile(const std::string& script) {
is_compiled = false;
//luaL_loadstring(L, script.c_str()) || lua_pcall(L, 0, LUA_MULTRET, 0))
const int res = luaL_loadstring(L, script.c_str());
if (res != LUA_OK) {
const char *msg = lua_tostring(L, -1);
errors = msg ? msg : "unknown error";
//switch (res)
//{
//case LUA_ERRSYNTAX:
// break;
//case LUA_ERRFILE:
// break;
//default :
// break;
//}
return false;
}
is_compiled = true;
using namespace luabind;
chunk = object(from_stack(L, -1));
//lua_pop(L, 1);
for (int index = 1;;++index) { // find _ENV upvalue, then use it index to changing chunk ENV for reEVAL.
auto upv = luabind::getupvalue(chunk, index);
auto name = std::get<0>(upv);
static std::string _ENV_NAME = "_ENV";
if (!name) break;
if (name == _ENV_NAME) {
ENV_index = index;
break;
}
// std::cout << name << std::endl;
}
//is_compiled = true;
return is_compiled;
}
const std::string& get_errors() const { return errors; }
luabind::object run(luabind::object env) {
using namespace luabind;
if (!is_compiled) return object();
if (env) {
setupvalue(chunk, 1, env);
}
else {
object _G = rawget(globals(L), "_G");
setupvalue(chunk, 1, _G);
}
luabind::function<luabind::object> chunk_func = chunk;
return chunk_func();
}
luabind::object new_instance() {
using namespace luabind;
object oldEnv = rawget(globals(L), "_G");
object newEnv = newtable(L);
object newEnvMeta = newtable(L);
settable(newEnvMeta, "__index", oldEnv);
setmetatable(newEnv, newEnvMeta);
run(newEnv);
return newEnv;
}
std::string errors;
bool is_compiled = false;
//luabind::function<luabind::object> chunk;
private:
luabind::object chunk;
int ENV_index = -1;
lua_State* L;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment