Remove FxExpression::EvalExpression() entirely

- For the purposes of getting constant values from expressions, the only
  class where Resolve doesn't duplicate the functionality of
  EvalExpression was FxConstant. So, every other class has had its
  EvalExpression taken away, and FxConstant has had it renamed to GetValue.
This commit is contained in:
Randy Heit 2013-07-30 22:52:27 -05:00
parent c810b4d724
commit 58f088c1ab
3 changed files with 98 additions and 465 deletions

View file

@ -230,7 +230,6 @@ public:
virtual FxExpression *Resolve(FCompileContext &ctx); virtual FxExpression *Resolve(FCompileContext &ctx);
FxExpression *ResolveAsBoolean(FCompileContext &ctx); FxExpression *ResolveAsBoolean(FCompileContext &ctx);
virtual ExpVal EvalExpression();
virtual bool isConstant() const; virtual bool isConstant() const;
virtual void RequestAddress(); virtual void RequestAddress();
@ -377,7 +376,11 @@ public:
{ {
return true; return true;
} }
ExpVal EvalExpression();
ExpVal GetValue() const
{
return value;
}
ExpEmit Emit(VMFunctionBuilder *build); ExpEmit Emit(VMFunctionBuilder *build);
}; };
@ -398,7 +401,6 @@ public:
~FxIntCast(); ~FxIntCast();
FxExpression *Resolve(FCompileContext&); FxExpression *Resolve(FCompileContext&);
ExpVal EvalExpression();
ExpEmit Emit(VMFunctionBuilder *build); ExpEmit Emit(VMFunctionBuilder *build);
}; };
@ -412,7 +414,6 @@ public:
~FxFloatCast(); ~FxFloatCast();
FxExpression *Resolve(FCompileContext&); FxExpression *Resolve(FCompileContext&);
ExpVal EvalExpression();
ExpEmit Emit(VMFunctionBuilder *build); ExpEmit Emit(VMFunctionBuilder *build);
}; };
@ -448,7 +449,6 @@ public:
FxMinusSign(FxExpression*); FxMinusSign(FxExpression*);
~FxMinusSign(); ~FxMinusSign();
FxExpression *Resolve(FCompileContext&); FxExpression *Resolve(FCompileContext&);
ExpVal EvalExpression();
ExpEmit Emit(VMFunctionBuilder *build); ExpEmit Emit(VMFunctionBuilder *build);
}; };
@ -466,7 +466,6 @@ public:
FxUnaryNotBitwise(FxExpression*); FxUnaryNotBitwise(FxExpression*);
~FxUnaryNotBitwise(); ~FxUnaryNotBitwise();
FxExpression *Resolve(FCompileContext&); FxExpression *Resolve(FCompileContext&);
ExpVal EvalExpression();
ExpEmit Emit(VMFunctionBuilder *build); ExpEmit Emit(VMFunctionBuilder *build);
}; };
@ -484,7 +483,6 @@ public:
FxUnaryNotBoolean(FxExpression*); FxUnaryNotBoolean(FxExpression*);
~FxUnaryNotBoolean(); ~FxUnaryNotBoolean();
FxExpression *Resolve(FCompileContext&); FxExpression *Resolve(FCompileContext&);
ExpVal EvalExpression();
ExpEmit Emit(VMFunctionBuilder *build); ExpEmit Emit(VMFunctionBuilder *build);
}; };
@ -519,7 +517,6 @@ public:
FxAddSub(int, FxExpression*, FxExpression*); FxAddSub(int, FxExpression*, FxExpression*);
FxExpression *Resolve(FCompileContext&); FxExpression *Resolve(FCompileContext&);
ExpVal EvalExpression();
ExpEmit Emit(VMFunctionBuilder *build); ExpEmit Emit(VMFunctionBuilder *build);
}; };
@ -535,7 +532,6 @@ public:
FxMulDiv(int, FxExpression*, FxExpression*); FxMulDiv(int, FxExpression*, FxExpression*);
FxExpression *Resolve(FCompileContext&); FxExpression *Resolve(FCompileContext&);
ExpVal EvalExpression();
ExpEmit Emit(VMFunctionBuilder *build); ExpEmit Emit(VMFunctionBuilder *build);
}; };
@ -551,7 +547,6 @@ public:
FxCompareRel(int, FxExpression*, FxExpression*); FxCompareRel(int, FxExpression*, FxExpression*);
FxExpression *Resolve(FCompileContext&); FxExpression *Resolve(FCompileContext&);
ExpVal EvalExpression();
ExpEmit Emit(VMFunctionBuilder *build); ExpEmit Emit(VMFunctionBuilder *build);
}; };
@ -567,7 +562,6 @@ public:
FxCompareEq(int, FxExpression*, FxExpression*); FxCompareEq(int, FxExpression*, FxExpression*);
FxExpression *Resolve(FCompileContext&); FxExpression *Resolve(FCompileContext&);
ExpVal EvalExpression();
ExpEmit Emit(VMFunctionBuilder *build); ExpEmit Emit(VMFunctionBuilder *build);
}; };
@ -583,7 +577,6 @@ public:
FxBinaryInt(int, FxExpression*, FxExpression*); FxBinaryInt(int, FxExpression*, FxExpression*);
FxExpression *Resolve(FCompileContext&); FxExpression *Resolve(FCompileContext&);
ExpVal EvalExpression();
ExpEmit Emit(VMFunctionBuilder *build); ExpEmit Emit(VMFunctionBuilder *build);
}; };
@ -604,7 +597,6 @@ public:
~FxBinaryLogical(); ~FxBinaryLogical();
FxExpression *Resolve(FCompileContext&); FxExpression *Resolve(FCompileContext&);
ExpVal EvalExpression();
ExpEmit Emit(VMFunctionBuilder *build); ExpEmit Emit(VMFunctionBuilder *build);
}; };
@ -625,7 +617,6 @@ public:
~FxConditional(); ~FxConditional();
FxExpression *Resolve(FCompileContext&); FxExpression *Resolve(FCompileContext&);
ExpVal EvalExpression();
ExpEmit Emit(VMFunctionBuilder *build); ExpEmit Emit(VMFunctionBuilder *build);
}; };
@ -645,7 +636,6 @@ public:
~FxAbs(); ~FxAbs();
FxExpression *Resolve(FCompileContext&); FxExpression *Resolve(FCompileContext&);
ExpVal EvalExpression();
ExpEmit Emit(VMFunctionBuilder *build); ExpEmit Emit(VMFunctionBuilder *build);
}; };
@ -719,7 +709,6 @@ public:
FxGlobalVariable(PSymbolVariable*, const FScriptPosition&); FxGlobalVariable(PSymbolVariable*, const FScriptPosition&);
FxExpression *Resolve(FCompileContext&); FxExpression *Resolve(FCompileContext&);
void RequestAddress(); void RequestAddress();
ExpVal EvalExpression();
}; };
//========================================================================== //==========================================================================
@ -739,7 +728,6 @@ public:
~FxClassMember(); ~FxClassMember();
FxExpression *Resolve(FCompileContext&); FxExpression *Resolve(FCompileContext&);
void RequestAddress(); void RequestAddress();
ExpVal EvalExpression();
ExpEmit Emit(VMFunctionBuilder *build); ExpEmit Emit(VMFunctionBuilder *build);
}; };
@ -774,7 +762,6 @@ public:
~FxArrayElement(); ~FxArrayElement();
FxExpression *Resolve(FCompileContext&); FxExpression *Resolve(FCompileContext&);
//void RequestAddress(); //void RequestAddress();
ExpVal EvalExpression();
ExpEmit Emit(VMFunctionBuilder *build); ExpEmit Emit(VMFunctionBuilder *build);
}; };
@ -837,7 +824,6 @@ public:
FxGlobalFunctionCall(FName fname, FArgumentList *args, const FScriptPosition &pos); FxGlobalFunctionCall(FName fname, FArgumentList *args, const FScriptPosition &pos);
~FxGlobalFunctionCall(); ~FxGlobalFunctionCall();
FxExpression *Resolve(FCompileContext&); FxExpression *Resolve(FCompileContext&);
ExpVal EvalExpression();
ExpEmit Emit(VMFunctionBuilder *build); ExpEmit Emit(VMFunctionBuilder *build);
}; };
@ -858,7 +844,6 @@ public:
FxClassTypeCast(const PClass *dtype, FxExpression *x); FxClassTypeCast(const PClass *dtype, FxExpression *x);
~FxClassTypeCast(); ~FxClassTypeCast();
FxExpression *Resolve(FCompileContext&); FxExpression *Resolve(FCompileContext&);
ExpVal EvalExpression();
ExpEmit Emit(VMFunctionBuilder *build); ExpEmit Emit(VMFunctionBuilder *build);
}; };
@ -895,7 +880,6 @@ public:
FxMultiNameState(const char *statestring, const FScriptPosition &pos); FxMultiNameState(const char *statestring, const FScriptPosition &pos);
FxExpression *Resolve(FCompileContext&); FxExpression *Resolve(FCompileContext&);
ExpVal EvalExpression();
ExpEmit Emit(VMFunctionBuilder *build); ExpEmit Emit(VMFunctionBuilder *build);
}; };

