Added constructors to tangible.build, more work on keyword argument parsing, added LS.tailcall.

This commit is contained in:
2025-01-21 20:20:54 -05:00
parent 485caee05d
commit 69cb659d78
6 changed files with 83 additions and 18 deletions

View File

@@ -183,6 +183,14 @@ LUPREXBUILDTASK["type"] = "shell"
LUPREXBUILDTASK["options"] = {}
LUPREXBUILDTASK["options"]["cwd"] = f"{INTEGRATION}/luprex"
#
# Add a presentation { clear=true } to all build tasks.
#
for task in WORKSPACE["tasks"]["tasks"]:
task["presentation"] = {}
task["presentation"]["clear"] = True
#
# Convert all launch configurations to lldb.
#

View File

@@ -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);

View File

@@ -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();

View File

@@ -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);
@@ -357,9 +357,12 @@ LuaDefine(tangible_build, "config",
tan->anim_queue_.clear(state);
tan->update_plane_item();
// TODO: call the constructor.
// 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",

View File

@@ -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);
}
}

View File

@@ -1,16 +1,24 @@
makeclass('login')
makeclass("engio")
makeclass('tree')
function login.initialize(actor, place)
dprint("login.initialize:", actor)
function tree.init(self, config)
print("In tree.init:")
pprint{self=self, config=config}
wait(1)
print("tick");
wait(1)
end
function login.init(actor, place)
dprint("login.init:", actor)
local x = math.random(1, 100)
local y = math.random(1, 100)
tangible.animate(actor, nil, {bp="tangiblecharacter", action="warpto", plane="earth", xyz={x, y, 90}})
end
end
function engio.move(actor, place, action, xyz, facing)
-- todo: sanity check the parameters.
dprint("engio.move ", action, " ", xyz[1], " ", xyz[2], " ", xyz[3])
tangible.animate(actor, nil, {action=action, xyz=xyz, facing=facing})
end
end