Fix assigning instance to pointer for inheritance

dev-new-models
melex750 2016-08-04 01:06:37 -04:00
parent 860cdb0aea
commit c9c02f5461
8 changed files with 46 additions and 10 deletions

View File

@ -132,6 +132,11 @@ bool CBotDefParam::Execute(CBotVar** ppVars, CBotStack* &pj)
(static_cast<CBotVarClass*>(newvar))->Copy(ppVars[i], false); (static_cast<CBotVarClass*>(newvar))->Copy(ppVars[i], false);
break; break;
case CBotTypPointer: case CBotTypPointer:
{
newvar->SetPointer(ppVars[i]->GetPointer());
newvar->SetType(p->m_type); // keep pointer type
}
break;
case CBotTypArrayPointer: case CBotTypArrayPointer:
{ {
newvar->SetPointer(ppVars[i]->GetPointer()); newvar->SetPointer(ppVars[i]->GetPointer());

View File

@ -174,7 +174,7 @@ CBotInstr* CBotDefClass::Compile(CBotToken* &p, CBotCStack* pStack, CBotClass* p
CBotClass* result = pStk->GetClass(); CBotClass* result = pStk->GetClass();
if ( !pStk->GetTypResult(CBotVar::GetTypeMode::CLASS_AS_POINTER).Eq(CBotTypNullPointer) && if ( !pStk->GetTypResult(CBotVar::GetTypeMode::CLASS_AS_POINTER).Eq(CBotTypNullPointer) &&
( !pStk->GetTypResult(CBotVar::GetTypeMode::CLASS_AS_POINTER).Eq(CBotTypPointer) || ( !pStk->GetTypResult(CBotVar::GetTypeMode::CLASS_AS_POINTER).Eq(CBotTypPointer) ||
( result != nullptr && !pClass->IsChildOf(result) ))) // type compatible ? ( result != nullptr && !result->IsChildOf(pClass) ))) // type compatible ?
{ {
pStk->SetError(CBotErrBadType1, p->GetStart()); pStk->SetError(CBotErrBadType1, p->GetStart());
goto error; goto error;
@ -282,7 +282,9 @@ bool CBotDefClass::Execute(CBotStack* &pj)
{ {
CBotVarClass* pInstance; CBotVarClass* pInstance;
pInstance = (static_cast<CBotVarPointer*>(pile->GetVar()))->GetPointer(); // value for the assignment pInstance = (static_cast<CBotVarPointer*>(pile->GetVar()))->GetPointer(); // value for the assignment
CBotTypResult type = pThis->GetTypResult();
pThis->SetPointer(pInstance); pThis->SetPointer(pInstance);
pThis->SetType(type); // keep pointer type
} }
pThis->SetInit(CBotVar::InitType::DEF); pThis->SetInit(CBotVar::InitType::DEF);
} }

View File

@ -63,6 +63,7 @@ CBotInstr* CBotInstrMethode::Compile(CBotToken* &p, CBotCStack* pStack, CBotVar*
if (pStack->IsOk()) if (pStack->IsOk())
{ {
inst->m_thisIdent = var->GetUniqNum();
CBotClass* pClass = var->GetClass(); // pointer to the class CBotClass* pClass = var->GetClass(); // pointer to the class
inst->m_className = pClass->GetName(); // name of the class inst->m_className = pClass->GetName(); // name of the class
CBotTypResult r = pClass->CompileMethode(inst->m_methodName, var, ppVars, CBotTypResult r = pClass->CompileMethode(inst->m_methodName, var, ppVars,
@ -144,8 +145,14 @@ bool CBotInstrMethode::ExecuteVar(CBotVar* &pVar, CBotStack* &pj, CBotToken* pre
} }
ppVars[i] = nullptr; ppVars[i] = nullptr;
CBotClass* pClass = CBotClass::Find(m_className);
CBotVar* pThis = pile1->GetVar(); CBotVar* pThis = pile1->GetVar();
CBotClass* pClass;
if (m_thisIdent == -3) // super.method()
pClass = CBotClass::Find(m_className);
else
pClass = pThis->GetClass();
CBotVar* pResult = nullptr; CBotVar* pResult = nullptr;
if (m_typRes.GetType() > 0) pResult = CBotVar::Create("", m_typRes); if (m_typRes.GetType() > 0) pResult = CBotVar::Create("", m_typRes);
if (m_typRes.Eq(CBotTypClass)) if (m_typRes.Eq(CBotTypClass))
@ -204,7 +211,13 @@ void CBotInstrMethode::RestoreStateVar(CBotStack* &pile, bool bMain)
} }
ppVars[i] = nullptr; ppVars[i] = nullptr;
CBotClass* pClass = CBotClass::Find(m_className); CBotClass* pClass;
if (m_thisIdent == -3) // super.method()
pClass = CBotClass::Find(m_className);
else
pClass = pThis->GetClass();
// CBotVar* pResult = nullptr; // CBotVar* pResult = nullptr;
// CBotVar* pRes = pResult; // CBotVar* pRes = pResult;
@ -253,8 +266,14 @@ bool CBotInstrMethode::Execute(CBotStack* &pj)
} }
ppVars[i] = nullptr; ppVars[i] = nullptr;
CBotClass* pClass = CBotClass::Find(m_className);
CBotVar* pThis = pile1->GetVar(); CBotVar* pThis = pile1->GetVar();
CBotClass* pClass;
if (m_thisIdent == -3) // super.method()
pClass = CBotClass::Find(m_className);
else
pClass = pThis->GetClass();
CBotVar* pResult = nullptr; CBotVar* pResult = nullptr;
if (m_typRes.GetType()>0) pResult = CBotVar::Create("", m_typRes); if (m_typRes.GetType()>0) pResult = CBotVar::Create("", m_typRes);
if (m_typRes.Eq(CBotTypClass)) if (m_typRes.Eq(CBotTypClass))

View File

@ -83,6 +83,9 @@ private:
long m_MethodeIdent; long m_MethodeIdent;
//! Name of the class. //! Name of the class.
std::string m_className; std::string m_className;
//! Variable ID
long m_thisIdent;
}; };
} // namespace CBot } // namespace CBot

View File

@ -182,15 +182,18 @@ bool CBotLeftExpr::Execute(CBotStack* &pj, CBotStack* array)
if (t2.Eq(CBotTypPointer)) if (t2.Eq(CBotTypPointer))
{ {
CBotClass* c1 = t1.GetClass(); CBotClass* c1 = t1.GetClass();
CBotClass* c2 = t2.GetClass(); CBotClass* c2 = var2->GetClass();
if ( !c2->IsChildOf(c1)) if ( !c2->IsChildOf(c1))
{ {
CBotToken* pt = &m_token; CBotToken* pt = &m_token;
pile->SetError(CBotErrBadType1, pt); pile->SetError(CBotErrBadType1, pt);
return pj->Return(pile); // operation performed return pj->Return(pile); // operation performed
} }
var1->SetVal(var2); // set pointer
var1->SetType(t1); // keep pointer type
} }
var1->SetVal(var2); // do assignment else
var1->SetVal(var2); // do assignment
} }
pile->SetCopyVar(var1); // replace the stack with the copy of the variable pile->SetCopyVar(var1); // replace the stack with the copy of the variable
// (for name) // (for name)

