diff --git a/luprex/cpp/gui.cpp b/luprex/cpp/gui.cpp index c5477553..fe4a6c75 100644 --- a/luprex/cpp/gui.cpp +++ b/luprex/cpp/gui.cpp @@ -10,3 +10,18 @@ void Gui::add_menu_item(const std::string &id, const std::string &label) { elts_.push_back(elt); } +LuaDefine(gui_create, "c") { + LuaRet lgui; + LuaStack LS(L, lgui); + LS.newpointer(lgui, new Gui, true); + return LS.result(); +} + +LuaDefine(gui_add_menu_item, "c") { + LuaArg lgui, lid; + LuaStack LS(L, lgui, lid); + Gui *gui = LS.ckuserdata(lgui); + std::string id = LS.ckstring(lid); + gui->add_menu_item(id, id); + return LS.result(); +} diff --git a/luprex/cpp/luaconsole.cpp b/luprex/cpp/luaconsole.cpp index c3733f22..88a78ce6 100644 --- a/luprex/cpp/luaconsole.cpp +++ b/luprex/cpp/luaconsole.cpp @@ -48,34 +48,23 @@ void LuaConsole::add(std::string line) { raw_input_ += line; raw_input_ += '\n'; lines_ += 1; - char cmd = raw_input_[0]; - // All commands are a single character. - if ((raw_input_[1] != ' ')&&(raw_input_[1] != '\n')) { - action_ = DO_SYNTAX; - syntax_ = "Commands are a single character followed by arguments"; - return; - } - - // Analyze non-lua commands. - if ((cmd != 'r') && (cmd != 'l')) { - lua_expression_ = ""; - if (lines_ == 1) { + // Try to interpret it as a special command. + if (lines_ == 1) { + split_words(); + if ((words_.size() >= 1)&&(words_[0].size() == 1)) { action_ = DO_COMMAND; - split_words(); - } else { - action_ = DO_SYNTAX; - syntax_ = "slash command has more than one line"; + return; } - return; } - + words_.clear(); + // Strip the leading punctuation from lua commands. std::string partial; - if (cmd == 'r') { - partial = std::string("return ") + raw_input_.substr(2); + if (raw_input_[0] == '=') { + partial = std::string("return ") + raw_input_.substr(1); } else { - partial = raw_input_.substr(2); + partial = raw_input_; } // Analyze lua expressions. diff --git a/luprex/cpp/luaconsole.hpp b/luprex/cpp/luaconsole.hpp index 4c2bdeeb..0af201e4 100644 --- a/luprex/cpp/luaconsole.hpp +++ b/luprex/cpp/luaconsole.hpp @@ -32,7 +32,7 @@ class LuaConsole { public: enum { DO_NOTHING, // We need more input text. - DO_COMMAND, // We have a valid non-lua command. + DO_COMMAND, // We have a valid slash command. DO_LUA, // We have a valid lua expression. DO_SYNTAX, // We have a syntax error. }; diff --git a/luprex/cpp/luastack.cpp b/luprex/cpp/luastack.cpp index 4d1bb38f..0c4fee30 100644 --- a/luprex/cpp/luastack.cpp +++ b/luprex/cpp/luastack.cpp @@ -1,4 +1,5 @@ #include "luastack.hpp" +#include "util.hpp" #include LuaSpecial LuaRegistry(LUA_REGISTRYINDEX); @@ -24,11 +25,10 @@ int LuaStack::collect_tagged_pointer(lua_State *L) { if (p==0) { luaL_error(L, "lua deleter function received a non-userdata"); } - if (p->ptr == 0) { - luaL_error(L, "lua object already deleted"); + if (p->ptr != 0) { + p->del(p->ptr); + p->ptr = 0; } - p->del(p->ptr); - p->ptr = 0; return 0; } @@ -37,7 +37,7 @@ void LuaStack::register_all_userdata(lua_State *L) { LuaStack LS(L, tab, lud); auto regs = LuaFunctionReg::all(); for (const LuaFunctionReg *r : regs) { - const std::string &name = r->get_name(); + const std::string &name = util::tolower(r->get_name()); lua_CFunction tag = r->get_func(); std::string mode = r->get_mode(); if (mode.find('t') != std::string::npos) { // Register type @@ -209,4 +209,18 @@ void LuaStack::check_nret(int xnret, int otop, int nret) const { luaL_error(L_, "expected %d return values", xnret); } } - \ No newline at end of file + +LuaDefine(system_type, "f") { + LuaArg obj; + LuaRet tname; + LuaVar mt; + LuaStack LS(L, obj, tname, mt); + int type = LS.type(obj); + if (type == LUA_TUSERDATA) { + LS.getmetatable(mt, obj); + LS.getfield(tname, mt, "type"); + } else { + LS.set(tname, lua_typename(L, type)); + } + return LS.result(); +} diff --git a/luprex/cpp/util.cpp b/luprex/cpp/util.cpp index f0c0ae0d..3f902cbb 100644 --- a/luprex/cpp/util.cpp +++ b/luprex/cpp/util.cpp @@ -12,6 +12,20 @@ namespace util { +std::string tolower(std::string input) { + for (int i = 0; i < int(input.size()); i++) { + input[i] = std::tolower(input[i]); + } + return input; +} + +std::string toupper(std::string input) { + for (int i = 0; i < int(input.size()); i++) { + input[i] = std::toupper(input[i]); + } + return input; +} + int64_t strtoint(const std::string &value, int64_t errval) { char *endptr; int64_t result = strtoll(value.c_str(), &endptr, 10); diff --git a/luprex/cpp/util.hpp b/luprex/cpp/util.hpp index 2db747d6..70bbafec 100644 --- a/luprex/cpp/util.hpp +++ b/luprex/cpp/util.hpp @@ -14,6 +14,10 @@ namespace util { using stringvec = std::vector; using stringset = std::set; +// String to lowercase/uppercase +std::string tolower(std::string input); +std::string toupper(std::string input); + // String to integer. Returns errval if the number is not parseable. int64_t strtoint(const std::string &value, int64_t errval);