// BlockyFroggy
// Copyright © 2017 John Ryland.
// All rights reserved.
// Compile with following to build a command line lua interpreter:
// g++ Lua.cpp -o lua -DTEST | -DPROG
// With my C++ bindings, LuaVM::CallLua(...) requires C++11
// g++ -std=c++11 Lua.cpp -o lua -DTEST | -DPROG
#include "Lua.h"
#include "LuaBindings.h"
#ifndef STANDALONE
#include <string>
#include "ResourceLoader.h"
#include "Log.h"
#endif
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wcomma"
// Do a unity build of all the lua source
#include "lua-5.3.2/src/lapi.c"
#include "lua-5.3.2/src/lauxlib.c"
#include "lua-5.3.2/src/lbaselib.c"
#include "lua-5.3.2/src/lbitlib.c"
#include "lua-5.3.2/src/lcode.c"
#include "lua-5.3.2/src/lcorolib.c"
#include "lua-5.3.2/src/lctype.c"
#include "lua-5.3.2/src/ldblib.c"
#include "lua-5.3.2/src/ldebug.c"
#include "lua-5.3.2/src/ldo.c"
#include "lua-5.3.2/src/ldump.c"
#include "lua-5.3.2/src/lfunc.c"
#include "lua-5.3.2/src/lgc.c"
#include "lua-5.3.2/src/linit.c"
#include "lua-5.3.2/src/liolib.c"
#include "lua-5.3.2/src/llex.c"
#include "lua-5.3.2/src/lmathlib.c"
#include "lua-5.3.2/src/lmem.c"
#include "lua-5.3.2/src/loadlib.c"
#include "lua-5.3.2/src/lobject.c"
#include "lua-5.3.2/src/lopcodes.c"
#include "lua-5.3.2/src/loslib.c"
#include "lua-5.3.2/src/lparser.c"
#include "lua-5.3.2/src/lstate.c"
#include "lua-5.3.2/src/lstring.c"
#include "lua-5.3.2/src/lstrlib.c"
#include "lua-5.3.2/src/ltable.c"
#include "lua-5.3.2/src/ltablib.c"
#include "lua-5.3.2/src/ltm.c"
#include "lua-5.3.2/src/lundump.c"
#include "lua-5.3.2/src/lutf8lib.c"
#include "lua-5.3.2/src/lvm.c"
#include "lua-5.3.2/src/lzio.c"
#pragma clang diagnostic pop
DECLARE_LOG_CONTEXT(LUA)
LuaVM::LuaVM() {
L = luaL_newstate();
luaL_openlibs(L);
lua_newtable(L);
registerLuaBindings(L);
}
LuaVM::~LuaVM() {
lua_close(L);
}
void LuaVM::loadFile(const char* file) {
#ifndef STANDALONE
std::string fileStr = file; // Dangerous if we capture the raw pointer, so encapsulate the const char* in something safer
::loadFileAsync(file, true, [this, fileStr](Resource* res) {
if (!res->isLoaded() || luaL_loadbuffer(L, (const char*)res->data.data(), res->data.size() - 1, fileStr.c_str()) != 0)
Log(LL_Error, "Error loading LUA file %s", fileStr.c_str());
else if (lua_pcall(L, 0, LUA_MULTRET, 0) != 0)
Log(LL_Error, "Error after loading LUA file %s", fileStr.c_str());
});
#else
if (luaL_loadfile(L, file) != 0) // Alternative way where Lua directly reads the file instead
Log(LL_Error, "Error loading LUA file %s", file);
else if (lua_pcall(L, 0, LUA_MULTRET, 0) != 0)
Log(LL_Error, "Error after loading LUA file %s", file);
#endif
}
void LuaVM::push(void) { lua_pushnil(L); }
void LuaVM::push(bool b) { lua_pushboolean(L, b); }
void LuaVM::push(const char *str) { lua_pushstring(L, str); }
void LuaVM::push(std::vector<char> buf) { lua_pushlstring(L, buf.data(), buf.size()); }
void LuaVM::push(void *data) { lua_pushlightuserdata(L, data); }
void LuaVM::push(double value) { lua_pushnumber(L, value); }
void LuaVM::push(int value) { lua_pushinteger(L, value); }
void LuaVM::push(lua_CFunction fn) { lua_pushcclosure(L, fn, 0); }
void LuaVM::pushArgs(int &) { }
#ifdef PROG
// Builds the lua command line interpreter
#include "lua-5.3.2/src/lua.c"
#endif
#ifdef TEST
// Builds small test program
int main(int argc, char *argv[])
{
LuaVM lua;
lua.loadFile("test.lua");
lua.callLua("helloWorld");
lua.callLua("args_test", 1, 2.0, "3");
//lua.callLua("args_test", "ids>i", 1, 2.0, "3");
lua.callLua("args_test", 1, 2.0, "3");
return 0;
}
#endif