The return statement now accepts any expression as its return value

So something like 'return ++user_x;' is now possible
Admittedly this needed quite a bit of refactoring mainly due to the fact that return types now have to be checked after resolving the function rather than before
This commit is contained in:
Leonard2 2016-08-02 18:50:34 +02:00 committed by Christoph Oelckers
commit b97024b710
5 changed files with 326 additions and 220 deletions

View file

@ -270,23 +270,28 @@ static void FinishThingdef()
for (i = 0; i < StateTempCalls.Size(); ++i)
{
FStateTempCall *tcall = StateTempCalls[i];
VMFunction *func;
VMFunction *func = nullptr;
assert(tcall->Code != NULL);
// Can we call this function directly without wrapping it in an
// anonymous function? e.g. Are we passing any parameters to it?
func = tcall->Code->GetDirectFunction();
if (func == NULL)
{
FCompileContext ctx(tcall->ActorClass);
tcall->Code = tcall->Code->Resolve(ctx);
// We don't know the return type in advance for anonymous functions.
FCompileContext ctx(tcall->ActorClass, nullptr);
tcall->Code = tcall->Code->Resolve(ctx);
tcall->Proto = ctx.ReturnProto;
// Make sure resolving it didn't obliterate it.
if (tcall->Code != NULL)
// Make sure resolving it didn't obliterate it.
if (tcall->Code != nullptr)
{
// Can we call this function directly without wrapping it in an
// anonymous function? e.g. Are we passing any parameters to it?
func = tcall->Code->GetDirectFunction();
if (func == nullptr)
{
VMFunctionBuilder buildit;
assert(tcall->Proto != nullptr);
// Allocate registers used to pass parameters in.
// self, stateowner, state (all are pointers)
buildit.Registers[REGT_POINTER].Get(3);
@ -300,15 +305,7 @@ static void FinishThingdef()
// Generate prototype for this anonymous function
TArray<PType *> args(3);
SetImplicitArgs(&args, NULL, tcall->ActorClass, VARF_Method | VARF_Action);
if (tcall->Proto != NULL)
{
sfunc->Proto = NewPrototype(tcall->Proto->ReturnTypes, args);
}
else
{
TArray<PType *> norets(0);
sfunc->Proto = NewPrototype(norets, args);
}
sfunc->Proto = NewPrototype(tcall->Proto->ReturnTypes, args);
func = sfunc;
@ -321,11 +318,9 @@ static void FinishThingdef()
codesize += sfunc->CodeSize;
}
}
}
if (tcall->Code != NULL)
{
delete tcall->Code;
tcall->Code = NULL;
tcall->Code = nullptr;
for (int k = 0; k < tcall->NumStates; ++k)
{
tcall->ActorClass->OwnedStates[tcall->FirstState + k].SetAction(func);