View File

@ -115,7 +115,7 @@ CBotInstr* CBotListArray::Compile(CBotToken* &p, CBotCStack* pStack, CBotTypResu
goto error; goto error;
} }
CBotTypResult valType = pStk->GetTypResult(); CBotTypResult valType = pStk->GetTypResult(CBotVar::GetTypeMode::CLASS_AS_INTRINSIC);
if (!TypeCompatible(valType, type, ID_ASS) ) if (!TypeCompatible(valType, type, ID_ASS) )
{ {
@ -133,7 +133,7 @@ CBotInstr* CBotListArray::Compile(CBotToken* &p, CBotCStack* pStack, CBotTypResu
goto error; goto error;
} }
CBotTypResult valType = pStk->GetTypResult(); CBotTypResult valType = pStk->GetTypResult(CBotVar::GetTypeMode::CLASS_AS_INTRINSIC);
if (!TypeCompatible(valType, type, ID_ASS) ) if (!TypeCompatible(valType, type, ID_ASS) )
{ {
@ -185,9 +185,12 @@ bool CBotListArray::Execute(CBotStack* &pj, CBotVar* pVar)
pj->SetError(CBotErrOutArray, p->GetToken()); pj->SetError(CBotErrOutArray, p->GetToken());
return false; return false;
} }
CBotTypResult type = pVar2->GetTypResult();
if (!p->Execute(pile1, pVar2)) return false; // evaluate expression if (!p->Execute(pile1, pVar2)) return false; // evaluate expression
if (type.Eq(CBotTypPointer)) pVar2->SetType(type); // keep pointer type
pile1->IncState(); pile1->IncState();
} }

View File

@ -903,6 +903,7 @@ bool CBotVar::RestoreState(FILE* pf, CBotVar* &pVar)
(static_cast<CBotVarPointer*>(pNew))->SetPointer( pInstance ); // and point over (static_cast<CBotVarPointer*>(pNew))->SetPointer( pInstance ); // and point over
if (bConstructor) pNew->ConstructorSet(); // constructor was called if (bConstructor) pNew->ConstructorSet(); // constructor was called
if (ptrType.Eq(CBotTypPointer)) pNew->SetType(ptrType); // keep pointer type
// if ( p != nullptr ) (static_cast<CBotVarPointer*>(pNew))->SetPointer( p ); // rather this one // if ( p != nullptr ) (static_cast<CBotVarPointer*>(pNew))->SetPointer( p ); // rather this one

View File

@ -174,9 +174,9 @@ CBotClass* CBotVarPointer::GetClass()
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool CBotVarPointer::Save1State(FILE* pf) bool CBotVarPointer::Save1State(FILE* pf)
{ {
if ( m_pClass ) if ( m_type.GetClass() != nullptr )
{ {
if (!WriteString(pf, m_pClass->GetName())) return false; // name of the class if (!WriteString(pf, m_type.GetClass()->GetName())) return false; // name of the class
} }
else else
{ {