2021-01-23 16:10:29 -05:00
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include "luaconsole.hpp"
|
2021-02-10 16:22:24 -05:00
|
|
|
#include "util.hpp"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static bool is_single_letter(const std::string &s) {
|
|
|
|
|
return ((s.size() == 1) && (s[0] >= 'a') && (s[0] <= 'z'));
|
|
|
|
|
}
|
2021-01-23 16:10:29 -05:00
|
|
|
|
|
|
|
|
LuaConsole::LuaConsole() {
|
2021-02-28 14:24:59 -05:00
|
|
|
lua_state_ = luaL_newstate();
|
2021-01-23 16:10:29 -05:00
|
|
|
clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LuaConsole::~LuaConsole() {
|
|
|
|
|
lua_close(lua_state_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void LuaConsole::clear() {
|
2021-02-02 16:29:07 -05:00
|
|
|
raw_input_ = "";
|
2021-01-23 16:10:29 -05:00
|
|
|
lines_ = 0;
|
2021-02-02 16:29:07 -05:00
|
|
|
lua_expression_ = "";
|
|
|
|
|
words_.clear();
|
2021-01-23 20:12:21 -05:00
|
|
|
syntax_ = "";
|
|
|
|
|
action_ = DO_NOTHING;
|
2021-01-23 16:10:29 -05:00
|
|
|
}
|
2021-02-02 16:29:07 -05:00
|
|
|
|
|
|
|
|
void LuaConsole::split_words() {
|
|
|
|
|
words_.clear();
|
|
|
|
|
std::string acc;
|
|
|
|
|
for (char c : raw_input_) {
|
|
|
|
|
if ((c == ' ')||(c == '\n')) {
|
|
|
|
|
if (!acc.empty()) {
|
|
|
|
|
words_.push_back(acc);
|
|
|
|
|
acc = "";
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
acc += c;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!acc.empty()) {
|
|
|
|
|
words_.push_back(acc);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-23 16:10:29 -05:00
|
|
|
void LuaConsole::add(std::string line) {
|
2021-01-23 20:12:21 -05:00
|
|
|
if (action_ != DO_NOTHING) {
|
|
|
|
|
clear();
|
|
|
|
|
}
|
2021-01-23 16:10:29 -05:00
|
|
|
for (int i = 0; i < int(line.size()); i++) {
|
|
|
|
|
if (line[i] == '\n') line[i] = ' ';
|
|
|
|
|
}
|
2021-02-02 16:29:07 -05:00
|
|
|
raw_input_ += line;
|
|
|
|
|
raw_input_ += '\n';
|
2021-01-23 16:10:29 -05:00
|
|
|
lines_ += 1;
|
|
|
|
|
|
2021-02-07 15:35:31 -05:00
|
|
|
// Try to interpret it as a special command.
|
|
|
|
|
if (lines_ == 1) {
|
|
|
|
|
split_words();
|
2021-02-10 16:22:24 -05:00
|
|
|
if (words_.size() >= 1) {
|
|
|
|
|
if (is_single_letter(words_[0]) || (util::validinteger(words_[0]))) {
|
|
|
|
|
action_ = DO_COMMAND;
|
|
|
|
|
return;
|
|
|
|
|
}
|
2021-01-23 16:10:29 -05:00
|
|
|
}
|
|
|
|
|
}
|
2021-02-07 15:35:31 -05:00
|
|
|
words_.clear();
|
|
|
|
|
|
2021-02-10 16:22:24 -05:00
|
|
|
// Translate lua expression with leading '=' to 'return'
|
2021-02-02 16:29:07 -05:00
|
|
|
std::string partial;
|
2021-02-07 15:35:31 -05:00
|
|
|
if (raw_input_[0] == '=') {
|
|
|
|
|
partial = std::string("return ") + raw_input_.substr(1);
|
2021-02-02 16:29:07 -05:00
|
|
|
} else {
|
2021-02-07 15:35:31 -05:00
|
|
|
partial = raw_input_;
|
2021-02-02 16:29:07 -05:00
|
|
|
}
|
2021-01-23 16:10:29 -05:00
|
|
|
|
2021-02-10 16:22:24 -05:00
|
|
|
// Try to parse the lua expression
|
2021-01-23 16:10:29 -05:00
|
|
|
int top = lua_gettop(lua_state_);
|
2021-02-02 16:29:07 -05:00
|
|
|
int status = luaL_loadbuffer(lua_state_, partial.c_str(), partial.size(), "=stdin");
|
2021-01-23 16:10:29 -05:00
|
|
|
if (status == LUA_ERRSYNTAX)
|
|
|
|
|
{
|
2021-07-12 00:37:07 -04:00
|
|
|
const char *eof = "<eof>";
|
|
|
|
|
int leof = strlen(eof);
|
2021-01-23 16:10:29 -05:00
|
|
|
size_t lmsg;
|
|
|
|
|
const char *msg = lua_tolstring(lua_state_, -1, &lmsg);
|
2021-07-12 00:37:07 -04:00
|
|
|
const char *tp = msg + lmsg - leof;
|
2021-01-23 16:10:29 -05:00
|
|
|
if (strstr(msg, eof) == tp) {
|
2021-01-23 20:12:21 -05:00
|
|
|
action_ = DO_NOTHING;
|
2021-01-23 16:10:29 -05:00
|
|
|
} else {
|
2021-01-23 20:12:21 -05:00
|
|
|
action_ = DO_SYNTAX;
|
2021-02-02 16:29:07 -05:00
|
|
|
syntax_ = msg;
|
2021-01-23 16:10:29 -05:00
|
|
|
}
|
|
|
|
|
} else {
|
2021-02-02 16:29:07 -05:00
|
|
|
action_ = DO_LUA;
|
|
|
|
|
lua_expression_ = partial;
|
2021-01-23 16:10:29 -05:00
|
|
|
}
|
|
|
|
|
lua_settop(lua_state_, top);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void LuaConsole::add_stdin() {
|
2021-01-23 20:12:21 -05:00
|
|
|
if (action_ != DO_NOTHING) {
|
|
|
|
|
clear();
|
|
|
|
|
}
|
2021-01-23 16:10:29 -05:00
|
|
|
const int MAXINPUT = 1000;
|
|
|
|
|
char buf[MAXINPUT];
|
2021-02-02 16:29:07 -05:00
|
|
|
fputs(raw_input_.empty() ? "> " : ">> ", stdout);
|
2021-01-23 16:10:29 -05:00
|
|
|
fflush(stdout);
|
|
|
|
|
if (fgets(buf, MAXINPUT, stdin)) {
|
|
|
|
|
size_t len = strlen(buf);
|
|
|
|
|
if (len > 0 && buf[len - 1] == '\n')
|
|
|
|
|
buf[len - 1] = '\0';
|
|
|
|
|
add(buf);
|
|
|
|
|
}
|
|
|
|
|
}
|