Merge commit '8e0151b4c1b88eaf295042ea2d545a83b4b99acc' into scripting

Conflicts:
	src/sc_man_tokens.h
	src/thingdef/thingdef_exp.h
	src/thingdef/thingdef_expression.cpp

(Scripting branch update part 3)
This commit is contained in:
Christoph Oelckers 2015-04-28 10:59:50 +02:00
commit 6ebdf7396c
5 changed files with 39 additions and 12 deletions

View file

@ -186,6 +186,7 @@ std2:
'random2' { RET(TK_Random2); } 'random2' { RET(TK_Random2); }
'frandom' { RET(TK_FRandom); } 'frandom' { RET(TK_FRandom); }
'randompick' { RET(TK_RandomPick); } 'randompick' { RET(TK_RandomPick); }
'frandompick' { RET(TK_FRandomPick); }
L (L|D)* { RET(TK_Identifier); } L (L|D)* { RET(TK_Identifier); }

View file

@ -117,7 +117,7 @@ xx(TK_Abs, "'abs'")
xx(TK_Random, "'random'") xx(TK_Random, "'random'")
xx(TK_Random2, "'random2'") xx(TK_Random2, "'random2'")
xx(TK_FRandom, "'frandom'") xx(TK_FRandom, "'frandom'")
xx(TK_Pick, "'pick'")
xx(TK_Is, "'is'") xx(TK_Is, "'is'")
xx(TK_Replaces, "'replaces'") xx(TK_Replaces, "'replaces'")
xx(TK_Vector, "'vector'") xx(TK_Vector, "'vector'")
@ -126,7 +126,8 @@ 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_RandomPick, "'randompick'")
xx(TK_FRandomPick, "'frandompick'")
xx(TK_States, "'states'") xx(TK_States, "'states'")
xx(TK_Loop, "'loop'") xx(TK_Loop, "'loop'")
xx(TK_Fail, "'fail'") xx(TK_Fail, "'fail'")

View file

@ -369,8 +369,9 @@ static FxExpression *ParseExpression0 (FScanner &sc, PClassActor *cls)
return new FxRandom(rng, min, max, sc); return new FxRandom(rng, min, max, sc);
} }
else if (sc.CheckToken(TK_RandomPick)) else if (sc.CheckToken(TK_RandomPick) || sc.CheckToken(TK_FRandomPick))
{ {
bool floaty = sc.TokenType == TK_FRandomPick;
FRandom *rng; FRandom *rng;
TArray<FxExpression*> list; TArray<FxExpression*> list;
list.Clear(); list.Clear();
@ -396,7 +397,7 @@ static FxExpression *ParseExpression0 (FScanner &sc, PClassActor *cls)
break; break;
sc.MustGetToken(','); sc.MustGetToken(',');
} }
return new FxRandomPick(rng, list, sc); return new FxRandomPick(rng, list, floaty, sc);
} }
else if (sc.CheckToken(TK_FRandom)) else if (sc.CheckToken(TK_FRandom))
{ {

View file

@ -645,7 +645,7 @@ protected:
public: public:
FxRandomPick(FRandom *, TArray<FxExpression*> &expr, const FScriptPosition &pos); FxRandomPick(FRandom *, TArray<FxExpression*> &expr, bool floaty, const FScriptPosition &pos);
~FxRandomPick(); ~FxRandomPick();
FxExpression *Resolve(FCompileContext&); FxExpression *Resolve(FCompileContext&);

View file

@ -2069,17 +2069,25 @@ ExpEmit FxRandom::Emit(VMFunctionBuilder *build)
// //
// //
//========================================================================== //==========================================================================
FxRandomPick::FxRandomPick(FRandom *r, TArray<FxExpression*> &expr, const FScriptPosition &pos) FxRandomPick::FxRandomPick(FRandom *r, TArray<FxExpression*> &expr, bool floaty, const FScriptPosition &pos)
: FxExpression(pos) : FxExpression(pos)
{ {
assert(expr.Size() > 0); assert(expr.Size() > 0);
choices.Resize(expr.Size()); choices.Resize(expr.Size());
for (unsigned int index = 0; index < expr.Size(); index++) for (unsigned int index = 0; index < expr.Size(); index++)
{ {
choices[index] = new FxIntCast(expr[index]); if (floaty)
{
choices[index] = new FxFloatCast(expr[index]);
}
else
{
choices[index] = new FxIntCast(expr[index]);
}
} }
rng = r; rng = r;
ValueType = VAL_Int; ValueType = floaty ? VAL_Float : VAL_Int;
} }
//========================================================================== //==========================================================================
@ -2132,6 +2140,7 @@ FxExpression *FxRandomPick::Resolve(FCompileContext &ctx)
ExpEmit FxRandomPick::Emit(VMFunctionBuilder *build) ExpEmit FxRandomPick::Emit(VMFunctionBuilder *build)
{ {
#pragma message("FxRandomPick::Emit: Floating point part needs reviewing!")
unsigned i; unsigned i;
assert(choices.Size() > 0); assert(choices.Size() > 0);
@ -2171,8 +2180,16 @@ ExpEmit FxRandomPick::Emit(VMFunctionBuilder *build)
build->BackpatchToHere(jumptable + i); build->BackpatchToHere(jumptable + i);
if (choices[i]->isConstant()) if (choices[i]->isConstant())
{ {
int val = static_cast<FxConstant *>(choices[i])->GetValue().GetInt(); if (ValueType == VAL_Int)
build->EmitLoadInt(resultreg.RegNum, val); {
int val = static_cast<FxConstant *>(choices[i])->GetValue().GetInt();
build->EmitLoadInt(resultreg.RegNum, val);
}
else
{
double val = static_cast<FxConstant *>(choices[i])->GetValue().GetFloat();
build->Emit(OP_PARAM, 0, REGT_FLOAT | REGT_KONST, build->GetConstantFloat(val));
}
} }
else else
{ {
@ -2182,7 +2199,14 @@ ExpEmit FxRandomPick::Emit(VMFunctionBuilder *build)
// was expected. Copy it to the one we wanted. // was expected. Copy it to the one we wanted.
resultreg.Reuse(build); // This is really just for the assert in Reuse() resultreg.Reuse(build); // This is really just for the assert in Reuse()
build->Emit(OP_MOVE, resultreg.RegNum, casereg.RegNum, 0); if (ValueType == VAL_Int)
{
build->Emit(OP_MOVE, resultreg.RegNum, casereg.RegNum, 0);
}
else
{
build->Emit(OP_MOVEF, resultreg.RegNum, casereg.RegNum, 0);
}
resultreg.Free(build); resultreg.Free(build);
} }
// Free this register so the remaining cases can use it. // Free this register so the remaining cases can use it.
@ -2201,7 +2225,7 @@ ExpEmit FxRandomPick::Emit(VMFunctionBuilder *build)
build->BackpatchToHere(finishes[i]); build->BackpatchToHere(finishes[i]);
} }
// The result register needs to be in-use when we return. // The result register needs to be in-use when we return.
// It should have been freed earlier, so restore it's in-use flag. // It should have been freed earlier, so restore its in-use flag.
resultreg.Reuse(build); resultreg.Reuse(build);
return resultreg; return resultreg;
} }