Minor improvements to LuaConsole.cpp

This commit is contained in:
2021-01-23 20:12:21 -05:00
parent 37a05fe1ac
commit df3ec8ab99
3 changed files with 61 additions and 57 deletions

View File

@@ -15,10 +15,13 @@ void LuaConsole::clear() {
expression_ = ""; expression_ = "";
lines_ = 0; lines_ = 0;
syntax_ = ""; syntax_ = "";
state_=STATE_INCOMPLETE; action_ = DO_NOTHING;
} }
void LuaConsole::add(std::string line) { void LuaConsole::add(std::string line) {
if (action_ != DO_NOTHING) {
clear();
}
for (int i = 0; i < int(line.size()); i++) { for (int i = 0; i < int(line.size()); i++) {
if (line[i] == '\n') line[i] = ' '; if (line[i] == '\n') line[i] = ' ';
} }
@@ -34,10 +37,10 @@ void LuaConsole::add(std::string line) {
// Analyze slash-commands. // Analyze slash-commands.
if (expression_[0] == '/') { if (expression_[0] == '/') {
if (lines_ == 1) { if (lines_ == 1) {
state_ = STATE_SLASHCOMMAND; action_ = DO_SLASH;
syntax_ = ""; syntax_ = "";
} else { } else {
state_ = STATE_SYNTAX; action_ = DO_SYNTAX;
syntax_ = "slash command has more than one line"; syntax_ = "slash command has more than one line";
} }
return; return;
@@ -54,19 +57,22 @@ void LuaConsole::add(std::string line) {
const char *tp = msg + lmsg - (sizeof(eof) - 1); const char *tp = msg + lmsg - (sizeof(eof) - 1);
if (strstr(msg, eof) == tp) { if (strstr(msg, eof) == tp) {
syntax_ = ""; syntax_ = "";
state_ = STATE_INCOMPLETE; action_ = DO_NOTHING;
} else { } else {
syntax_ = msg; syntax_ = msg;
state_ = STATE_SYNTAX; action_ = DO_SYNTAX;
} }
} else { } else {
syntax_ = ""; syntax_ = "";
state_ = STATE_COMPLETE; action_ = DO_COMMAND;
} }
lua_settop(lua_state_, top); lua_settop(lua_state_, top);
} }
void LuaConsole::add_stdin() { void LuaConsole::add_stdin() {
if (action_ != DO_NOTHING) {
clear();
}
const int MAXINPUT = 1000; const int MAXINPUT = 1000;
char buf[MAXINPUT]; char buf[MAXINPUT];
fputs(expression_.empty() ? "> " : ">> ", stdout); fputs(expression_.empty() ? "> " : ">> ", stdout);

View File

@@ -2,8 +2,20 @@
// //
// LuaConsole: // LuaConsole:
// //
// Parses lines of text, and tells you if you have a valid // Used to parse lines of text that are being interactively typed
// lua expression. // in by a user.
//
// Whenever the user types in a line, you should add the line to
// the LuaConsole object. After adding a line, the console will
// recommend one of several actions:
//
// 1. DO_NOTHING: The input is not complete, so you need to wait.
// 2. DO_COMMAND: Execute a lua command.
// 3. DO_SYNTAX: Print a syntax error message.
// 4. DO_SLASH: Execute a slash-command that bypasses lua.
//
// Also: if the first character of the lua form is '=', then
// replace the '=' with 'return '.
// //
////////////////////////////////////////////////////// //////////////////////////////////////////////////////
@@ -16,14 +28,14 @@
class LuaConsole { class LuaConsole {
public: public:
enum { enum {
STATE_INCOMPLETE, // We need more input text. DO_NOTHING, // We need more input text.
STATE_COMPLETE, // We have a valid lua expression. DO_COMMAND, // We have a valid lua expression.
STATE_SLASHCOMMAND, // We have a slash-command. DO_SYNTAX, // We have a syntax error.
STATE_SYNTAX, // We have a syntax error. DO_SLASH, // We have a slash-command.
}; };
private: private:
lua_State *lua_state_; lua_State *lua_state_;
int state_; int action_;
int lines_; int lines_;
std::string expression_; std::string expression_;
std::string syntax_; std::string syntax_;
@@ -32,7 +44,7 @@ public:
LuaConsole(); LuaConsole();
~LuaConsole(); ~LuaConsole();
int state() const { return state_; } int action() const { return action_; }
int lines() const { return lines_; } int lines() const { return lines_; }
const std::string &expression() const { return expression_; } const std::string &expression() const { return expression_; }
const std::string &syntax() const { return syntax_; } const std::string &syntax() const { return syntax_; }

View File

@@ -42,18 +42,6 @@ static void l_message(const char *msg)
fflush(stderr); fflush(stderr);
} }
static int report(lua_State *L, int status)
{
if (status && !lua_isnil(L, -1))
{
const char *msg = lua_tostring(L, -1);
if (msg == NULL)
msg = "(error object is not a string)";
l_message(msg);
lua_pop(L, 1);
}
return status;
}
static void doexp(lua_State *L, const std::string &exp) static void doexp(lua_State *L, const std::string &exp)
{ {
@@ -63,11 +51,8 @@ static void doexp(lua_State *L, const std::string &exp)
signal(SIGINT, laction); signal(SIGINT, laction);
status = traceback_pcall(L, 0, LUA_MULTRET); status = traceback_pcall(L, 0, LUA_MULTRET);
signal(SIGINT, SIG_DFL); signal(SIGINT, SIG_DFL);
if (status != LUA_OK) { if (status == LUA_OK) {
report(L, status); if (lua_gettop(L) > 0) {
lua_gc(L, LUA_GCCOLLECT, 0);
}
if (status == LUA_OK && lua_gettop(L) > 0) {
lua_getglobal(L, "pprint"); lua_getglobal(L, "pprint");
if (lua_isnil(L, -1)) { if (lua_isnil(L, -1)) {
lua_pop(L, 1); lua_pop(L, 1);
@@ -80,6 +65,15 @@ static void doexp(lua_State *L, const std::string &exp)
lua_tostring(L, -1))); lua_tostring(L, -1)));
} }
} }
} else {
const char *msg = lua_tostring(L, -1);
if (msg == NULL) {
msg = "(error object is not a string)";
}
l_message(msg);
lua_pop(L, 1);
lua_gc(L, LUA_GCCOLLECT, 0);
}
} }
void TextGame::run() void TextGame::run()
@@ -87,21 +81,13 @@ void TextGame::run()
LuaConsole console; LuaConsole console;
while (true) { while (true) {
console.add_stdin(); console.add_stdin();
switch (console.state()) { int action = console.action();
case LuaConsole::STATE_INCOMPLETE: if (action == LuaConsole::DO_COMMAND) {
break;
case LuaConsole::STATE_COMPLETE:
doexp(viewer_.get_lua_state(), console.expression()); doexp(viewer_.get_lua_state(), console.expression());
console.clear(); } else if (action == LuaConsole::DO_SLASH) {
break;
case LuaConsole::STATE_SLASHCOMMAND:
std::cerr << "Slash commands not supported yet." << std::endl; std::cerr << "Slash commands not supported yet." << std::endl;
console.clear(); } else if (action == LuaConsole::DO_SYNTAX) {
break;
case LuaConsole::STATE_SYNTAX:
std::cerr << console.syntax() << std::endl; std::cerr << console.syntax() << std::endl;
console.clear();
break;
} }
} }
} }