- implemented '**' (power) operator. To ensure reliability, acustom 'pow' function will be used to calculate it.
- fixed: FxBinary::ResolveLR' check for numeric operations was incomplete. Like far too many other places it just assumed that everything with ValueType->GetRegType() == REGT_INT is a numeric type, but for names this is not the case.
This commit is contained in:
parent
d0a8960f61
commit
938ab4ca70
10 changed files with 1033 additions and 10 deletions
|
|
@ -1824,13 +1824,16 @@ bool FxBinary::ResolveLR(FCompileContext& ctx, bool castnumeric)
|
|||
{
|
||||
ValueType = TypeBool;
|
||||
}
|
||||
if (left->ValueType->GetRegType() == REGT_INT && right->ValueType->GetRegType() == REGT_INT)
|
||||
{
|
||||
ValueType = TypeSInt32;
|
||||
}
|
||||
else if (left->IsNumeric() && right->IsNumeric())
|
||||
{
|
||||
ValueType = TypeFloat64;
|
||||
if (left->ValueType->GetRegType() == REGT_INT && right->ValueType->GetRegType() == REGT_INT)
|
||||
{
|
||||
ValueType = TypeSInt32;
|
||||
}
|
||||
else
|
||||
{
|
||||
ValueType = TypeFloat64;
|
||||
}
|
||||
}
|
||||
else if (left->ValueType->GetRegType() == REGT_POINTER && left->ValueType == right->ValueType)
|
||||
{
|
||||
|
|
@ -2137,6 +2140,60 @@ ExpEmit FxMulDiv::Emit(VMFunctionBuilder *build)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FxPow::FxPow(FxExpression *l, FxExpression *r)
|
||||
: FxBinary(TK_MulMul, new FxFloatCast(l), new FxFloatCast(r))
|
||||
{
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FxExpression *FxPow::Resolve(FCompileContext& ctx)
|
||||
{
|
||||
CHECKRESOLVED();
|
||||
|
||||
if (!ResolveLR(ctx, true)) return NULL;
|
||||
|
||||
if (left->isConstant() && right->isConstant())
|
||||
{
|
||||
double v1 = static_cast<FxConstant *>(left)->GetValue().GetFloat();
|
||||
double v2 = static_cast<FxConstant *>(right)->GetValue().GetFloat();
|
||||
return new FxConstant(g_pow(v1, v2), left->ScriptPosition);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
ExpEmit FxPow::Emit(VMFunctionBuilder *build)
|
||||
{
|
||||
ExpEmit op1 = left->Emit(build);
|
||||
ExpEmit op2 = right->Emit(build);
|
||||
|
||||
// Pow is not commutative, so either side may be constant (but not both).
|
||||
assert(!op1.Konst || !op2.Konst);
|
||||
op1.Free(build);
|
||||
op2.Free(build);
|
||||
assert(op1.RegType == REGT_FLOAT && op2.RegType == REGT_FLOAT);
|
||||
ExpEmit to(build, REGT_FLOAT);
|
||||
build->Emit((op1.Konst ? OP_POWF_KR : op2.Konst ? OP_POWF_RK : OP_POWF_RR), to.RegNum, op1.RegNum, op2.RegNum);
|
||||
return to;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FxCompareRel::FxCompareRel(int o, FxExpression *l, FxExpression *r)
|
||||
: FxBinary(o, l, r)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue