Add FxVMFunctionCall class
- This replaces the general extensibility that had existed formerly in thingdef_function.cpp. Parameter parsing for function calls is shared with state parameter parsing. Functions are defined exactly in the same way as action functions, but without the 'action' keyword.
This commit is contained in:
parent
9e3ed70021
commit
c6c2b21901
6 changed files with 243 additions and 97 deletions
|
|
@ -326,99 +326,7 @@ do_stop:
|
|||
if (afd != NULL)
|
||||
{
|
||||
tcall->Function = afd->Variants[0].Implementation;
|
||||
const TArray<PType *> ¶ms = afd->Variants[0].Proto->ArgumentTypes;
|
||||
const TArray<DWORD> ¶mflags = afd->Variants[0].ArgFlags;
|
||||
int numparams = (int)params.Size();
|
||||
int pnum = 0;
|
||||
if (afd->Flags & VARF_Method)
|
||||
{
|
||||
numparams--;
|
||||
pnum++;
|
||||
}
|
||||
if (afd->Flags & VARF_Action)
|
||||
{
|
||||
numparams -= 2;
|
||||
pnum += 2;
|
||||
}
|
||||
if (numparams > 0)
|
||||
{
|
||||
int v;
|
||||
|
||||
if (!(paramflags[pnum] & VARF_Optional))
|
||||
{
|
||||
sc.MustGetStringName("(");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!sc.CheckString("("))
|
||||
{
|
||||
goto endofstate;
|
||||
}
|
||||
}
|
||||
|
||||
while (numparams > 0)
|
||||
{
|
||||
FxExpression *x;
|
||||
if (params[pnum] == TypeState && sc.CheckNumber())
|
||||
{
|
||||
// Special case: State label as an offset
|
||||
if (sc.Number > 0 && statestring.Len() > 1)
|
||||
{
|
||||
sc.ScriptError("You cannot use state jumps commands with a jump offset on multistate definitions\n");
|
||||
}
|
||||
|
||||
v = sc.Number;
|
||||
if (v<0)
|
||||
{
|
||||
sc.ScriptError("Negative jump offsets are not allowed");
|
||||
}
|
||||
|
||||
if (v > 0)
|
||||
{
|
||||
x = new FxStateByIndex(bag.statedef.GetStateCount() + v, sc);
|
||||
}
|
||||
else
|
||||
{
|
||||
x = new FxConstant((FState*)NULL, sc);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use the generic parameter parser for everything else
|
||||
x = ParseParameter(sc, bag.Info, params[pnum], false);
|
||||
}
|
||||
tcall->Parameters.Push(new FxParameter(x));
|
||||
pnum++;
|
||||
numparams--;
|
||||
if (numparams > 0)
|
||||
{
|
||||
if (params[pnum] == NULL)
|
||||
{ // varargs function
|
||||
if (sc.CheckString(")"))
|
||||
{
|
||||
goto endofstate;
|
||||
}
|
||||
pnum--;
|
||||
numparams++;
|
||||
}
|
||||
else if ((paramflags[pnum] & VARF_Optional) && sc.CheckString(")"))
|
||||
{
|
||||
goto endofstate;
|
||||
}
|
||||
sc.MustGetStringName (",");
|
||||
}
|
||||
}
|
||||
sc.MustGetStringName(")");
|
||||
}
|
||||
else
|
||||
{
|
||||
sc.MustGetString();
|
||||
if (sc.Compare("("))
|
||||
{
|
||||
sc.ScriptError("You cannot pass parameters to '%s'\n",sc.String);
|
||||
}
|
||||
sc.UnGet();
|
||||
}
|
||||
ParseFunctionParameters(sc, bag.Info, tcall->Parameters, afd, statestring, &bag.statedef);
|
||||
goto endofstate;
|
||||
}
|
||||
sc.ScriptError("Invalid state parameter %s\n", sc.String);
|
||||
|
|
@ -448,3 +356,111 @@ endofstate:
|
|||
sc.SetEscape(true); // re-enable escape sequences
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ParseFunctionParameters
|
||||
//
|
||||
// Parses the parameters for a VM function. Called by both ParseStates
|
||||
// (which will set statestring and statedef) and by ParseExpression0 (which
|
||||
// will not set them). The first token returned by the scanner when entering
|
||||
// this function should be '('.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void ParseFunctionParameters(FScanner &sc, PClassActor *cls, TArray<FxExpression *> &out_params,
|
||||
PFunction *afd, FString statestring, FStateDefinitions *statedef)
|
||||
{
|
||||
const TArray<PType *> ¶ms = afd->Variants[0].Proto->ArgumentTypes;
|
||||
const TArray<DWORD> ¶mflags = afd->Variants[0].ArgFlags;
|
||||
int numparams = (int)params.Size();
|
||||
int pnum = 0;
|
||||
if (afd->Flags & VARF_Method)
|
||||
{
|
||||
numparams--;
|
||||
pnum++;
|
||||
}
|
||||
if (afd->Flags & VARF_Action)
|
||||
{
|
||||
numparams -= 2;
|
||||
pnum += 2;
|
||||
}
|
||||
if (numparams > 0)
|
||||
{
|
||||
int v;
|
||||
|
||||
if (!(paramflags[pnum] & VARF_Optional))
|
||||
{
|
||||
sc.MustGetStringName("(");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!sc.CheckString("("))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
while (numparams > 0)
|
||||
{
|
||||
FxExpression *x;
|
||||
if (statedef != NULL && params[pnum] == TypeState && sc.CheckNumber())
|
||||
{
|
||||
// Special case: State label as an offset
|
||||
if (sc.Number > 0 && statestring.Len() > 1)
|
||||
{
|
||||
sc.ScriptError("You cannot use state jumps commands with a jump offset on multistate definitions\n");
|
||||
}
|
||||
|
||||
v = sc.Number;
|
||||
if (v<0)
|
||||
{
|
||||
sc.ScriptError("Negative jump offsets are not allowed");
|
||||
}
|
||||
|
||||
if (v > 0)
|
||||
{
|
||||
x = new FxStateByIndex(statedef->GetStateCount() + v, sc);
|
||||
}
|
||||
else
|
||||
{
|
||||
x = new FxConstant((FState*)NULL, sc);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use the generic parameter parser for everything else
|
||||
x = ParseParameter(sc, cls, params[pnum], false);
|
||||
}
|
||||
out_params.Push(new FxParameter(x));
|
||||
pnum++;
|
||||
numparams--;
|
||||
if (numparams > 0)
|
||||
{
|
||||
if (params[pnum] == NULL)
|
||||
{ // varargs function
|
||||
if (sc.CheckString(")"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
pnum--;
|
||||
numparams++;
|
||||
}
|
||||
else if ((paramflags[pnum] & VARF_Optional) && sc.CheckString(")"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
sc.MustGetStringName (",");
|
||||
}
|
||||
}
|
||||
sc.MustGetStringName(")");
|
||||
}
|
||||
else
|
||||
{
|
||||
sc.MustGetString();
|
||||
if (sc.Compare("("))
|
||||
{
|
||||
sc.ScriptError("You cannot pass parameters to '%s'\n", afd->SymbolName.GetChars());
|
||||
}
|
||||
sc.UnGet();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue