From df3ec8ab997b2cede4987391bff5ff808e63a2fb Mon Sep 17 00:00:00 2001 From: Josh Yelon Date: Sat, 23 Jan 2021 20:12:21 -0500 Subject: [PATCH] Minor improvements to LuaConsole.cpp --- luprex/cpp/luaconsole.cpp | 22 +++++++++----- luprex/cpp/luaconsole.hpp | 32 ++++++++++++++------ luprex/cpp/textgame.cpp | 64 +++++++++++++++------------------------ 3 files changed, 61 insertions(+), 57 deletions(-) diff --git a/luprex/cpp/luaconsole.cpp b/luprex/cpp/luaconsole.cpp index f48655e9..1af07375 100644 --- a/luprex/cpp/luaconsole.cpp +++ b/luprex/cpp/luaconsole.cpp @@ -12,13 +12,16 @@ LuaConsole::~LuaConsole() { } void LuaConsole::clear() { - expression_=""; + expression_ = ""; lines_ = 0; - syntax_=""; - state_=STATE_INCOMPLETE; + syntax_ = ""; + action_ = DO_NOTHING; } void LuaConsole::add(std::string line) { + if (action_ != DO_NOTHING) { + clear(); + } for (int i = 0; i < int(line.size()); i++) { if (line[i] == '\n') line[i] = ' '; } @@ -34,10 +37,10 @@ void LuaConsole::add(std::string line) { // Analyze slash-commands. if (expression_[0] == '/') { if (lines_ == 1) { - state_ = STATE_SLASHCOMMAND; + action_ = DO_SLASH; syntax_ = ""; } else { - state_ = STATE_SYNTAX; + action_ = DO_SYNTAX; syntax_ = "slash command has more than one line"; } return; @@ -54,19 +57,22 @@ void LuaConsole::add(std::string line) { const char *tp = msg + lmsg - (sizeof(eof) - 1); if (strstr(msg, eof) == tp) { syntax_ = ""; - state_ = STATE_INCOMPLETE; + action_ = DO_NOTHING; } else { syntax_ = msg; - state_ = STATE_SYNTAX; + action_ = DO_SYNTAX; } } else { syntax_ = ""; - state_ = STATE_COMPLETE; + action_ = DO_COMMAND; } lua_settop(lua_state_, top); } void LuaConsole::add_stdin() { + if (action_ != DO_NOTHING) { + clear(); + } const int MAXINPUT = 1000; char buf[MAXINPUT]; fputs(expression_.empty() ? "> " : ">> ", stdout); diff --git a/luprex/cpp/luaconsole.hpp b/luprex/cpp/luaconsole.hpp index 9b6fa208..1e5fdcaa 100644 --- a/luprex/cpp/luaconsole.hpp +++ b/luprex/cpp/luaconsole.hpp @@ -2,9 +2,21 @@ // // LuaConsole: // -// Parses lines of text, and tells you if you have a valid -// lua expression. -// +// Used to parse lines of text that are being interactively typed +// 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 '. +// ////////////////////////////////////////////////////// #ifndef LUACONSOLE_HPP @@ -16,14 +28,14 @@ class LuaConsole { public: enum { - STATE_INCOMPLETE, // We need more input text. - STATE_COMPLETE, // We have a valid lua expression. - STATE_SLASHCOMMAND, // We have a slash-command. - STATE_SYNTAX, // We have a syntax error. + DO_NOTHING, // We need more input text. + DO_COMMAND, // We have a valid lua expression. + DO_SYNTAX, // We have a syntax error. + DO_SLASH, // We have a slash-command. }; private: lua_State *lua_state_; - int state_; + int action_; int lines_; std::string expression_; std::string syntax_; @@ -32,7 +44,7 @@ public: LuaConsole(); ~LuaConsole(); - int state() const { return state_; } + int action() const { return action_; } int lines() const { return lines_; } const std::string &expression() const { return expression_; } const std::string &syntax() const { return syntax_; } @@ -42,4 +54,4 @@ public: void clear(); }; -#endif //LUACONSOLE_HPP +#endif // LUACONSOLE_HPP diff --git a/luprex/cpp/textgame.cpp b/luprex/cpp/textgame.cpp index d0f82cda..3471a219 100644 --- a/luprex/cpp/textgame.cpp +++ b/luprex/cpp/textgame.cpp @@ -42,18 +42,6 @@ static void l_message(const char *msg) 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) { @@ -63,23 +51,29 @@ static void doexp(lua_State *L, const std::string &exp) signal(SIGINT, laction); status = traceback_pcall(L, 0, LUA_MULTRET); signal(SIGINT, SIG_DFL); - if (status != LUA_OK) { - report(L, status); + if (status == LUA_OK) { + if (lua_gettop(L) > 0) { + lua_getglobal(L, "pprint"); + if (lua_isnil(L, -1)) { + lua_pop(L, 1); + lua_getglobal(L, "print"); + } + lua_insert(L, 1); + if (lua_pcall(L, lua_gettop(L) - 1, 0, 0) != 0) { + l_message( + lua_pushfstring(L, "error calling 'print' (%s)", + 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); } - if (status == LUA_OK && lua_gettop(L) > 0) { - lua_getglobal(L, "pprint"); - if (lua_isnil(L, -1)) { - lua_pop(L, 1); - lua_getglobal(L, "print"); - } - lua_insert(L, 1); - if (lua_pcall(L, lua_gettop(L) - 1, 0, 0) != 0) { - l_message( - lua_pushfstring(L, "error calling 'print' (%s)", - lua_tostring(L, -1))); - } - } } void TextGame::run() @@ -87,21 +81,13 @@ void TextGame::run() LuaConsole console; while (true) { console.add_stdin(); - switch (console.state()) { - case LuaConsole::STATE_INCOMPLETE: - break; - case LuaConsole::STATE_COMPLETE: + int action = console.action(); + if (action == LuaConsole::DO_COMMAND) { doexp(viewer_.get_lua_state(), console.expression()); - console.clear(); - break; - case LuaConsole::STATE_SLASHCOMMAND: + } else if (action == LuaConsole::DO_SLASH) { std::cerr << "Slash commands not supported yet." << std::endl; - console.clear(); - break; - case LuaConsole::STATE_SYNTAX: + } else if (action == LuaConsole::DO_SYNTAX) { std::cerr << console.syntax() << std::endl; - console.clear(); - break; } } }