Implemented the keyword argument parser.

This commit is contained in:
2022-07-22 16:00:37 -04:00
parent 4735c1fd7d
commit 001add12bf
7 changed files with 116 additions and 113 deletions

View File

@@ -3,6 +3,8 @@
#include <cassert>
#include <cstdio>
#include <climits>
#include "wrap-string.hpp"
#include "wrap-set.hpp"
LuaSpecial LuaRegistry(LUA_REGISTRYINDEX);
LuaNilMarker LuaNil;
@@ -76,6 +78,10 @@ lua_State *LuaStack::newstate (lua_Alloc allocf) {
return L;
}
void LuaStack::argerr(const char *nm, const char *tp) const {
luaL_error(L_, "'%s' should be %s", nm, tp);
}
bool LuaStack::isinteger(LuaSlot s) const {
if (lua_type(L_, s) == LUA_TNUMBER) {
lua_Number result = lua_tonumber(L_, s);
@@ -93,11 +99,12 @@ bool LuaStack::isint(LuaSlot s) const {
}
bool LuaStack::ckboolean(LuaSlot s) const {
luaL_checktype(L_, s, LUA_TBOOLEAN);
checkboolean(s, "value");
return lua_toboolean(L_, s) ? true:false;
}
lua_Integer LuaStack::ckinteger(LuaSlot s) const {
checknumber(s, "value");
luaL_checktype(L_, s, LUA_TNUMBER);
lua_Number result = lua_tonumber(L_, s);
lua_Integer iresult(result);
@@ -109,7 +116,7 @@ lua_Integer LuaStack::ckinteger(LuaSlot s) const {
}
int LuaStack::ckint(LuaSlot s) const {
luaL_checktype(L_, s, LUA_TNUMBER);
checknumber(s, "value");
lua_Number result = lua_tonumber(L_, s);
int iresult(result);
if (iresult != result) {
@@ -120,31 +127,31 @@ int LuaStack::ckint(LuaSlot s) const {
}
lua_Number LuaStack::cknumber(LuaSlot s) const {
luaL_checktype(L_, s, LUA_TNUMBER);
checknumber(s, "value");
return lua_tonumber(L_, s);
}
eng::string LuaStack::ckstring(LuaSlot s) const {
luaL_checktype(L_, s, LUA_TSTRING);
checkstring(s, "value");
size_t len;
const char *str = lua_tolstring(L_, s, &len);
return eng::string(str, len);
}
std::string_view LuaStack::ckstringview(LuaSlot s) const {
luaL_checktype(L_, s, LUA_TSTRING);
checkstring(s, "value");
size_t len;
const char *str = lua_tolstring(L_, s, &len);
return std::string_view(str, len);
}
lua_State *LuaStack::ckthread(LuaSlot s) const {
luaL_checktype(L_, s, LUA_TTHREAD);
checkthread(s, "value");
return lua_tothread(L_, s);
}
LuaToken LuaStack::cktoken(LuaSlot s) const {
luaL_checktype(L_, s, LUA_TLIGHTUSERDATA);
checktoken(s, "value");
return LuaToken(lua_touserdata(L_, s));
}
@@ -457,3 +464,41 @@ bool LuaStack::getvisited(LuaSlot tab) const {
void LuaStack::setvisited(LuaSlot tab, bool visited) const {
lua_modflagbits(L_, tab.index(), 0x0010, visited ? 0x0010 : 0);
}
LuaKeywordParser::LuaKeywordParser(lua_State *L, int slot) {
L_ = L;
slot_ = slot;
if (!lua_istable(L_, slot_)) {
luaL_error(L_, "expected an argument which is a table full of keywords");
}
}
bool LuaKeywordParser::parse(LuaSlot out, const char *kw) {
lua_pushstring(L_, kw);
lua_rawget(L_, slot_);
lua_replace(L_, out.index());
if (!lua_isnil(L_, out.index())) {
parsed_.insert(kw);
return true;
} else {
return false;
}
};
void LuaKeywordParser::check_unparsed_keywords() {
if (lua_nkeys(L_, slot_) != int(parsed_.size())) {
lua_pushnil(L_);
while (lua_next(L_, slot_) != 0) {
lua_pop(L_, 1); // Don't need the value.
if (!lua_isstring(L_, -1)) {
luaL_error(L_, "keyword table contains non-string key");
}
const char *kw = lua_tostring(L_, -1);
if (parsed_.find(kw) == parsed_.end()) {
luaL_error(L_, "keyword %s not known", kw);
}
}
assert(false && "should never get here in check_unparsed_keywords");
}
}