Added constructors to tangible.build, more work on keyword argument parsing, added LS.tailcall.
This commit is contained in:
@@ -653,9 +653,26 @@ void LuaCoreStack::guard_nopredict(const char *fn) {
|
||||
}
|
||||
}
|
||||
|
||||
static int tailcall_continuation(lua_State *L)
|
||||
{
|
||||
int base;
|
||||
lua_getctx(L, &base);
|
||||
return lua_gettop(L) - base;
|
||||
}
|
||||
|
||||
int LuaDefStack::tailcall_internal(bool passup, int base, int nargs) {
|
||||
lua_callk(L_, nargs, passup ? LUA_MULTRET : 0, base, tailcall_continuation);
|
||||
return lua_gettop(L_) - base;
|
||||
}
|
||||
|
||||
LuaKeywordParser::LuaKeywordParser(const LuaCoreStack &LS0, LuaSlot slot)
|
||||
: keytab(slot.index()), LS(LS0.state(), found, error, key, val) {
|
||||
: keytab(slot.index()), LS(LS0.state()) {
|
||||
lua_State *L = LS0.state();
|
||||
lua_pushnil(L); found.index_ = lua_gettop(L);
|
||||
lua_pushnil(L); error.index_ = lua_gettop(L);
|
||||
lua_pushnil(L); key.index_ = lua_gettop(L);
|
||||
lua_pushnil(L); val.index_ = lua_gettop(L);
|
||||
|
||||
istable = LS.istable(keytab);
|
||||
if (istable) {
|
||||
LS.rawget(found, keytab, token_found);
|
||||
|
||||
@@ -493,6 +493,7 @@ private:
|
||||
friend class LuaCoreStack;
|
||||
friend class LuaDefStack;
|
||||
friend class LuaExtStack;
|
||||
friend class LuaKeywordParser;
|
||||
};
|
||||
|
||||
class LuaArg : public LuaSlot {};
|
||||
@@ -1136,7 +1137,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);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@@ -1237,7 +1264,7 @@ class LuaKeywordParser {
|
||||
private:
|
||||
LuaVar found, error, key, val;
|
||||
LuaSpecial keytab;
|
||||
LuaExtStack LS;
|
||||
LuaCoreStack LS;
|
||||
bool istable;
|
||||
|
||||
void init(const lua_State *L, int slot);
|
||||
@@ -1255,12 +1282,14 @@ public:
|
||||
// stores an [ERROR] report in the keyword table.
|
||||
bool required(LuaSlot slot, std::string_view kw);
|
||||
|
||||
// Check if there are any errors so far. If any error has been
|
||||
// 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. Also check that all keyword
|
||||
// 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();
|
||||
|
||||
@@ -109,8 +109,8 @@ LuaDefine(tangible_animinit, "tan,config",
|
||||
"|get persisted: they stay the same unless you change them in"
|
||||
"|the 'animate' command."
|
||||
"|"
|
||||
"|There are five hardwired persistent variables: plane,xyz,facing,bp,model."
|
||||
"|These five variables are persistent no matter what. This function,"
|
||||
"|There are four hardwired persistent variables: plane,xyz,facing,bp."
|
||||
"|These variables are persistent no matter what. This function,"
|
||||
"|tangible.animinit, optionally allows you to create more persistent"
|
||||
"|variables. For example, let's say you have a pirate chest. You might"
|
||||
"|want to add two persistent variables in addition to the usual set:"
|
||||
@@ -302,9 +302,9 @@ LuaDefine(tangible_build, "config",
|
||||
"|The constructor is not allowed to block."
|
||||
){
|
||||
LuaArg config;
|
||||
LuaVar classname, classtab, bp, plane, xyz, facing, mt;
|
||||
LuaVar classname, classtab, bp, plane, xyz, facing, mt, func;
|
||||
LuaRet database;
|
||||
LuaDefStack LS(L, config, classname, classtab, bp, plane, xyz, facing, mt, database);
|
||||
LuaDefStack LS(L, config, classname, classtab, bp, plane, xyz, facing, mt, func, database);
|
||||
World *w = World::fetch_global_pointer(L);
|
||||
|
||||
LuaKeywordParser kp(LS, config);
|
||||
@@ -356,10 +356,13 @@ LuaDefine(tangible_build, "config",
|
||||
// Initialize the animstate of the new tangible.
|
||||
tan->anim_queue_.clear(state);
|
||||
tan->update_plane_item();
|
||||
|
||||
// TODO: call the constructor.
|
||||
|
||||
return LS.result();
|
||||
|
||||
// Call the constructor and finish.
|
||||
LS.rawget(func, classtab, "init");
|
||||
if (!LS.isfunction(func)) {
|
||||
return LS.result();
|
||||
}
|
||||
return LS.tailcall(false, func, database, config);
|
||||
}
|
||||
|
||||
LuaDefine(tangible_get, "id",
|
||||
|
||||
@@ -331,7 +331,7 @@ int64_t World::create_login_actor() {
|
||||
tan->print_buffer_.clear();
|
||||
|
||||
if (is_authoritative()) {
|
||||
LS.rawget(func, classtab, "initialize");
|
||||
LS.rawget(func, classtab, "init");
|
||||
spawn(LS, id, id, func, true, 0, false);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user