mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-28 06:53:40 +00:00
Cleanup parsing of DECORATE intrinsics
- Split specific parsing for each intrinsic out of ParseExpression0 and into their own functions. - Instead of reserving keywords for intrinsics, identify them by name within TK_Identifier's handling.
This commit is contained in:
parent
01bdd8a7da
commit
326907f6ab
6 changed files with 155 additions and 167 deletions
|
@ -280,7 +280,10 @@ xx(Cast) // 'damage type' for the cast call
|
||||||
|
|
||||||
// Special names for thingdef_exp.cpp
|
// Special names for thingdef_exp.cpp
|
||||||
xx(Random)
|
xx(Random)
|
||||||
|
xx(FRandom)
|
||||||
xx(Random2)
|
xx(Random2)
|
||||||
|
xx(RandomPick)
|
||||||
|
xx(FRandomPick)
|
||||||
xx(Cos)
|
xx(Cos)
|
||||||
xx(Sin)
|
xx(Sin)
|
||||||
xx(Alpha)
|
xx(Alpha)
|
||||||
|
|
|
@ -185,14 +185,6 @@ std2:
|
||||||
'#include' { RET(TK_Include); }
|
'#include' { RET(TK_Include); }
|
||||||
'fixed_t' { RET(TK_Fixed_t); }
|
'fixed_t' { RET(TK_Fixed_t); }
|
||||||
'angle_t' { RET(TK_Angle_t); }
|
'angle_t' { RET(TK_Angle_t); }
|
||||||
'abs' { RET(TK_Abs); }
|
|
||||||
'random' { RET(TK_Random); }
|
|
||||||
'random2' { RET(TK_Random2); }
|
|
||||||
'frandom' { RET(TK_FRandom); }
|
|
||||||
'randompick' { RET(TK_RandomPick); }
|
|
||||||
'frandompick' { RET(TK_FRandomPick); }
|
|
||||||
'min' { RET(TK_Min); }
|
|
||||||
'max' { RET(TK_Max); }
|
|
||||||
|
|
||||||
L (L|D)* { RET(TK_Identifier); }
|
L (L|D)* { RET(TK_Identifier); }
|
||||||
|
|
||||||
|
|
|
@ -113,10 +113,6 @@ xx(TK_Stop, "'stop'")
|
||||||
xx(TK_Include, "'include'")
|
xx(TK_Include, "'include'")
|
||||||
xx(TK_Fixed_t, "'fixed_t'")
|
xx(TK_Fixed_t, "'fixed_t'")
|
||||||
xx(TK_Angle_t, "'angle_t'")
|
xx(TK_Angle_t, "'angle_t'")
|
||||||
xx(TK_Abs, "'abs'")
|
|
||||||
xx(TK_Random, "'random'")
|
|
||||||
xx(TK_Random2, "'random2'")
|
|
||||||
xx(TK_FRandom, "'frandom'")
|
|
||||||
|
|
||||||
xx(TK_Is, "'is'")
|
xx(TK_Is, "'is'")
|
||||||
xx(TK_Replaces, "'replaces'")
|
xx(TK_Replaces, "'replaces'")
|
||||||
|
@ -126,10 +122,6 @@ xx(TK_Array, "'array'")
|
||||||
xx(TK_In, "'in'")
|
xx(TK_In, "'in'")
|
||||||
xx(TK_SizeOf, "'sizeof'")
|
xx(TK_SizeOf, "'sizeof'")
|
||||||
xx(TK_AlignOf, "'alignof'")
|
xx(TK_AlignOf, "'alignof'")
|
||||||
xx(TK_RandomPick, "'randompick'")
|
|
||||||
xx(TK_FRandomPick, "'frandompick'")
|
|
||||||
xx(TK_Min, "'min'")
|
|
||||||
xx(TK_Max, "'max'")
|
|
||||||
xx(TK_States, "'states'")
|
xx(TK_States, "'states'")
|
||||||
xx(TK_Loop, "'loop'")
|
xx(TK_Loop, "'loop'")
|
||||||
xx(TK_Fail, "'fail'")
|
xx(TK_Fail, "'fail'")
|
||||||
|
|
|
@ -52,6 +52,12 @@
|
||||||
|
|
||||||
FRandom pr_exrandom ("EX_Random");
|
FRandom pr_exrandom ("EX_Random");
|
||||||
|
|
||||||
|
static FxExpression *ParseRandom(FScanner &sc, FName identifier, PClassActor *cls);
|
||||||
|
static FxExpression *ParseRandomPick(FScanner &sc, FName identifier, PClassActor *cls);
|
||||||
|
static FxExpression *ParseRandom2(FScanner &sc, PClassActor *cls);
|
||||||
|
static FxExpression *ParseAbs(FScanner &sc, PClassActor *cls);
|
||||||
|
static FxExpression *ParseMinMax(FScanner &sc, FName identifier, PClassActor *cls);
|
||||||
|
|
||||||
//
|
//
|
||||||
// ParseExpression
|
// ParseExpression
|
||||||
// [GRB] Parses an expression and stores it into Expression array
|
// [GRB] Parses an expression and stores it into Expression array
|
||||||
|
@ -349,161 +355,63 @@ static FxExpression *ParseExpression0 (FScanner &sc, PClassActor *cls)
|
||||||
// a cheap way to get them working when people use "name" instead of 'name'.
|
// a cheap way to get them working when people use "name" instead of 'name'.
|
||||||
return new FxConstant(FName(sc.String), scpos);
|
return new FxConstant(FName(sc.String), scpos);
|
||||||
}
|
}
|
||||||
else if (sc.CheckToken(TK_Min) || sc.CheckToken(TK_Max))
|
|
||||||
{
|
|
||||||
int type = sc.TokenType;
|
|
||||||
TArray<FxExpression*> list;
|
|
||||||
sc.MustGetToken('(');
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
FxExpression *expr = ParseExpressionM(sc, cls);
|
|
||||||
list.Push(expr);
|
|
||||||
if (sc.CheckToken(')'))
|
|
||||||
break;
|
|
||||||
sc.MustGetToken(',');
|
|
||||||
}
|
|
||||||
return new FxMinMax(list, type, sc);
|
|
||||||
}
|
|
||||||
else if (sc.CheckToken(TK_Random))
|
|
||||||
{
|
|
||||||
FRandom *rng;
|
|
||||||
|
|
||||||
if (sc.CheckToken('['))
|
|
||||||
{
|
|
||||||
sc.MustGetToken(TK_Identifier);
|
|
||||||
rng = FRandom::StaticFindRNG(sc.String);
|
|
||||||
sc.MustGetToken(']');
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rng = &pr_exrandom;
|
|
||||||
}
|
|
||||||
sc.MustGetToken('(');
|
|
||||||
|
|
||||||
FxExpression *min = ParseExpressionM (sc, cls);
|
|
||||||
sc.MustGetToken(',');
|
|
||||||
FxExpression *max = ParseExpressionM (sc, cls);
|
|
||||||
sc.MustGetToken(')');
|
|
||||||
|
|
||||||
return new FxRandom(rng, min, max, sc);
|
|
||||||
}
|
|
||||||
else if (sc.CheckToken(TK_RandomPick) || sc.CheckToken(TK_FRandomPick))
|
|
||||||
{
|
|
||||||
bool floaty = sc.TokenType == TK_FRandomPick;
|
|
||||||
FRandom *rng;
|
|
||||||
TArray<FxExpression*> list;
|
|
||||||
list.Clear();
|
|
||||||
int index = 0;
|
|
||||||
|
|
||||||
if (sc.CheckToken('['))
|
|
||||||
{
|
|
||||||
sc.MustGetToken(TK_Identifier);
|
|
||||||
rng = FRandom::StaticFindRNG(sc.String);
|
|
||||||
sc.MustGetToken(']');
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rng = &pr_exrandom;
|
|
||||||
}
|
|
||||||
sc.MustGetToken('(');
|
|
||||||
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
FxExpression *expr = ParseExpressionM(sc, cls);
|
|
||||||
list.Push(expr);
|
|
||||||
if (sc.CheckToken(')'))
|
|
||||||
break;
|
|
||||||
sc.MustGetToken(',');
|
|
||||||
}
|
|
||||||
return new FxRandomPick(rng, list, floaty, sc);
|
|
||||||
}
|
|
||||||
else if (sc.CheckToken(TK_FRandom))
|
|
||||||
{
|
|
||||||
FRandom *rng;
|
|
||||||
|
|
||||||
if (sc.CheckToken('['))
|
|
||||||
{
|
|
||||||
sc.MustGetToken(TK_Identifier);
|
|
||||||
rng = FRandom::StaticFindRNG(sc.String);
|
|
||||||
sc.MustGetToken(']');
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rng = &pr_exrandom;
|
|
||||||
}
|
|
||||||
sc.MustGetToken('(');
|
|
||||||
|
|
||||||
FxExpression *min = ParseExpressionM (sc, cls);
|
|
||||||
sc.MustGetToken(',');
|
|
||||||
FxExpression *max = ParseExpressionM (sc, cls);
|
|
||||||
sc.MustGetToken(')');
|
|
||||||
|
|
||||||
return new FxFRandom(rng, min, max, sc);
|
|
||||||
}
|
|
||||||
else if (sc.CheckToken(TK_Random2))
|
|
||||||
{
|
|
||||||
FRandom *rng;
|
|
||||||
|
|
||||||
if (sc.CheckToken('['))
|
|
||||||
{
|
|
||||||
sc.MustGetToken(TK_Identifier);
|
|
||||||
rng = FRandom::StaticFindRNG(sc.String);
|
|
||||||
sc.MustGetToken(']');
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rng = &pr_exrandom;
|
|
||||||
}
|
|
||||||
|
|
||||||
sc.MustGetToken('(');
|
|
||||||
|
|
||||||
FxExpression *mask = NULL;
|
|
||||||
|
|
||||||
if (!sc.CheckToken(')'))
|
|
||||||
{
|
|
||||||
mask = ParseExpressionM(sc, cls);
|
|
||||||
sc.MustGetToken(')');
|
|
||||||
}
|
|
||||||
return new FxRandom2(rng, mask, sc);
|
|
||||||
}
|
|
||||||
else if (sc.CheckToken(TK_Abs))
|
|
||||||
{
|
|
||||||
sc.MustGetToken('(');
|
|
||||||
FxExpression *x = ParseExpressionM (sc, cls);
|
|
||||||
sc.MustGetToken(')');
|
|
||||||
return new FxAbs(x);
|
|
||||||
}
|
|
||||||
else if (sc.CheckToken(TK_Identifier))
|
else if (sc.CheckToken(TK_Identifier))
|
||||||
{
|
{
|
||||||
FName identifier = FName(sc.String);
|
FName identifier = FName(sc.String);
|
||||||
|
FArgumentList *args;
|
||||||
|
PFunction *func;
|
||||||
|
|
||||||
|
switch (identifier)
|
||||||
|
{
|
||||||
|
case NAME_Random:
|
||||||
|
case NAME_FRandom:
|
||||||
|
return ParseRandom(sc, identifier, cls);
|
||||||
|
case NAME_RandomPick:
|
||||||
|
case NAME_FRandomPick:
|
||||||
|
return ParseRandomPick(sc, identifier, cls);
|
||||||
|
case NAME_Random2:
|
||||||
|
return ParseRandom2(sc, cls);
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (sc.CheckToken('('))
|
if (sc.CheckToken('('))
|
||||||
{
|
{
|
||||||
FArgumentList *args = new FArgumentList;
|
switch (identifier)
|
||||||
PFunction *func = dyn_cast<PFunction>(cls->Symbols.FindSymbol(identifier, true));
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
// There is an action function ACS_NamedExecuteWithResult which must be ignored here for this to work.
|
case NAME_Min:
|
||||||
if (func != NULL && identifier != NAME_ACS_NamedExecuteWithResult)
|
case NAME_Max:
|
||||||
|
return ParseMinMax(sc, identifier, cls);
|
||||||
|
case NAME_Abs:
|
||||||
|
return ParseAbs(sc, cls);
|
||||||
|
default:
|
||||||
|
args = new FArgumentList;
|
||||||
|
func = dyn_cast<PFunction>(cls->Symbols.FindSymbol(identifier, true));
|
||||||
|
try
|
||||||
{
|
{
|
||||||
sc.UnGet();
|
// There is an action function ACS_NamedExecuteWithResult which must be ignored here for this to work.
|
||||||
ParseFunctionParameters(sc, cls, *args, func, "", NULL);
|
if (func != NULL && identifier != NAME_ACS_NamedExecuteWithResult)
|
||||||
return new FxVMFunctionCall(func, args, sc);
|
|
||||||
}
|
|
||||||
else if (!sc.CheckToken(')'))
|
|
||||||
{
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
args->Push(ParseExpressionM (sc, cls));
|
sc.UnGet();
|
||||||
|
ParseFunctionParameters(sc, cls, *args, func, "", NULL);
|
||||||
|
return new FxVMFunctionCall(func, args, sc);
|
||||||
}
|
}
|
||||||
while (sc.CheckToken(','));
|
else if (!sc.CheckToken(')'))
|
||||||
sc.MustGetToken(')');
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
args->Push(ParseExpressionM (sc, cls));
|
||||||
|
}
|
||||||
|
while (sc.CheckToken(','));
|
||||||
|
sc.MustGetToken(')');
|
||||||
|
}
|
||||||
|
return new FxFunctionCall(NULL, identifier, args, sc);
|
||||||
}
|
}
|
||||||
return new FxFunctionCall(NULL, identifier, args, sc);
|
catch (...)
|
||||||
}
|
{
|
||||||
catch (...)
|
delete args;
|
||||||
{
|
throw;
|
||||||
delete args;
|
}
|
||||||
throw;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -519,4 +427,97 @@ static FxExpression *ParseExpression0 (FScanner &sc, PClassActor *cls)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static FRandom *ParseRNG(FScanner &sc)
|
||||||
|
{
|
||||||
|
FRandom *rng;
|
||||||
|
|
||||||
|
if (sc.CheckToken('['))
|
||||||
|
{
|
||||||
|
sc.MustGetToken(TK_Identifier);
|
||||||
|
rng = FRandom::StaticFindRNG(sc.String);
|
||||||
|
sc.MustGetToken(']');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rng = &pr_exrandom;
|
||||||
|
}
|
||||||
|
return rng;
|
||||||
|
}
|
||||||
|
|
||||||
|
static FxExpression *ParseRandom(FScanner &sc, FName identifier, PClassActor *cls)
|
||||||
|
{
|
||||||
|
FRandom *rng = ParseRNG(sc);
|
||||||
|
|
||||||
|
sc.MustGetToken('(');
|
||||||
|
FxExpression *min = ParseExpressionM (sc, cls);
|
||||||
|
sc.MustGetToken(',');
|
||||||
|
FxExpression *max = ParseExpressionM (sc, cls);
|
||||||
|
sc.MustGetToken(')');
|
||||||
|
|
||||||
|
if (identifier == NAME_Random)
|
||||||
|
{
|
||||||
|
return new FxRandom(rng, min, max, sc);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new FxFRandom(rng, min, max, sc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static FxExpression *ParseRandomPick(FScanner &sc, FName identifier, PClassActor *cls)
|
||||||
|
{
|
||||||
|
bool floaty = identifier == NAME_FRandomPick;
|
||||||
|
FRandom *rng;
|
||||||
|
TArray<FxExpression*> list;
|
||||||
|
list.Clear();
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
rng = ParseRNG(sc);
|
||||||
|
sc.MustGetToken('(');
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
FxExpression *expr = ParseExpressionM(sc, cls);
|
||||||
|
list.Push(expr);
|
||||||
|
if (sc.CheckToken(')'))
|
||||||
|
break;
|
||||||
|
sc.MustGetToken(',');
|
||||||
|
}
|
||||||
|
return new FxRandomPick(rng, list, floaty, sc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static FxExpression *ParseRandom2(FScanner &sc, PClassActor *cls)
|
||||||
|
{
|
||||||
|
FRandom *rng = ParseRNG(sc);
|
||||||
|
FxExpression *mask = NULL;
|
||||||
|
|
||||||
|
sc.MustGetToken('(');
|
||||||
|
|
||||||
|
if (!sc.CheckToken(')'))
|
||||||
|
{
|
||||||
|
mask = ParseExpressionM(sc, cls);
|
||||||
|
sc.MustGetToken(')');
|
||||||
|
}
|
||||||
|
return new FxRandom2(rng, mask, sc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static FxExpression *ParseAbs(FScanner &sc, PClassActor *cls)
|
||||||
|
{
|
||||||
|
FxExpression *x = ParseExpressionM (sc, cls);
|
||||||
|
sc.MustGetToken(')');
|
||||||
|
return new FxAbs(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
static FxExpression *ParseMinMax(FScanner &sc, FName identifier, PClassActor *cls)
|
||||||
|
{
|
||||||
|
TArray<FxExpression*> list;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
FxExpression *expr = ParseExpressionM(sc, cls);
|
||||||
|
list.Push(expr);
|
||||||
|
if (sc.CheckToken(')'))
|
||||||
|
break;
|
||||||
|
sc.MustGetToken(',');
|
||||||
|
}
|
||||||
|
return new FxMinMax(list, identifier, sc);
|
||||||
|
}
|
||||||
|
|
|
@ -632,10 +632,10 @@ public:
|
||||||
class FxMinMax : public FxExpression
|
class FxMinMax : public FxExpression
|
||||||
{
|
{
|
||||||
TDeletingArray<FxExpression *> choices;
|
TDeletingArray<FxExpression *> choices;
|
||||||
int Type;
|
FName Type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FxMinMax(TArray<FxExpression*> &expr, int type, const FScriptPosition &pos);
|
FxMinMax(TArray<FxExpression*> &expr, FName type, const FScriptPosition &pos);
|
||||||
FxExpression *Resolve(FCompileContext&);
|
FxExpression *Resolve(FCompileContext&);
|
||||||
|
|
||||||
ExpEmit Emit(VMFunctionBuilder *build);
|
ExpEmit Emit(VMFunctionBuilder *build);
|
||||||
|
|
|
@ -2043,11 +2043,11 @@ ExpEmit FxAbs::Emit(VMFunctionBuilder *build)
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
FxMinMax::FxMinMax(TArray<FxExpression*> &expr, int type, const FScriptPosition &pos)
|
FxMinMax::FxMinMax(TArray<FxExpression*> &expr, FName type, const FScriptPosition &pos)
|
||||||
: FxExpression(pos), Type(type)
|
: FxExpression(pos), Type(type)
|
||||||
{
|
{
|
||||||
assert(expr.Size() > 0);
|
assert(expr.Size() > 0);
|
||||||
assert(type == TK_Min || type == TK_Max);
|
assert(type == NAME_Min || type == NAME_Max);
|
||||||
|
|
||||||
ValueType = VAL_Unknown;
|
ValueType = VAL_Unknown;
|
||||||
choices.Resize(expr.Size());
|
choices.Resize(expr.Size());
|
||||||
|
@ -2132,7 +2132,7 @@ FxExpression *FxMinMax::Resolve(FCompileContext &ctx)
|
||||||
{
|
{
|
||||||
ExpVal value = static_cast<FxConstant *>(choices[j])->GetValue();
|
ExpVal value = static_cast<FxConstant *>(choices[j])->GetValue();
|
||||||
assert(value.Type == ValueType.Type);
|
assert(value.Type == ValueType.Type);
|
||||||
if (Type == TK_Min)
|
if (Type == NAME_Min)
|
||||||
{
|
{
|
||||||
if (value.Type == VAL_Float)
|
if (value.Type == VAL_Float)
|
||||||
{
|
{
|
||||||
|
@ -2213,7 +2213,7 @@ ExpEmit FxMinMax::Emit(VMFunctionBuilder *build)
|
||||||
assert(OP_LEF_RK == OP_LEF_RR+1);
|
assert(OP_LEF_RK == OP_LEF_RR+1);
|
||||||
assert(OP_LE_RK == OP_LE_RR+1);
|
assert(OP_LE_RK == OP_LE_RR+1);
|
||||||
|
|
||||||
if (Type == TK_Min)
|
if (Type == NAME_Min)
|
||||||
{
|
{
|
||||||
opcode = ValueType.Type == VAL_Float ? OP_LEF_RR : OP_LE_RR;
|
opcode = ValueType.Type == VAL_Float ? OP_LEF_RR : OP_LE_RR;
|
||||||
opA = 1;
|
opA = 1;
|
||||||
|
|
Loading…
Reference in a new issue