diff --git a/src/CBot/CBotDefParam.cpp b/src/CBot/CBotDefParam.cpp index 5f164cab..d73c02e0 100644 --- a/src/CBot/CBotDefParam.cpp +++ b/src/CBot/CBotDefParam.cpp @@ -132,6 +132,11 @@ bool CBotDefParam::Execute(CBotVar** ppVars, CBotStack* &pj) (static_cast(newvar))->Copy(ppVars[i], false); break; case CBotTypPointer: + { + newvar->SetPointer(ppVars[i]->GetPointer()); + newvar->SetType(p->m_type); // keep pointer type + } + break; case CBotTypArrayPointer: { newvar->SetPointer(ppVars[i]->GetPointer()); diff --git a/src/CBot/CBotInstr/CBotDefClass.cpp b/src/CBot/CBotInstr/CBotDefClass.cpp index f7ea77a6..4c9ea4d4 100644 --- a/src/CBot/CBotInstr/CBotDefClass.cpp +++ b/src/CBot/CBotInstr/CBotDefClass.cpp @@ -174,7 +174,7 @@ CBotInstr* CBotDefClass::Compile(CBotToken* &p, CBotCStack* pStack, CBotClass* p CBotClass* result = pStk->GetClass(); if ( !pStk->GetTypResult(CBotVar::GetTypeMode::CLASS_AS_POINTER).Eq(CBotTypNullPointer) && ( !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()); goto error; @@ -282,7 +282,9 @@ bool CBotDefClass::Execute(CBotStack* &pj) { CBotVarClass* pInstance; pInstance = (static_cast(pile->GetVar()))->GetPointer(); // value for the assignment + CBotTypResult type = pThis->GetTypResult(); pThis->SetPointer(pInstance); + pThis->SetType(type); // keep pointer type } pThis->SetInit(CBotVar::InitType::DEF); } diff --git a/src/CBot/CBotInstr/CBotInstrMethode.cpp b/src/CBot/CBotInstr/CBotInstrMethode.cpp index 3bdf8492..207b9c12 100644 --- a/src/CBot/CBotInstr/CBotInstrMethode.cpp +++ b/src/CBot/CBotInstr/CBotInstrMethode.cpp @@ -63,6 +63,7 @@ CBotInstr* CBotInstrMethode::Compile(CBotToken* &p, CBotCStack* pStack, CBotVar* if (pStack->IsOk()) { + inst->m_thisIdent = var->GetUniqNum(); CBotClass* pClass = var->GetClass(); // pointer to the class inst->m_className = pClass->GetName(); // name of the class 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; - CBotClass* pClass = CBotClass::Find(m_className); CBotVar* pThis = pile1->GetVar(); + CBotClass* pClass; + + if (m_thisIdent == -3) // super.method() + pClass = CBotClass::Find(m_className); + else + pClass = pThis->GetClass(); + CBotVar* pResult = nullptr; if (m_typRes.GetType() > 0) pResult = CBotVar::Create("", m_typRes); if (m_typRes.Eq(CBotTypClass)) @@ -204,7 +211,13 @@ void CBotInstrMethode::RestoreStateVar(CBotStack* &pile, bool bMain) } 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* pRes = pResult; @@ -253,8 +266,14 @@ bool CBotInstrMethode::Execute(CBotStack* &pj) } ppVars[i] = nullptr; - CBotClass* pClass = CBotClass::Find(m_className); CBotVar* pThis = pile1->GetVar(); + CBotClass* pClass; + + if (m_thisIdent == -3) // super.method() + pClass = CBotClass::Find(m_className); + else + pClass = pThis->GetClass(); + CBotVar* pResult = nullptr; if (m_typRes.GetType()>0) pResult = CBotVar::Create("", m_typRes); if (m_typRes.Eq(CBotTypClass)) diff --git a/src/CBot/CBotInstr/CBotInstrMethode.h b/src/CBot/CBotInstr/CBotInstrMethode.h index 6c8d1731..10bfe499 100644 --- a/src/CBot/CBotInstr/CBotInstrMethode.h +++ b/src/CBot/CBotInstr/CBotInstrMethode.h @@ -83,6 +83,9 @@ private: long m_MethodeIdent; //! Name of the class. std::string m_className; + //! Variable ID + long m_thisIdent; + }; } // namespace CBot diff --git a/src/CBot/CBotInstr/CBotLeftExpr.cpp b/src/CBot/CBotInstr/CBotLeftExpr.cpp index 881d841d..3a9fe155 100644 --- a/src/CBot/CBotInstr/CBotLeftExpr.cpp +++ b/src/CBot/CBotInstr/CBotLeftExpr.cpp @@ -182,15 +182,18 @@ bool CBotLeftExpr::Execute(CBotStack* &pj, CBotStack* array) if (t2.Eq(CBotTypPointer)) { CBotClass* c1 = t1.GetClass(); - CBotClass* c2 = t2.GetClass(); + CBotClass* c2 = var2->GetClass(); if ( !c2->IsChildOf(c1)) { CBotToken* pt = &m_token; pile->SetError(CBotErrBadType1, pt); 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 // (for name) diff --git a/src/CBot/CBotInstr/CBotListArray.cpp b/src/CBot/CBotInstr/CBotListArray.cpp index 89cbb79a..cf3bfddc 100644 --- a/src/CBot/CBotInstr/CBotListArray.cpp +++ b/src/CBot/CBotInstr/CBotListArray.cpp @@ -115,7 +115,7 @@ CBotInstr* CBotListArray::Compile(CBotToken* &p, CBotCStack* pStack, CBotTypResu goto error; } - CBotTypResult valType = pStk->GetTypResult(); + CBotTypResult valType = pStk->GetTypResult(CBotVar::GetTypeMode::CLASS_AS_INTRINSIC); if (!TypeCompatible(valType, type, ID_ASS) ) { @@ -133,7 +133,7 @@ CBotInstr* CBotListArray::Compile(CBotToken* &p, CBotCStack* pStack, CBotTypResu goto error; } - CBotTypResult valType = pStk->GetTypResult(); + CBotTypResult valType = pStk->GetTypResult(CBotVar::GetTypeMode::CLASS_AS_INTRINSIC); if (!TypeCompatible(valType, type, ID_ASS) ) { @@ -185,9 +185,12 @@ bool CBotListArray::Execute(CBotStack* &pj, CBotVar* pVar) pj->SetError(CBotErrOutArray, p->GetToken()); return false; } + CBotTypResult type = pVar2->GetTypResult(); if (!p->Execute(pile1, pVar2)) return false; // evaluate expression + if (type.Eq(CBotTypPointer)) pVar2->SetType(type); // keep pointer type + pile1->IncState(); } diff --git a/src/CBot/CBotStack.cpp b/src/CBot/CBotStack.cpp index aa67264b..295e6063 100644 --- a/src/CBot/CBotStack.cpp +++ b/src/CBot/CBotStack.cpp @@ -903,6 +903,7 @@ bool CBotVar::RestoreState(FILE* pf, CBotVar* &pVar) (static_cast(pNew))->SetPointer( pInstance ); // and point over if (bConstructor) pNew->ConstructorSet(); // constructor was called + if (ptrType.Eq(CBotTypPointer)) pNew->SetType(ptrType); // keep pointer type // if ( p != nullptr ) (static_cast(pNew))->SetPointer( p ); // rather this one diff --git a/src/CBot/CBotVar/CBotVarPointer.cpp b/src/CBot/CBotVar/CBotVarPointer.cpp index 059edb7e..f98b1463 100644 --- a/src/CBot/CBotVar/CBotVarPointer.cpp +++ b/src/CBot/CBotVar/CBotVarPointer.cpp @@ -174,9 +174,9 @@ CBotClass* CBotVarPointer::GetClass() //////////////////////////////////////////////////////////////////////////////// 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 {