#include "AppHdr.h"
#include "luaterp.h"
#include "cio.h"
#include "clua.h"
#include "dlua.h"
static int _incomplete(lua_State *ls, int status)
{
if (status == LUA_ERRSYNTAX)
{
size_t lmsg;
const char *msg = lua_tolstring(ls, -1, &lmsg);
const char *tp = msg + lmsg - (sizeof(LUA_QL("<eof>")) - 1);
if (strstr(msg, LUA_QL("<eof>")) == tp)
{
lua_pop(ls, 1);
return 1;
}
}
return 0;
}
static int _pushline(lua_State *ls, int firstline)
{
char buffer[80];
char *b = buffer;
size_t l;
mpr(firstline ? "> " : ". ", MSGCH_PROMPT);
if (cancelable_get_line_autohist(buffer, sizeof(buffer)))
return (0);
l = strlen(b);
if (l > 0 && b[l-1] == '\n') b[l-1] = '\0';
if (firstline && l > 0 && b[0] == '=') lua_pushfstring(ls, "return %s", b+1); else
lua_pushstring(ls, b);
return (1);
}
static int _loadline(lua_State *ls)
{
int status;
lua_settop(ls, 0);
if (!_pushline(ls, 1))
return -1;
for (;;)
{
status = luaL_loadbuffer(ls, lua_tostring(ls, 1),
lua_strlen(ls, 1), "=terp");
if (!_incomplete(ls, status))
break;
if (!_pushline(ls, 0))
return -1;
lua_pushliteral(ls, "\n"); lua_insert(ls, -2); lua_concat(ls, 3); }
lua_remove(ls, 1); return status;
}
static int _docall(lua_State *ls)
{
int status;
int base = lua_gettop(ls);
status = lua_pcall(ls, 0, LUA_MULTRET, base);
if (status != 0)
lua_gc(ls, LUA_GCCOLLECT, 0);
return (status);
}
static int _report(lua_State *ls, int status)
{
if (status && !lua_isnil(ls, -1))
{
const char *msg = lua_tostring(ls, -1);
if (msg == NULL)
msg = "(error object is not a string)";
mprf(MSGCH_ERROR, msg);
lua_pop(ls, 1);
}
return status;
}
void run_clua_interpreter(lua_State *ls)
{
int status;
while ((status = _loadline(ls)) != -1)
{
if (status == 0)
status = _docall(ls);
_report(ls, status);
if (status == 0 && lua_gettop(ls) > 0)
{
lua_getglobal(ls, "__echo");
lua_insert(ls, 1);
if (lua_pcall(ls, lua_gettop(ls) - 1, 0, 0) != 0)
{
mprf(MSGCH_ERROR, "error calling __echo (%s)",
lua_tostring(ls, -1));
}
}
}
lua_settop(ls, 0); }
void debug_terp_dlua()
{
run_clua_interpreter(dlua);
}