No, really, this is the code for the new keyword parsing.

This commit is contained in:
2022-07-22 16:04:14 -04:00
parent 001add12bf
commit e6414e113d
2 changed files with 51 additions and 13 deletions

View File

@@ -155,6 +155,8 @@
#define LUASTACK_HPP
#include "wrap-string.hpp"
#include "wrap-set.hpp"
#include <cstring>
extern "C" {
#include "lua.h"
@@ -351,6 +353,8 @@ private:
static void delete_pointer(void *p) { delete (T*)p; }
static void do_not_delete(void *p) { }
void argerr(const char *arg, const char *tp) const;
public:
template<class... SS>
LuaStack(lua_State *L, SS & ... stackslots) {
@@ -386,19 +390,22 @@ public:
bool isint(LuaSlot s) const;
bool isthread(LuaSlot s) const { return lua_type(L_, s) == LUA_TTHREAD; }
bool isfunction(LuaSlot s) const { return lua_type(L_, s) == LUA_TFUNCTION; }
bool iscfunction(LuaSlot s) const { return lua_iscfunction(L_, s) != 0; }
bool isboolean(LuaSlot s) const { return lua_type(L_, s) == LUA_TBOOLEAN; }
bool isnil(LuaSlot s) const { return lua_type(L_, s) == LUA_TNIL; }
bool iscfunction(LuaSlot s) const { return lua_iscfunction(L_, s) != 0; }
bool istoken(LuaSlot s) const { return lua_islightuserdata(L_, s) != 0; }
void checktable(LuaSlot index) const { checktype(index, LUA_TTABLE); }
void checkstring(LuaSlot index) const { checktype(index, LUA_TSTRING); }
void checknumber(LuaSlot index) const { checktype(index, LUA_TNUMBER); }
void checkthread(LuaSlot index) const { checktype(index, LUA_TTHREAD); }
void checkfunction(LuaSlot index) const { checktype(index, LUA_TFUNCTION); }
void checkboolean(LuaSlot index) const { checktype(index, LUA_TBOOLEAN); }
void checknil(LuaSlot index) const { checktype(index, LUA_TNIL); }
void checktoken(LuaSlot index) const { checktype(index, LUA_TLIGHTUSERDATA); }
void checktable(LuaSlot s, const char *n) const { if (!istable(s)) argerr(n, "table"); }
void checkstring(LuaSlot s, const char *n) const { if (!isstring(s)) argerr(n, "string"); }
void checknumber(LuaSlot s, const char *n) const { if (!isnumber(s)) argerr(n, "number"); }
void checkinteger(LuaSlot s, const char *n) const { if (!isinteger(s)) argerr(n, "integer"); }
void checkint(LuaSlot s, const char *n) const { if (!isint(s)) argerr(n, "int"); }
void checkthread(LuaSlot s, const char *n) const { if (!isthread(s)) argerr(n, "thread"); }
void checkfunction(LuaSlot s, const char *n) const { if (!isfunction(s)) argerr(n, "function"); }
void checkcfunction(LuaSlot s, const char *n) const { if (!iscfunction(s)) argerr(n, "cfunction"); }
void checkboolean(LuaSlot s, const char *n) const { if (!isboolean(s)) argerr(n, "boolean"); }
void checknil(LuaSlot s, const char *n) const { if (!isnil(s)) argerr(n, "nil"); }
void checktoken(LuaSlot s, const char *n) const { if (!istoken(s)) argerr(n, "token"); }
bool ckboolean(LuaSlot s) const;
lua_Integer ckinteger(LuaSlot s) const;
@@ -516,6 +523,37 @@ public:
static bool int64_storable(int64_t v) { return (v <= MAXINT) && (v >= -MAXINT); }
};
// This is a helper class to help parse tables full of keywords.
class LuaKeywordParser {
struct cmp_char {
bool operator () (const char *s1, const char *s2) const {
return strcmp(s1, s2) < 0;
};
};
private:
lua_State *L_;
int slot_;
eng::set<const char *, cmp_char> parsed_;
void init(const lua_State *L, int slot);
public:
// The constructor will throw a lua error if the
// slot is not a table.
LuaKeywordParser(lua_State *L, int slot);
LuaKeywordParser(const LuaStack &LS, LuaSlot slot) : LuaKeywordParser(LS.state(), slot.index()) {}
// Fetch a value from the table. This never throws.
// Return true if the value is non-nil.
bool parse(LuaSlot slot, const char *kw);
// Check if there are any keywords in the table that
// were never parsed. If so, throw an error.
void check_unparsed_keywords();
// Fetch the state pointer.
lua_State *state() const { return L_; }
};
class LuaConstantReg : public eng::nevernew {
private:
const char *name_;

View File

@@ -131,8 +131,8 @@ public:
// Convert a lua table into a scan configuration.
//
// If there is an error in the configuration, returns an
// error message, otherwise returns empty string.
// If there is an error in the configuration,
// throws a lua error message.
//
// Caution: if this detects the configuration flag 'near',
// then it stores the near ID. However, it doesn't fetch
@@ -141,7 +141,7 @@ public:
// and plane. This is admittedly ugly, but it eliminates
// a dependency on the world module.
//
eng::string configure(const LuaStack &LS, LuaSlot slot);
void configure(LuaKeywordParser &kw);
void set_bbox_given_center_radius(const util::XYZ &center, float r) {
set_center(center);