Merge pull request #783 from melex750/dev

[INFO] Conversion to string
master
krzys-h 2016-06-17 22:41:53 +02:00
commit bf2e3cdfae
5 changed files with 50 additions and 9 deletions

View File

@ -71,6 +71,13 @@ CBotInstr* CBotExpression::Compile(CBotToken* &p, CBotCStack* pStack)
return nullptr;
}
if ( p->GetType() == ID_SEP )
{
pStack->SetError(CBotErrNoExpression, p);
delete inst;
return nullptr;
}
inst->m_rightop = CBotExpression::Compile(p, pStack);
if (inst->m_rightop == nullptr)
{
@ -118,13 +125,13 @@ CBotInstr* CBotExpression::Compile(CBotToken* &p, CBotCStack* pStack)
break;
case ID_ASSADD:
if (type2.Eq(CBotTypBoolean) ||
type2.Eq(CBotTypPointer) ) type2 = -1; // numbers and strings
type2.GetType() > CBotTypString ) type2.SetType(-1); // numbers and strings
break;
case ID_ASSSUB:
case ID_ASSMUL:
case ID_ASSDIV:
case ID_ASSMODULO:
if (type2.GetType() >= CBotTypBoolean) type2 = -1; // numbers only
if (type2.GetType() >= CBotTypBoolean) type2.SetType(-1); // numbers only
break;
}
@ -179,6 +186,18 @@ bool CBotExpression::Execute(CBotStack* &pj)
if ( pile2->GetState()==0)
{
if (m_rightop && !m_rightop->Execute(pile2)) return false; // initial value // interrupted?
if (m_rightop)
{
CBotVar* var = pile1->GetVar();
CBotVar* value = pile2->GetVar();
if (var->GetType() == CBotTypString && value->GetType() != CBotTypString)
{
CBotVar* newVal = CBotVar::Create("", var->GetTypResult());
value->Update(pj->GetUserPtr());
newVal->SetValString(value->GetValString());
pile2->SetVar(newVal);
}
}
pile2->IncState();
}

View File

@ -97,9 +97,9 @@ bool TypeCompatible(CBotTypResult& type1, CBotTypResult& type2, int op)
if (max == 99) return false; // result is void?
// special case for strin concatenation
if (op == ID_ADD && max >= CBotTypString) return true;
if (op == ID_ASSADD && max >= CBotTypString) return true;
if (op == ID_ASS && t1 == CBotTypString) return true;
if (op == ID_ADD && t1 == CBotTypString) return true;
if (op == ID_ASSADD && t2 == CBotTypString) return true;
if (op == ID_ASS && t2 == CBotTypString) return true;
if (max >= CBotTypBoolean)
{

View File

@ -39,7 +39,13 @@ CBotInstr* CompileParams(CBotToken* &p, CBotCStack* pStack, CBotVar** ppVars);
/*!
* \brief TypeCompatible Check if two results are consistent to make an
* operation.
* operation. TypeCompatible is used in two ways:
* For non-assignment operations: see CBotTwoOpExpr::Compile
* TypeCompatible( leftType, rightType, opType )
* For assignment or compound assignment operations (it's reversed):
* see CBotReturn::Compile & CBotExpression::Compile
* TypeCompatible( valueType, varType, opType )
* \param type1
* \param type2
* \param op

View File

@ -64,6 +64,12 @@ bool CBotLeftExprVar::Execute(CBotStack* &pj)
CBotVar* var2 = pj->GetVar(); // Initial value on the stack
if (var2 != nullptr)
{
if (m_typevar.Eq(CBotTypString) && var2->GetType() != CBotTypString)
{
var2->Update(pj->GetUserPtr());
var1->SetValString(var2->GetValString());
return true;
}
var1->SetVal(var2); // Set the value
}

View File

@ -214,6 +214,13 @@ CBotInstr* CBotTwoOpExpr::Compile(CBotToken* &p, CBotCStack* pStack, int* pOpera
type2 = pStk->GetTypResult(); // what kind of results?
if ( type1.Eq(99) || type2.Eq(99) ) // operand is void
{
pStack->SetError(CBotErrBadType2, &inst->m_token);
delete inst;
return nullptr;
}
// what kind of result?
int TypeRes = std::max( type1.GetType(CBotTypResult::GetTypeMode::NULL_AS_POINTER), type2.GetType(CBotTypResult::GetTypeMode::NULL_AS_POINTER) );
if (typeOp == ID_ADD && type1.Eq(CBotTypString))
@ -267,7 +274,7 @@ CBotInstr* CBotTwoOpExpr::Compile(CBotToken* &p, CBotCStack* pStack, int* pOpera
return pStack->Return(nullptr, pStk);
}
if ( TypeRes != CBotTypString )
if ( TypeRes != CBotTypString ) // keep string conversion
TypeRes = std::max(type1.GetType(), type2.GetType());
inst = i;
}
@ -370,7 +377,9 @@ bool CBotTwoOpExpr::Execute(CBotStack* &pStack)
// what kind of result?
int TypeRes = std::max(type1.GetType(), type2.GetType());
if ( GetTokenType() == ID_ADD && type1.Eq(CBotTypString) )
// see "any type convertible chain" in compile method
if ( GetTokenType() == ID_ADD &&
(type1.Eq(CBotTypString) || type2.Eq(CBotTypString)) )
{
TypeRes = CBotTypString;
}
@ -397,7 +406,8 @@ bool CBotTwoOpExpr::Execute(CBotStack* &pStack)
CBotVar* result = CBotVar::Create("", TypeRes);
// creates a variable to perform the calculation in the appropriate type
TypeRes = std::max(type1.GetType(), type2.GetType());
if ( TypeRes != CBotTypString ) // keep string conversion
TypeRes = std::max(type1.GetType(), type2.GetType());
if ( GetTokenType() == ID_ADD && type1.Eq(CBotTypString) )
{