Implemented the keyword argument parser.
This commit is contained in:
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user