#include #include "luaconsole.hpp" #include "util.hpp" #include static bool is_single_letter(const std::string &s) { return ((s.size() == 1) && (s[0] >= 'a') && (s[0] <= 'z')); } LuaConsole::LuaConsole() { lua_state_ = luaL_newstate(); clear_raw_input(); } LuaConsole::~LuaConsole() { lua_close(lua_state_); } static LuaConsole::StringVec split_words(const std::string &raw) { LuaConsole::StringVec result; std::string acc; for (char c : raw) { if ((c == ' ')||(c == '\n')||(c == '\r')) { if (!acc.empty()) { result.push_back(acc); acc = ""; } } else { acc += c; } } if (!acc.empty()) { result.push_back(acc); } return result; } LuaConsole::StringVec LuaConsole::get_command() { StringVec result = words_; words_.clear(); return result; } void LuaConsole::clear_raw_input() { raw_input_ = ""; lines_ = 0; prompt_ = "> "; } void LuaConsole::add(std::string line) { for (int i = 0; i < int(line.size()); i++) { if (line[i] == '\n') line[i] = ' '; } raw_input_ += line; raw_input_ += '\n'; lines_ += 1; prompt_ = ">> "; // Try to interpret it as a special command. if (lines_ == 1) { StringVec words = split_words(raw_input_); if (words.size() >= 1) { if (is_single_letter(words[0]) || (util::validinteger(words[0]))) { words_ = words; clear_raw_input(); return; } } } // Translate lua expression with leading '=' to 'return' std::string partial; if (raw_input_[0] == '=') { partial = std::string("return ") + raw_input_.substr(1); } else { partial = raw_input_; } // Try to parse the lua expression int top = lua_gettop(lua_state_); int status = luaL_loadbuffer(lua_state_, partial.c_str(), partial.size(), "=stdin"); if (status == LUA_ERRSYNTAX) { const char *eof = ""; int leof = strlen(eof); size_t lmsg; const char *msg = lua_tolstring(lua_state_, -1, &lmsg); const char *tp = msg + lmsg - leof; if (strstr(msg, eof) != tp) { words_.push_back("syntax"); words_.push_back(msg); clear_raw_input(); } } else { words_.push_back("lua"); words_.push_back(partial); clear_raw_input(); } lua_settop(lua_state_, top); }