Hi Gnomi,
TL;DR: call_other() ruins everything.
On 12.03.24 19:22, Gnomi wrote:
> Hi Invisible,
>
> I'm not sure I understand your proposal.
I was thinking about it more from the "receiving side", i.e. the moment
before a function is actually executed in the driver.
For local calls it would be rather straightforward:
void func(int a, int b);
would internally be more like
void func(<anon> int a, int b);
with a and b referencing the local function variables a and b on the stack.
(I'm writing func(<>...) here, instead of func( (<>...) ), to denote
that this struct is never visible on the LPC side, but only internally
generated from the function prototype, and only used to associate the
parameters on the stack with their respective names.)
The parser would then just have to treat everything in the brackets of a
function call as a struct initialization, thereby writing the values
into the local variables.
So in a world without call_other() & Co it could have been relatively easy.
> So we have a function call via some forwarding function like call_other:
>
> ob->fun(b: 10);
Yes, call_other is a very special case. The problem here is mostly in
the 'varargs' part, because when forwarding a function call it cannot
just be resolved to an array of values any longer (as that would lose
the argument names). So this would limit 'varargs' parameters to
positional only - which kinda defeats the point of having named
arguments in the first place, since call_other() is so widely used in LPC.
To make this work would require a replacement for 'varargs' that would
not return an array, but a new datatype for an argument-list, which is
an array/struct blend (as at this point we don't know the target
function's signature we have to preserve the provided argument list
as-is, including argument names as well as unnamed arguments in the
correct order, so that they can later be mapped onto the function
prototype correctly).
This would in turn also require extending the '...' operator to handle
this new argument-list datatype, which would then also have to properly
merge these arguments with the others provided in the call, as well as
map the result onto the actual implicitly generated struct from the
function at the time of the function call - which both open up a whole
new can of worms each, because now we can also have collisions between
positional and named arguments at runtime.
And at this point we're drifting more and more away from just using the
existing concepts of structs. :-(
> If so, I think there needs to be some disambiguation between passing this
> generated argument struct and passing a real struct as an argument.
The "real" struct would just be a field *inside* the implicitly
generated struct (which would directly reference the correct location on
the stack to end up in the correct variable), so no problem here.
> In the same line: How would a call_other sefun look like?
A simul_efun::call_other wouldn't be anything special per se, but of
course the varargs-problem still remains the same.
Plus the first two parameters of call_other & Co would need to have
reserved names, to prevent collisions.
regards,
Invis