Merge
This commit is contained in:
@@ -538,6 +538,7 @@ private:
|
||||
friend class LuaCoreStack;
|
||||
friend class LuaDefStack;
|
||||
friend class LuaExtStack;
|
||||
friend class LuaKeywordParser;
|
||||
};
|
||||
|
||||
class LuaArg : public LuaSlot {};
|
||||
@@ -563,10 +564,8 @@ private:
|
||||
int size_;
|
||||
|
||||
public:
|
||||
LuaExtraArgs() {
|
||||
index_ = 0;
|
||||
size_ = 0;
|
||||
}
|
||||
LuaExtraArgs() : index_(0), size_(0) {}
|
||||
LuaExtraArgs(int i, int s) : index_(i), size_(s) {}
|
||||
|
||||
LuaSpecial operator[] (int n) const { return LuaSpecial(index_ + n); }
|
||||
int size() const { return size_; }
|
||||
@@ -1183,7 +1182,33 @@ public:
|
||||
return nret_;
|
||||
}
|
||||
|
||||
// Tail-call into lua.
|
||||
//
|
||||
// This is meant to be used as follows: return LS.tailcall(passup, func, arg, arg...)
|
||||
//
|
||||
// If passup is true, the return value to our caller consists of our
|
||||
// LuaRet arguments concatenated to the return values from the tail-call.
|
||||
// If passup is false, the return value to our caller consists solely
|
||||
// of our LuaRet arguments.
|
||||
//
|
||||
template<typename... T>
|
||||
int tailcall(bool passup, LuaSlot func, T... args) {
|
||||
lua_checkstack(L_, nret_ + 20);
|
||||
int base = lua_gettop(L_);
|
||||
for (int i = 1; i <= nret_; i++) {
|
||||
lua_pushvalue(L_, i);
|
||||
}
|
||||
push_any_value(func);
|
||||
int argbase = lua_gettop(L_);
|
||||
push_any_values(args...);
|
||||
int nargs = lua_gettop(L_) - argbase;
|
||||
return tailcall_internal(passup, base, nargs);
|
||||
}
|
||||
|
||||
~LuaDefStack() { }
|
||||
|
||||
private:
|
||||
int tailcall_internal(bool passup, int base, int nargs);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@@ -1231,7 +1256,9 @@ public:
|
||||
|
||||
~LuaExtStack() {
|
||||
if (!lua_isthrowing(L_)) {
|
||||
lua_settop(L_, oldtop_);
|
||||
if (lua_gettop(L_) > oldtop_) {
|
||||
lua_settop(L_, oldtop_);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1246,49 +1273,85 @@ public:
|
||||
//
|
||||
// * It makes sure the keyword table actually is a table.
|
||||
//
|
||||
// * It makes sure that you didn't put an unrecognized keyword
|
||||
// into the keyword table. Unrecognized keywords are defined
|
||||
// as keywords that are never checked using 'parse'.
|
||||
// * It makes sure that all required keywords are present.
|
||||
//
|
||||
// * It makes sure that you didn't put anything that isn't a
|
||||
// keyword into the keyword table.
|
||||
// known keyword into the keyword table.
|
||||
//
|
||||
// This module adds two fields to the table:
|
||||
//
|
||||
// [ERROR] - stores an error message, initially nil.
|
||||
// [FOUND] - the set of keywords successfully parsed.
|
||||
//
|
||||
// If at any time, this module detects an error, it doesn't throw.
|
||||
// Instead, it stores an error report in the table key [ERROR].
|
||||
// Later, you can check for an error string using the function
|
||||
// final_check or final_check_throw. If an error is
|
||||
// detected when there is already an error report in the table,
|
||||
// the error report is not overwritten, so therefore, the error
|
||||
// reported is always the first error detected.
|
||||
//
|
||||
// When this module finds a keyword in the table, it adds the keyword
|
||||
// to the [FOUND] set of all keywords successfully parsed.
|
||||
//
|
||||
// If the keyword table that you pass in isn't a table at all,
|
||||
// then the keyword-fetching functions will always return false.
|
||||
// Later, when you call 'check', an appropriate error will be
|
||||
// generated.
|
||||
//
|
||||
// The lua module 'keywords' contains the same functions as this
|
||||
// C++ class. You can write code where a C++ function does some
|
||||
// of the parsing, and the lua code does the rest of the parsing.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
class LuaKeywordParser {
|
||||
struct cmp_char {
|
||||
bool operator () (const char *s1, const char *s2) const {
|
||||
return strcmp(s1, s2) < 0;
|
||||
};
|
||||
};
|
||||
private:
|
||||
bool not_table_;
|
||||
lua_State *L_;
|
||||
int slot_;
|
||||
eng::set<const char *, cmp_char> parsed_;
|
||||
LuaVar found, error, key, val;
|
||||
LuaSpecial keytab;
|
||||
LuaCoreStack LS;
|
||||
bool istable;
|
||||
|
||||
void init(const lua_State *L, int slot);
|
||||
public:
|
||||
// If the slot is not a table, sets the not_table
|
||||
// flag and creates a dummy table in the slot.
|
||||
LuaKeywordParser(lua_State *L, int slot);
|
||||
LuaKeywordParser(const LuaCoreStack &LS, LuaSlot slot) : LuaKeywordParser(LS.state(), slot.index()) {}
|
||||
LuaKeywordParser(const LuaCoreStack &LS, LuaSlot slot);
|
||||
|
||||
// Fetch a value from the table. This never throws.
|
||||
// Return true if the value is non-nil.
|
||||
bool parse(LuaSlot slot, const char *kw);
|
||||
// Fetch the value of the keyword. If the keyword is found, then the
|
||||
// keyword is added to the [FOUND] set, the value is returned in slot,
|
||||
// and returns true. Otherwise, sets slot to nil and returns false.
|
||||
bool optional(LuaSlot slot, std::string_view kw);
|
||||
|
||||
// Check if there were any errors. If so, return an
|
||||
// error message.
|
||||
// Fetch the value of the keyword. If the keyword is found, then the
|
||||
// keyword is added to the [FOUND] set, the value is returned in slot,
|
||||
// and returns true. Otherwise, sets slot to nil, returns false, and
|
||||
// stores an [ERROR] report in the keyword table.
|
||||
bool required(LuaSlot slot, std::string_view kw);
|
||||
|
||||
// Check if there are any errors so far, by checking for an [ERROR]
|
||||
// report in the keyword table. If any error has been
|
||||
// detected, returns an error message, otherwise, returns empty
|
||||
// string.
|
||||
eng::string check();
|
||||
|
||||
// Check if there are any errors so far, by checking for an [ERROR]
|
||||
// report in the keyword table. Also check that all keyword
|
||||
// arguments present in the table are in the [FOUND] set. If there are
|
||||
// any errors, returns an error message, otherwise returns empty string.
|
||||
eng::string final_check();
|
||||
|
||||
// Check if there are any errors. If so, throw a lua error.
|
||||
// If check() returns an error, throws the error using luaL_error.
|
||||
void check_throw();
|
||||
|
||||
// If final_check() returns an error, throws the error using luaL_error.
|
||||
void final_check_throw();
|
||||
|
||||
// Fetch the state pointer.
|
||||
lua_State *state() const { return L_; }
|
||||
lua_State *state() const { return LS.state(); }
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Lua Byte Reader
|
||||
|
||||
Reference in New Issue
Block a user