View file

@ -198,22 +198,6 @@ static ExpVal GetVariableValue (void *address, FExpressionType &type)
// //
//========================================================================== //==========================================================================
ExpVal FxExpression::EvalExpression()
{
ScriptPosition.Message(MSG_ERROR, "Unresolved expression found");
ExpVal val;
val.Type = VAL_Int;
val.Int = 0;
return val;
}
//==========================================================================
//
//
//
//==========================================================================
ExpEmit FxExpression::Emit (VMFunctionBuilder *build) ExpEmit FxExpression::Emit (VMFunctionBuilder *build)
{ {
ScriptPosition.Message(MSG_ERROR, "Unemitted expression found"); ScriptPosition.Message(MSG_ERROR, "Unemitted expression found");
@ -324,7 +308,7 @@ ExpEmit FxParameter::Emit(VMFunctionBuilder *build)
{ {
if (Operand->isConstant()) if (Operand->isConstant())
{ {
ExpVal val = Operand->EvalExpression(); ExpVal val = static_cast<FxConstant *>(Operand)->GetValue();
if (val.Type == VAL_Int || val.Type == VAL_Sound || val.Type == VAL_Name || val.Type == VAL_Color) if (val.Type == VAL_Int || val.Type == VAL_Sound || val.Type == VAL_Name || val.Type == VAL_Color)
{ {
build->EmitParamInt(val.Int); build->EmitParamInt(val.Int);
@ -375,17 +359,6 @@ ExpEmit FxParameter::Emit(VMFunctionBuilder *build)
// //
//========================================================================== //==========================================================================
ExpVal FxConstant::EvalExpression()
{
return value;
}
//==========================================================================
//
//
//
//==========================================================================
FxExpression *FxConstant::MakeConstant(PSymbol *sym, const FScriptPosition &pos) FxExpression *FxConstant::MakeConstant(PSymbol *sym, const FScriptPosition &pos)
{ {
FxExpression *x; FxExpression *x;
@ -500,7 +473,7 @@ FxExpression *FxIntCast::Resolve(FCompileContext &ctx)
{ {
if (basex->isConstant()) if (basex->isConstant())
{ {
ExpVal constval = basex->EvalExpression(); ExpVal constval = static_cast<FxConstant *>(basex)->GetValue();
FxExpression *x = new FxConstant(constval.GetInt(), ScriptPosition); FxExpression *x = new FxConstant(constval.GetInt(), ScriptPosition);
delete this; delete this;
return x; return x;
@ -521,14 +494,6 @@ FxExpression *FxIntCast::Resolve(FCompileContext &ctx)
// //
//========================================================================== //==========================================================================
ExpVal FxIntCast::EvalExpression()
{
ExpVal baseval = basex->EvalExpression();
baseval.Int = baseval.GetInt();
baseval.Type = VAL_Int;
return baseval;
}
ExpEmit FxIntCast::Emit(VMFunctionBuilder *build) ExpEmit FxIntCast::Emit(VMFunctionBuilder *build)
{ {
ExpEmit from = basex->Emit(build); ExpEmit from = basex->Emit(build);
@ -585,7 +550,7 @@ FxExpression *FxFloatCast::Resolve(FCompileContext &ctx)
{ {
if (basex->isConstant()) if (basex->isConstant())
{ {
ExpVal constval = basex->EvalExpression(); ExpVal constval = static_cast<FxConstant *>(basex)->GetValue();
FxExpression *x = new FxConstant(constval.GetFloat(), ScriptPosition); FxExpression *x = new FxConstant(constval.GetFloat(), ScriptPosition);
delete this; delete this;
return x; return x;
@ -606,14 +571,6 @@ FxExpression *FxFloatCast::Resolve(FCompileContext &ctx)
// //
//========================================================================== //==========================================================================
ExpVal FxFloatCast::EvalExpression()
{
ExpVal baseval = basex->EvalExpression();
baseval.Float = baseval.GetFloat();
baseval.Type = VAL_Float;
return baseval;
}
ExpEmit FxFloatCast::Emit(VMFunctionBuilder *build) ExpEmit FxFloatCast::Emit(VMFunctionBuilder *build)
{ {
ExpEmit from = basex->Emit(build); ExpEmit from = basex->Emit(build);
@ -717,7 +674,7 @@ FxExpression *FxMinusSign::Resolve(FCompileContext& ctx)
{ {
if (Operand->isConstant()) if (Operand->isConstant())
{ {
ExpVal val = Operand->EvalExpression(); ExpVal val = static_cast<FxConstant *>(Operand)->GetValue();
FxExpression *e = val.Type == VAL_Int? FxExpression *e = val.Type == VAL_Int?
new FxConstant(-val.Int, ScriptPosition) : new FxConstant(-val.Int, ScriptPosition) :
new FxConstant(-val.Float, ScriptPosition); new FxConstant(-val.Float, ScriptPosition);
@ -741,23 +698,6 @@ FxExpression *FxMinusSign::Resolve(FCompileContext& ctx)
// //
//========================================================================== //==========================================================================
ExpVal FxMinusSign::EvalExpression()
{
ExpVal ret;
if (ValueType == VAL_Int)
{
ret.Int = -Operand->EvalExpression().GetInt();
ret.Type = VAL_Int;
}
else
{
ret.Float = -Operand->EvalExpression().GetFloat();
ret.Type = VAL_Float;
}
return ret;
}
ExpEmit FxMinusSign::Emit(VMFunctionBuilder *build) ExpEmit FxMinusSign::Emit(VMFunctionBuilder *build)
{ {
assert(ValueType.Type == Operand->ValueType.Type); assert(ValueType.Type == Operand->ValueType.Type);
@ -831,7 +771,7 @@ FxExpression *FxUnaryNotBitwise::Resolve(FCompileContext& ctx)
if (Operand->isConstant()) if (Operand->isConstant())
{ {
int result = ~Operand->EvalExpression().GetInt(); int result = ~static_cast<FxConstant *>(Operand)->GetValue().GetInt();
FxExpression *e = new FxConstant(result, ScriptPosition); FxExpression *e = new FxConstant(result, ScriptPosition);
delete this; delete this;
return e; return e;
@ -846,15 +786,6 @@ FxExpression *FxUnaryNotBitwise::Resolve(FCompileContext& ctx)
// //
//========================================================================== //==========================================================================
ExpVal FxUnaryNotBitwise::EvalExpression()
{
ExpVal ret;
ret.Int = ~Operand->EvalExpression().GetInt();
ret.Type = VAL_Int;
return ret;
}
ExpEmit FxUnaryNotBitwise::Emit(VMFunctionBuilder *build) ExpEmit FxUnaryNotBitwise::Emit(VMFunctionBuilder *build)
{ {
assert(ValueType.Type == Operand->ValueType.Type); assert(ValueType.Type == Operand->ValueType.Type);
@ -913,7 +844,7 @@ FxExpression *FxUnaryNotBoolean::Resolve(FCompileContext& ctx)
{ {
if (Operand->isConstant()) if (Operand->isConstant())
{ {
bool result = !Operand->EvalExpression().GetBool(); bool result = !static_cast<FxConstant *>(Operand)->GetValue().GetBool();
FxExpression *e = new FxConstant(result, ScriptPosition); FxExpression *e = new FxConstant(result, ScriptPosition);
delete this; delete this;
return e; return e;
@ -935,15 +866,6 @@ FxExpression *FxUnaryNotBoolean::Resolve(FCompileContext& ctx)
// //
//========================================================================== //==========================================================================
ExpVal FxUnaryNotBoolean::EvalExpression()
{
ExpVal ret;
ret.Int = !Operand->EvalExpression().GetBool();
ret.Type = VAL_Int;
return ret;
}
ExpEmit FxUnaryNotBoolean::Emit(VMFunctionBuilder *build) ExpEmit FxUnaryNotBoolean::Emit(VMFunctionBuilder *build)
{ {
ExpEmit from = Operand->Emit(build); ExpEmit from = Operand->Emit(build);
@ -1089,8 +1011,8 @@ FxExpression *FxAddSub::Resolve(FCompileContext& ctx)
if (ValueType == VAL_Float) if (ValueType == VAL_Float)
{ {
double v; double v;
double v1 = left->EvalExpression().GetFloat(); double v1 = static_cast<FxConstant *>(left)->GetValue().GetFloat();
double v2 = right->EvalExpression().GetFloat(); double v2 = static_cast<FxConstant *>(right)->GetValue().GetFloat();
v = Operator == '+'? v1 + v2 : v = Operator == '+'? v1 + v2 :
Operator == '-'? v1 - v2 : 0; Operator == '-'? v1 - v2 : 0;
@ -1102,8 +1024,8 @@ FxExpression *FxAddSub::Resolve(FCompileContext& ctx)
else else
{ {
int v; int v;
int v1 = left->EvalExpression().GetInt(); int v1 = static_cast<FxConstant *>(left)->GetValue().GetInt();
int v2 = right->EvalExpression().GetInt(); int v2 = static_cast<FxConstant *>(right)->GetValue().GetInt();
v = Operator == '+'? v1 + v2 : v = Operator == '+'? v1 + v2 :
Operator == '-'? v1 - v2 : 0; Operator == '-'? v1 - v2 : 0;
@ -1124,32 +1046,6 @@ FxExpression *FxAddSub::Resolve(FCompileContext& ctx)
// //
//========================================================================== //==========================================================================
ExpVal FxAddSub::EvalExpression()
{
ExpVal ret;
if (ValueType == VAL_Float)
{
double v1 = left->EvalExpression().GetFloat();
double v2 = right->EvalExpression().GetFloat();
ret.Type = VAL_Float;
ret.Float = Operator == '+'? v1 + v2 :
Operator == '-'? v1 - v2 : 0;
}
else
{
int v1 = left->EvalExpression().GetInt();
int v2 = right->EvalExpression().GetInt();
ret.Type = VAL_Int;
ret.Int = Operator == '+'? v1 + v2 :
Operator == '-'? v1 - v2 : 0;
}
return ret;
}
ExpEmit FxAddSub::Emit(VMFunctionBuilder *build) ExpEmit FxAddSub::Emit(VMFunctionBuilder *build)
{ {
assert(Operator == '+' || Operator == '-'); assert(Operator == '+' || Operator == '-');
@ -1241,8 +1137,8 @@ FxExpression *FxMulDiv::Resolve(FCompileContext& ctx)
if (ValueType == VAL_Float) if (ValueType == VAL_Float)
{ {
double v; double v;
double v1 = left->EvalExpression().GetFloat(); double v1 = static_cast<FxConstant *>(left)->GetValue().GetFloat();
double v2 = right->EvalExpression().GetFloat(); double v2 = static_cast<FxConstant *>(right)->GetValue().GetFloat();
if (Operator != '*' && v2 == 0) if (Operator != '*' && v2 == 0)
{ {
@ -1262,8 +1158,8 @@ FxExpression *FxMulDiv::Resolve(FCompileContext& ctx)
else else
{ {
int v; int v;
int v1 = left->EvalExpression().GetInt(); int v1 = static_cast<FxConstant *>(left)->GetValue().GetInt();
int v2 = right->EvalExpression().GetInt(); int v2 = static_cast<FxConstant *>(right)->GetValue().GetInt();
if (Operator != '*' && v2 == 0) if (Operator != '*' && v2 == 0)
{ {
@ -1293,44 +1189,6 @@ FxExpression *FxMulDiv::Resolve(FCompileContext& ctx)
// //
//========================================================================== //==========================================================================
ExpVal FxMulDiv::EvalExpression()
{
ExpVal ret;
if (ValueType == VAL_Float)
{
double v1 = left->EvalExpression().GetFloat();
double v2 = right->EvalExpression().GetFloat();
if (Operator != '*' && v2 == 0)
{
I_Error("Division by 0");
}
ret.Type = VAL_Float;
ret.Float = Operator == '*'? v1 * v2 :
Operator == '/'? v1 / v2 :
Operator == '%'? fmod(v1, v2) : 0;
}
else
{
int v1 = left->EvalExpression().GetInt();
int v2 = right->EvalExpression().GetInt();
if (Operator != '*' && v2 == 0)
{
I_Error("Division by 0");
}
ret.Type = VAL_Int;
ret.Int = Operator == '*'? v1 * v2 :
Operator == '/'? v1 / v2 :
Operator == '%'? v1 % v2 : 0;
}
return ret;
}
ExpEmit FxMulDiv::Emit(VMFunctionBuilder *build) ExpEmit FxMulDiv::Emit(VMFunctionBuilder *build)
{ {
ExpEmit op1 = left->Emit(build); ExpEmit op1 = left->Emit(build);
@ -1425,8 +1283,8 @@ FxExpression *FxCompareRel::Resolve(FCompileContext& ctx)
if (ValueType == VAL_Float) if (ValueType == VAL_Float)
{ {
double v1 = left->EvalExpression().GetFloat(); double v1 = static_cast<FxConstant *>(left)->GetValue().GetFloat();
double v2 = right->EvalExpression().GetFloat(); double v2 = static_cast<FxConstant *>(right)->GetValue().GetFloat();
v = Operator == '<'? v1 < v2 : v = Operator == '<'? v1 < v2 :
Operator == '>'? v1 > v2 : Operator == '>'? v1 > v2 :
Operator == TK_Geq? v1 >= v2 : Operator == TK_Geq? v1 >= v2 :
@ -1434,8 +1292,8 @@ FxExpression *FxCompareRel::Resolve(FCompileContext& ctx)
} }
else else
{ {
int v1 = left->EvalExpression().GetInt(); int v1 = static_cast<FxConstant *>(left)->GetValue().GetInt();
int v2 = right->EvalExpression().GetInt(); int v2 = static_cast<FxConstant *>(right)->GetValue().GetInt();
v = Operator == '<'? v1 < v2 : v = Operator == '<'? v1 < v2 :
Operator == '>'? v1 > v2 : Operator == '>'? v1 > v2 :
Operator == TK_Geq? v1 >= v2 : Operator == TK_Geq? v1 >= v2 :
@ -1457,33 +1315,6 @@ FxExpression *FxCompareRel::Resolve(FCompileContext& ctx)
// //
//========================================================================== //==========================================================================
ExpVal FxCompareRel::EvalExpression()
{
ExpVal ret;
ret.Type = VAL_Int;
if (left->ValueType == VAL_Float || right->ValueType == VAL_Float)
{
double v1 = left->EvalExpression().GetFloat();
double v2 = right->EvalExpression().GetFloat();
ret.Int = Operator == '<'? v1 < v2 :
Operator == '>'? v1 > v2 :
Operator == TK_Geq? v1 >= v2 :
Operator == TK_Leq? v1 <= v2 : 0;
}
else
{
int v1 = left->EvalExpression().GetInt();
int v2 = right->EvalExpression().GetInt();
ret.Int = Operator == '<'? v1 < v2 :
Operator == '>'? v1 > v2 :
Operator == TK_Geq? v1 >= v2 :
Operator == TK_Leq? v1 <= v2 : 0;
}
return ret;
}
ExpEmit FxCompareRel::Emit(VMFunctionBuilder *build) ExpEmit FxCompareRel::Emit(VMFunctionBuilder *build)
{ {
ExpEmit op1 = left->Emit(build); ExpEmit op1 = left->Emit(build);
@ -1584,14 +1415,14 @@ cont:
if (ValueType == VAL_Float) if (ValueType == VAL_Float)
{ {
double v1 = left->EvalExpression().GetFloat(); double v1 = static_cast<FxConstant *>(left)->GetValue().GetFloat();
double v2 = right->EvalExpression().GetFloat(); double v2 = static_cast<FxConstant *>(right)->GetValue().GetFloat();
v = Operator == TK_Eq? v1 == v2 : v1 != v2; v = Operator == TK_Eq? v1 == v2 : v1 != v2;
} }
else else
{ {
int v1 = left->EvalExpression().GetInt(); int v1 = static_cast<FxConstant *>(left)->GetValue().GetInt();
int v2 = right->EvalExpression().GetInt(); int v2 = static_cast<FxConstant *>(right)->GetValue().GetInt();
v = Operator == TK_Eq? v1 == v2 : v1 != v2; v = Operator == TK_Eq? v1 == v2 : v1 != v2;
} }
FxExpression *e = new FxConstant(v, ScriptPosition); FxExpression *e = new FxConstant(v, ScriptPosition);
@ -1609,32 +1440,6 @@ cont:
// //
//========================================================================== //==========================================================================
ExpVal FxCompareEq::EvalExpression()
{
ExpVal ret;
ret.Type = VAL_Int;
if (left->ValueType == VAL_Float || right->ValueType == VAL_Float)
{
double v1 = left->EvalExpression().GetFloat();
double v2 = right->EvalExpression().GetFloat();
ret.Int = Operator == TK_Eq? v1 == v2 : v1 != v2;
}
else if (left->ValueType == VAL_Int)
{
int v1 = left->EvalExpression().GetInt();
int v2 = right->EvalExpression().GetInt();
ret.Int = Operator == TK_Eq? v1 == v2 : v1 != v2;
}
else
{
// Implement pointer comparison
ret.Int = 0;
}
return ret;
}
ExpEmit FxCompareEq::Emit(VMFunctionBuilder *build) ExpEmit FxCompareEq::Emit(VMFunctionBuilder *build)
{ {
ExpEmit op1 = left->Emit(build); ExpEmit op1 = left->Emit(build);
@ -1725,8 +1530,8 @@ FxExpression *FxBinaryInt::Resolve(FCompileContext& ctx)
} }
else if (left->isConstant() && right->isConstant()) else if (left->isConstant() && right->isConstant())
{ {
int v1 = left->EvalExpression().GetInt(); int v1 = static_cast<FxConstant *>(left)->GetValue().GetInt();
int v2 = right->EvalExpression().GetInt(); int v2 = static_cast<FxConstant *>(right)->GetValue().GetInt();
FxExpression *e = new FxConstant( FxExpression *e = new FxConstant(
Operator == TK_LShift? v1 << v2 : Operator == TK_LShift? v1 << v2 :
@ -1748,25 +1553,6 @@ FxExpression *FxBinaryInt::Resolve(FCompileContext& ctx)
// //
//========================================================================== //==========================================================================
ExpVal FxBinaryInt::EvalExpression()
{
int v1 = left->EvalExpression().GetInt();
int v2 = right->EvalExpression().GetInt();
ExpVal ret;
ret.Type = VAL_Int;
ret.Int =
Operator == TK_LShift? v1 << v2 :
Operator == TK_RShift? v1 >> v2 :
Operator == TK_URShift? int((unsigned int)(v1) >> v2) :
Operator == '&'? v1 & v2 :
Operator == '|'? v1 | v2 :
Operator == '^'? v1 ^ v2 : 0;
return ret;
}
ExpEmit FxBinaryInt::Emit(VMFunctionBuilder *build) ExpEmit FxBinaryInt::Emit(VMFunctionBuilder *build)
{ {
assert(left->ValueType == VAL_Int); assert(left->ValueType == VAL_Int);
@ -1795,7 +1581,7 @@ ExpEmit FxBinaryInt::Emit(VMFunctionBuilder *build)
{ // Shift instructions use right-hand immediates instead of constant registers. { // Shift instructions use right-hand immediates instead of constant registers.
if (right->isConstant()) if (right->isConstant())
{ {
rop = right->EvalExpression().GetInt(); rop = static_cast<FxConstant *>(right)->GetValue().GetInt();
op2.Konst = true; op2.Konst = true;
} }
else else
@ -1886,8 +1672,8 @@ FxExpression *FxBinaryLogical::Resolve(FCompileContext& ctx)
int b_left=-1, b_right=-1; int b_left=-1, b_right=-1;
if (left->isConstant()) b_left = left->EvalExpression().GetBool(); if (left->isConstant()) b_left = static_cast<FxConstant *>(left)->GetValue().GetBool();
if (right->isConstant()) b_right = right->EvalExpression().GetBool(); if (right->isConstant()) b_right = static_cast<FxConstant *>(right)->GetValue().GetBool();
// Do some optimizations. This will throw out all sub-expressions that are not // Do some optimizations. This will throw out all sub-expressions that are not
// needed to retrieve the final result. // needed to retrieve the final result.
@ -1966,25 +1752,6 @@ FxExpression *FxBinaryLogical::Resolve(FCompileContext& ctx)
// //
//========================================================================== //==========================================================================
ExpVal FxBinaryLogical::EvalExpression()
{
bool b_left = left->EvalExpression().GetBool();
ExpVal ret;
ret.Type = VAL_Int;
ret.Int = false;
if (Operator == TK_AndAnd)
{
ret.Int = (b_left && right->EvalExpression().GetBool());
}
else if (Operator == TK_OrOr)
{
ret.Int = (b_left || right->EvalExpression().GetBool());
}
return ret;
}
ExpEmit FxBinaryLogical::Emit(VMFunctionBuilder *build) ExpEmit FxBinaryLogical::Emit(VMFunctionBuilder *build)
{ {
// This is not the "right" way to do these, but it works for now. // This is not the "right" way to do these, but it works for now.
@ -2088,7 +1855,7 @@ FxExpression *FxConditional::Resolve(FCompileContext& ctx)
if (condition->isConstant()) if (condition->isConstant())
{ {
ExpVal condval = condition->EvalExpression(); ExpVal condval = static_cast<FxConstant *>(condition)->GetValue();
bool result = condval.GetBool(); bool result = condval.GetBool();
FxExpression *e = result? truex:falsex; FxExpression *e = result? truex:falsex;
@ -2121,15 +1888,6 @@ FxExpression *FxConditional::Resolve(FCompileContext& ctx)
// //
//========================================================================== //==========================================================================
ExpVal FxConditional::EvalExpression()
{
ExpVal condval = condition->EvalExpression();
bool result = condval.GetBool();
FxExpression *e = result? truex:falsex;
return e->EvalExpression();
}
ExpEmit FxConditional::Emit(VMFunctionBuilder *build) ExpEmit FxConditional::Emit(VMFunctionBuilder *build)
{ {
ExpEmit out; ExpEmit out;
@ -2148,7 +1906,7 @@ ExpEmit FxConditional::Emit(VMFunctionBuilder *build)
if (truex->isConstant() && truex->ValueType == VAL_Int) if (truex->isConstant() && truex->ValueType == VAL_Int)
{ {
out = ExpEmit(build, REGT_INT); out = ExpEmit(build, REGT_INT);
build->EmitLoadInt(out.RegNum, truex->EvalExpression().GetInt()); build->EmitLoadInt(out.RegNum, static_cast<FxConstant *>(truex)->GetValue().GetInt());
} }
else else
{ {
@ -2171,7 +1929,7 @@ ExpEmit FxConditional::Emit(VMFunctionBuilder *build)
build->BackpatchToHere(patchspot); build->BackpatchToHere(patchspot);
if (falsex->isConstant() && falsex->ValueType == VAL_Int) if (falsex->isConstant() && falsex->ValueType == VAL_Int)
{ {
build->EmitLoadInt(out.RegNum, falsex->EvalExpression().GetInt()); build->EmitLoadInt(out.RegNum, static_cast<FxConstant *>(falsex)->GetValue().GetInt());
} }
else else
{ {
@ -2245,7 +2003,7 @@ FxExpression *FxAbs::Resolve(FCompileContext &ctx)
} }
else if (val->isConstant()) else if (val->isConstant())
{ {
ExpVal value = val->EvalExpression(); ExpVal value = static_cast<FxConstant *>(val)->GetValue();
switch (value.Type) switch (value.Type)
{ {
case VAL_Int: case VAL_Int:
@ -2274,23 +2032,6 @@ FxExpression *FxAbs::Resolve(FCompileContext &ctx)
// //
//========================================================================== //==========================================================================
ExpVal FxAbs::EvalExpression()
{
ExpVal value = val->EvalExpression();
switch (value.Type)
{
default:
case VAL_Int:
value.Int = abs(value.Int);
break;
case VAL_Float:
value.Float = fabs(value.Float);
break;
}
return value;
}
ExpEmit FxAbs::Emit(VMFunctionBuilder *build) ExpEmit FxAbs::Emit(VMFunctionBuilder *build)
{ {
ExpEmit absofsteal = val->Emit(build); ExpEmit absofsteal = val->Emit(build);
@ -2761,28 +2502,6 @@ FxExpression *FxGlobalVariable::Resolve(FCompileContext&)
// //
//========================================================================== //==========================================================================
ExpVal FxGlobalVariable::EvalExpression()
{
ExpVal ret;
if (!AddressRequested)
{
ret = GetVariableValue((void*)var->offset, var->ValueType);
}
else
{
ret.pointer = (void*)var->offset;
ret.Type = VAL_Pointer;
}
return ret;
}
//==========================================================================
//
//
//
//==========================================================================
FxClassMember::FxClassMember(FxExpression *x, PSymbolVariable* mem, const FScriptPosition &pos) FxClassMember::FxClassMember(FxExpression *x, PSymbolVariable* mem, const FScriptPosition &pos)
: FxExpression(pos) : FxExpression(pos)
{ {
@ -2858,42 +2577,6 @@ FxExpression *FxClassMember::Resolve(FCompileContext &ctx)
return this; return this;
} }
//==========================================================================
//
//
//
//==========================================================================
ExpVal FxClassMember::EvalExpression()
{
char *object = NULL;
if (classx->ValueType == VAL_Class)
{
// not implemented yet
}
else
{
object = classx->EvalExpression().GetPointer<char>();
}
if (object == NULL)
{
I_Error("Accessing member variable without valid object");
}
ExpVal ret;
if (!AddressRequested)
{
ret = GetVariableValue(object + membervar->offset, membervar->ValueType);
}
else
{
ret.pointer = object + membervar->offset;
ret.Type = VAL_Pointer;
}
return ret;
}
ExpEmit FxClassMember::Emit(VMFunctionBuilder *build) ExpEmit FxClassMember::Emit(VMFunctionBuilder *build)
{ {
ExpEmit obj = classx->Emit(build); ExpEmit obj = classx->Emit(build);
@ -3071,23 +2754,6 @@ FxExpression *FxArrayElement::Resolve(FCompileContext &ctx)
// //
//========================================================================== //==========================================================================
ExpVal FxArrayElement::EvalExpression()
{
int * arraystart = Array->EvalExpression().GetPointer<int>();
int indexval = index->EvalExpression().GetInt();
if (indexval < 0 || indexval >= Array->ValueType.size)
{
I_Error("Array index out of bounds");
}
ExpVal ret;
ret.Int = arraystart[indexval];
ret.Type = VAL_Int;
return ret;
}
ExpEmit FxArrayElement::Emit(VMFunctionBuilder *build) ExpEmit FxArrayElement::Emit(VMFunctionBuilder *build)
{ {
ExpEmit start = Array->Emit(build); ExpEmit start = Array->Emit(build);
@ -3100,7 +2766,7 @@ ExpEmit FxArrayElement::Emit(VMFunctionBuilder *build)
} }
if (index->isConstant()) if (index->isConstant())
{ {
int indexval = index->EvalExpression().GetInt(); int indexval = static_cast<FxConstant *>(index)->GetValue().GetInt();
if (indexval < 0 || indexval >= Array->ValueType.size) if (indexval < 0 || indexval >= Array->ValueType.size)
{ {
I_Error("Array index out of bounds"); I_Error("Array index out of bounds");
@ -3326,14 +2992,14 @@ ExpEmit FxActionSpecialCall::Emit(VMFunctionBuilder *build)
{ {
assert(argex->ValueType == VAL_Name); assert(argex->ValueType == VAL_Name);
assert(argex->isConstant()); assert(argex->isConstant());
build->EmitParamInt(-argex->EvalExpression().GetName()); build->EmitParamInt(-static_cast<FxConstant *>(argex)->GetValue().GetName());
} }
else else
{ {
assert(argex->ValueType == VAL_Int); assert(argex->ValueType == VAL_Int);
if (argex->isConstant()) if (argex->isConstant())
{ {
build->EmitParamInt(argex->EvalExpression().GetInt()); build->EmitParamInt(static_cast<FxConstant *>(argex)->GetValue().GetInt());
} }
else else
{ {
@ -3408,7 +3074,7 @@ FxExpression *FxGlobalFunctionCall::Resolve(FCompileContext& ctx)
} }
if ((*ArgList)[0]->isConstant()) if ((*ArgList)[0]->isConstant())
{ {
double v = (*ArgList)[0]->EvalExpression().GetFloat(); double v = static_cast<FxConstant *>((*ArgList)[0])->GetValue().GetFloat();
if (Name == NAME_Sqrt) if (Name == NAME_Sqrt)
{ {
v = sqrt(v); v = sqrt(v);
@ -3435,24 +3101,6 @@ FxExpression *FxGlobalFunctionCall::Resolve(FCompileContext& ctx)
// //
//========================================================================== //==========================================================================
ExpVal FxGlobalFunctionCall::EvalExpression()
{
double v = (*ArgList)[0]->EvalExpression().GetFloat();
ExpVal ret;
ret.Type = VAL_Float;
if (Name == NAME_Sqrt)
{
ret.Float = sqrt(v);
}
else
{
v *= M_PI / 180.0; // convert from degrees to radians
ret.Float = (Name == NAME_Sin) ? sin(v) : cos(v);
}
return ret;
}
ExpEmit FxGlobalFunctionCall::Emit(VMFunctionBuilder *build) ExpEmit FxGlobalFunctionCall::Emit(VMFunctionBuilder *build)
{ {
ExpEmit v = (*ArgList)[0]->Emit(build); ExpEmit v = (*ArgList)[0]->Emit(build);
@ -3507,7 +3155,7 @@ FxExpression *FxClassTypeCast::Resolve(FCompileContext &ctx)
if (basex->isConstant()) if (basex->isConstant())
{ {
FName clsname = basex->EvalExpression().GetName(); FName clsname = static_cast<FxConstant *>(basex)->GetValue().GetName();
const PClass *cls = NULL; const PClass *cls = NULL;
if (clsname != NAME_None) if (clsname != NAME_None)
@ -3550,23 +3198,6 @@ FxExpression *FxClassTypeCast::Resolve(FCompileContext &ctx)
// //
//========================================================================== //==========================================================================
ExpVal FxClassTypeCast::EvalExpression()
{
FName clsname = basex->EvalExpression().GetName();
const PClass *cls = PClass::FindClass(clsname);
if (!cls->IsDescendantOf(desttype))
{
Printf("class '%s' is not compatible with '%s'", clsname.GetChars(), desttype->TypeName.GetChars());
cls = NULL;
}
ExpVal ret;
ret.Type = VAL_Class;
ret.pointer = (void*)cls;
return ret;
}
int DecoNameToClass(VMFrameStack *stack, VMValue *param, int numparam, VMReturn *ret, int numret) int DecoNameToClass(VMFrameStack *stack, VMValue *param, int numparam, VMReturn *ret, int numret)
{ {
assert(numparam == 2); assert(numparam == 2);
@ -3735,25 +3366,6 @@ FxExpression *FxMultiNameState::Resolve(FCompileContext &ctx)
// //
//========================================================================== //==========================================================================
ExpVal FxMultiNameState::EvalExpression()
{
ExpVal ret;
ret.Type = VAL_State;
ret.pointer = NULL;
if (ret.pointer == NULL)
{
const char *dot="";
Printf("Jump target '");
for (unsigned int i=0;i<names.Size();i++)
{
Printf("%s%s", dot, names[i].GetChars());
dot = ".";
}
Printf("' not found in\n");
}
return ret;
}
static int DoFindState(VMFrameStack *stack, VMValue *param, int numparam, VMReturn *ret, FName *names, int numnames) static int DoFindState(VMFrameStack *stack, VMValue *param, int numparam, VMReturn *ret, FName *names, int numnames)
{ {
PARAM_OBJECT_AT(0, self, AActor); PARAM_OBJECT_AT(0, self, AActor);
@ -3877,7 +3489,7 @@ ExpEmit FxDamageValue::Emit(VMFunctionBuilder *build)
{ {
if (val->isConstant()) if (val->isConstant())
{ {
build->EmitRetInt(0, false, val->EvalExpression().Int); build->EmitRetInt(0, false, static_cast<FxConstant *>(val)->GetValue().Int);
} }
else else
{ {

View file

@ -208,25 +208,35 @@ static void ParseConstant (FScanner &sc, PSymbolTable *symt, PClassActor *cls)
FxExpression *expr = ParseExpression (sc, cls); FxExpression *expr = ParseExpression (sc, cls);
sc.MustGetToken(';'); sc.MustGetToken(';');
ExpVal val = expr->EvalExpression(); FCompileContext ctx(cls, true, true);
delete expr; expr = expr->Resolve(ctx);
PSymbolConst *sym = new PSymbolConst(symname); if (!expr->isConstant())
if (type == TK_Int)
{ {
sym->ValueType = VAL_Int; sc.ScriptMessage("Constant definition is not a constant");
sym->Value = val.GetInt(); FScriptPosition::ErrorCounter++;
} }
else else
{ {
sym->ValueType = VAL_Float; ExpVal val = static_cast<FxConstant *>(expr)->GetValue();
sym->Float = val.GetFloat(); delete expr;
} PSymbolConst *sym = new PSymbolConst(symname);
if (symt->AddSymbol (sym) == NULL) if (type == TK_Int)
{ {
delete sym; sym->ValueType = VAL_Int;
sc.ScriptMessage ("'%s' is already defined in '%s'.", sym->Value = val.GetInt();
symname.GetChars(), cls? cls->TypeName.GetChars() : "Global"); }
FScriptPosition::ErrorCounter++; else
{
sym->ValueType = VAL_Float;
sym->Float = val.GetFloat();
}
if (symt->AddSymbol (sym) == NULL)
{
delete sym;
sc.ScriptMessage ("'%s' is already defined in '%s'.",
symname.GetChars(), cls? cls->TypeName.GetChars() : "Global");
FScriptPosition::ErrorCounter++;
}
} }
} }
else else
@ -256,7 +266,17 @@ static void ParseEnum (FScanner &sc, PSymbolTable *symt, PClassActor *cls)
if (sc.CheckToken('=')) if (sc.CheckToken('='))
{ {
FxExpression *expr = ParseExpression (sc, cls); FxExpression *expr = ParseExpression (sc, cls);
currvalue = expr->EvalExpression().GetInt(); FCompileContext ctx(cls, true, true);
expr = expr->Resolve(ctx);
if (!expr->isConstant())
{
sc.ScriptMessage("'%s' must be constant", symname.GetChars());
FScriptPosition::ErrorCounter++;
}
else
{
currvalue = static_cast<FxConstant *>(expr)->GetValue().GetInt();
}
delete expr; delete expr;
} }
PSymbolConst *sym = new PSymbolConst(symname); PSymbolConst *sym = new PSymbolConst(symname);
@ -335,7 +355,13 @@ static void ParseNativeVariable (FScanner &sc, PSymbolTable *symt, PClassActor *
if (sc.CheckToken('[')) if (sc.CheckToken('['))
{ {
FxExpression *expr = ParseExpression (sc, cls); FxExpression *expr = ParseExpression (sc, cls);
int maxelems = expr->EvalExpression().GetInt(); FCompileContext ctx(cls, true, true);
expr = expr->Resolve(ctx);
if (!expr->isConstant())
{
sc.ScriptError("Array size must be constant");
}
int maxelems = static_cast<FxConstant *>(expr)->GetValue().GetInt();
delete expr; delete expr;
sc.MustGetToken(']'); sc.MustGetToken(']');
valuetype.MakeArray(maxelems); valuetype.MakeArray(maxelems);
@ -402,8 +428,19 @@ static void ParseUserVariable (FScanner &sc, PSymbolTable *symt, PClassActor *cl
if (sc.CheckToken('[')) if (sc.CheckToken('['))
{ {
FxExpression *expr = ParseExpression(sc, cls); FxExpression *expr = ParseExpression(sc, cls);
int maxelems = expr->EvalExpression().GetInt(); FCompileContext ctx(cls, true, true);
delete expr; int maxelems;
expr = expr->Resolve(ctx);
if (!expr->isConstant())
{
sc.ScriptMessage("Array size must be a constant");
FScriptPosition::ErrorCounter++;
maxelems = 1;
}
else
{
maxelems = static_cast<FxConstant *>(expr)->GetValue().GetInt();
}
sc.MustGetToken(']'); sc.MustGetToken(']');
if (maxelems <= 0) if (maxelems <= 0)
{ {