forked from redo/BlockLua
296 lines
9.6 KiB
C++
296 lines
9.6 KiB
C++
// run ../compile
|
|
|
|
// TS -> Lua API
|
|
|
|
// Call a TS function from Lua, push the result to Lua stack
|
|
#include "BlFuncs.hpp"
|
|
#include "BlHooks.hpp"
|
|
#include "lauxlib.h"
|
|
#include "lua.h"
|
|
#include "luainterp.hpp"
|
|
|
|
int bll_TsCall(lua_State* L, const char* oname, const char* fname, int argc, int ofs) {
|
|
ADDR obj = (ADDR)NULL;
|
|
if (oname) {
|
|
obj = BlObject(oname);
|
|
if (!obj) {
|
|
return luaL_error(L, "Lua->TS call: Object not found");
|
|
}
|
|
}
|
|
|
|
if (argc > BLL_ARG_COUNT) {
|
|
return luaL_error(L, "Lua->TS call: Too many arguments (Max is 19)");
|
|
}
|
|
|
|
char* argv[BLL_ARG_COUNT];
|
|
for (int i = 0; i < argc; i++) {
|
|
char* argbuf = bll_arg_buffer[i];
|
|
argv[i] = argbuf;
|
|
bll_toarg(L, argbuf, i + ofs + 1, true);
|
|
}
|
|
|
|
// /:^| /
|
|
const char* res;
|
|
if (obj) {
|
|
switch (argc) {
|
|
case 0:
|
|
res = BlCallObj(obj, fname);
|
|
break; // no idea why this happens sometimes, it shouldnt be possible
|
|
case 1:
|
|
res = BlCallObj(obj, fname);
|
|
break;
|
|
case 2:
|
|
res = BlCallObj(obj, fname, argv[0]);
|
|
break;
|
|
case 3:
|
|
res = BlCallObj(obj, fname, argv[0], argv[1]);
|
|
break;
|
|
case 4:
|
|
res = BlCallObj(obj, fname, argv[0], argv[1], argv[2]);
|
|
break;
|
|
case 5:
|
|
res = BlCallObj(obj, fname, argv[0], argv[1], argv[2], argv[3]);
|
|
break;
|
|
case 6:
|
|
res = BlCallObj(obj, fname, argv[0], argv[1], argv[2], argv[3], argv[4]);
|
|
break;
|
|
case 7:
|
|
res = BlCallObj(obj, fname, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]);
|
|
break;
|
|
case 8:
|
|
res = BlCallObj(obj, fname, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6]);
|
|
break;
|
|
case 9:
|
|
res = BlCallObj(obj, fname, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7]);
|
|
break;
|
|
case 10:
|
|
res = BlCallObj(obj, fname, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8]);
|
|
break;
|
|
case 11:
|
|
res = BlCallObj(
|
|
obj, fname, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9]);
|
|
break;
|
|
case 12:
|
|
res = BlCallObj(
|
|
obj, fname, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9],
|
|
argv[10]);
|
|
break;
|
|
case 13:
|
|
res = BlCallObj(
|
|
obj, fname, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9],
|
|
argv[10], argv[11]);
|
|
break;
|
|
case 14:
|
|
res = BlCallObj(
|
|
obj, fname, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9],
|
|
argv[10], argv[11], argv[12]);
|
|
break;
|
|
case 15:
|
|
res = BlCallObj(
|
|
obj, fname, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9],
|
|
argv[10], argv[11], argv[12], argv[13]);
|
|
break;
|
|
case 16:
|
|
res = BlCallObj(
|
|
obj, fname, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9],
|
|
argv[10], argv[11], argv[12], argv[13], argv[14]);
|
|
break;
|
|
case 17:
|
|
res = BlCallObj(
|
|
obj, fname, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9],
|
|
argv[10], argv[11], argv[12], argv[13], argv[14], argv[15]);
|
|
break;
|
|
case 18:
|
|
res = BlCallObj(
|
|
obj, fname, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9],
|
|
argv[10], argv[11], argv[12], argv[13], argv[14], argv[15], argv[16]);
|
|
break;
|
|
case 19:
|
|
res = BlCallObj(
|
|
obj, fname, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9],
|
|
argv[10], argv[11], argv[12], argv[13], argv[14], argv[15], argv[16], argv[17]);
|
|
break;
|
|
case 20:
|
|
res = BlCallObj(
|
|
obj, fname, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9],
|
|
argv[10], argv[11], argv[12], argv[13], argv[14], argv[15], argv[16], argv[17], argv[18]);
|
|
break;
|
|
default:
|
|
res = "";
|
|
luaL_error(L, "Lua->TS object call: Too many arguments (Max is 19)");
|
|
}
|
|
} else {
|
|
switch (argc) {
|
|
case 0:
|
|
res = BlCall(fname);
|
|
break;
|
|
case 1:
|
|
res = BlCall(fname, argv[0]);
|
|
break;
|
|
case 2:
|
|
res = BlCall(fname, argv[0], argv[1]);
|
|
break;
|
|
case 3:
|
|
res = BlCall(fname, argv[0], argv[1], argv[2]);
|
|
break;
|
|
case 4:
|
|
res = BlCall(fname, argv[0], argv[1], argv[2], argv[3]);
|
|
break;
|
|
case 5:
|
|
res = BlCall(fname, argv[0], argv[1], argv[2], argv[3], argv[4]);
|
|
break;
|
|
case 6:
|
|
res = BlCall(fname, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]);
|
|
break;
|
|
case 7:
|
|
res = BlCall(fname, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6]);
|
|
break;
|
|
case 8:
|
|
res = BlCall(fname, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7]);
|
|
break;
|
|
case 9:
|
|
res = BlCall(fname, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8]);
|
|
break;
|
|
case 10:
|
|
res = BlCall(fname, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9]);
|
|
break;
|
|
case 11:
|
|
res = BlCall(
|
|
fname, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10]);
|
|
break;
|
|
case 12:
|
|
res = BlCall(
|
|
fname, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10],
|
|
argv[11]);
|
|
break;
|
|
case 13:
|
|
res = BlCall(
|
|
fname, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10],
|
|
argv[11], argv[12]);
|
|
break;
|
|
case 14:
|
|
res = BlCall(
|
|
fname, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10],
|
|
argv[11], argv[12], argv[13]);
|
|
break;
|
|
case 15:
|
|
res = BlCall(
|
|
fname, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10],
|
|
argv[11], argv[12], argv[13], argv[14]);
|
|
break;
|
|
case 16:
|
|
res = BlCall(
|
|
fname, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10],
|
|
argv[11], argv[12], argv[13], argv[14], argv[15]);
|
|
break;
|
|
case 17:
|
|
res = BlCall(
|
|
fname, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10],
|
|
argv[11], argv[12], argv[13], argv[14], argv[15], argv[16]);
|
|
break;
|
|
case 18:
|
|
res = BlCall(
|
|
fname, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10],
|
|
argv[11], argv[12], argv[13], argv[14], argv[15], argv[16], argv[17]);
|
|
break;
|
|
case 19:
|
|
res = BlCall(
|
|
fname, argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10],
|
|
argv[11], argv[12], argv[13], argv[14], argv[15], argv[16], argv[17], argv[18]);
|
|
break;
|
|
default:
|
|
res = "";
|
|
luaL_error(L, "Lua->TS call: Too many arguments (Max is 19)");
|
|
}
|
|
}
|
|
|
|
lua_pushstring(L, res);
|
|
|
|
return 1;
|
|
}
|
|
|
|
// Lua lib function: ts.call
|
|
int bll_lua_tscall(lua_State* L) {
|
|
int argc = lua_gettop(L) - 1; // number of arguments after function name
|
|
if (argc < 0)
|
|
return luaL_error(L, "_bllua_ts.call: Must provide a function name");
|
|
|
|
const char* fname = luaL_checkstring(L, 1);
|
|
|
|
return bll_TsCall(L, NULL, fname, argc, 1);
|
|
}
|
|
|
|
// Lua lib function: ts.callobj
|
|
int bll_lua_tscallobj(lua_State* L) {
|
|
int argc = lua_gettop(L) - 2; // number of arguments after function name and object?
|
|
if (argc < 0)
|
|
return luaL_error(L, "_bllua_ts.callobj: Must provide an object and function name");
|
|
|
|
const char* oname = luaL_checkstring(L, 1);
|
|
const char* fname = luaL_checkstring(L, 2);
|
|
|
|
return bll_TsCall(L, oname, fname, argc, 2);
|
|
}
|
|
|
|
// Lua lib function: ts.getvar
|
|
int bll_lua_tsgetvar(lua_State* L) {
|
|
const char* vname = luaL_checkstring(L, 1);
|
|
|
|
const char* var = BlGetVar(vname);
|
|
lua_pushstring(L, var);
|
|
return 1;
|
|
}
|
|
|
|
// Lua lib function: ts.getfield
|
|
int bll_lua_tsgetfield(lua_State* L) {
|
|
const char* oname = luaL_checkstring(L, 1);
|
|
const char* vname = luaL_checkstring(L, 2);
|
|
ADDR obj = BlObject(oname);
|
|
if (!obj) {
|
|
return luaL_error(L, "_bllua_ts.getfield: Object not found");
|
|
}
|
|
|
|
const char* val = BlGetField(obj, vname, NULL);
|
|
lua_pushstring(L, val);
|
|
return 1;
|
|
}
|
|
|
|
// Lua lib function: ts.setfield
|
|
int bll_lua_tssetfield(lua_State* L) {
|
|
const char* oname = luaL_checkstring(L, 1);
|
|
const char* vname = luaL_checkstring(L, 2);
|
|
const char* val = luaL_checkstring(L, 3);
|
|
ADDR obj = BlObject(oname);
|
|
if (!obj) {
|
|
return luaL_error(L, "_bllua_ts.setfield: Object not found");
|
|
}
|
|
|
|
BlSetField(obj, vname, NULL, val);
|
|
return 0;
|
|
}
|
|
|
|
// Lua lib function: ts.eval
|
|
int bll_lua_tseval(lua_State* L) {
|
|
const char* str = luaL_checkstring(L, 1);
|
|
const char* res = BlEval(str);
|
|
lua_pushstring(L, res);
|
|
return 1;
|
|
}
|
|
|
|
// Lua lib function: ts.echo
|
|
// Print to BL console - used in Lua print implementation
|
|
int bll_lua_tsecho(lua_State* L) {
|
|
const char* str = luaL_checkstring(L, 1);
|
|
BlPrintf("%s", str);
|
|
return 0;
|
|
}
|
|
|
|
const luaL_Reg bll_lua_reg[] = {
|
|
{"call", bll_lua_tscall}, {"callobj", bll_lua_tscallobj},
|
|
{"getvar", bll_lua_tsgetvar}, {"getfield", bll_lua_tsgetfield},
|
|
{"setfield", bll_lua_tssetfield}, {"eval", bll_lua_tseval},
|
|
{"echo", bll_lua_tsecho}, {NULL, NULL},
|
|
};
|
|
|
|
void llibbl_init(lua_State* L) { luaL_register(L, "_bllua_ts", bll_lua_reg); }
|