This is an automated email from the git hooks/post-receive script. odyx pushed a commit to branch debian/master in repository colobot.
commit 4a29e8406ddcad70ec84e0ef142a9d4f270ad570 Author: melex750 <melex...@users.noreply.github.com> Date: Sun Mar 20 07:48:20 2016 -0400 Fix syntax and type checking for CBotListArray --- src/CBot/CBotInstr/CBotListArray.cpp | 99 +++++++++++++++++++++++++++++++----- src/CBot/CBotInstr/CBotListArray.h | 3 +- 2 files changed, 87 insertions(+), 15 deletions(-) diff --git a/src/CBot/CBotInstr/CBotListArray.cpp b/src/CBot/CBotInstr/CBotListArray.cpp index 20a34e6..ab25e05 100644 --- a/src/CBot/CBotInstr/CBotListArray.cpp +++ b/src/CBot/CBotInstr/CBotListArray.cpp @@ -45,57 +45,111 @@ CBotListArray::~CBotListArray() } //////////////////////////////////////////////////////////////////////////////// -CBotInstr* CBotListArray::Compile(CBotToken* &p, CBotCStack* pStack, CBotTypResult type) +CBotInstr* CBotListArray::Compile(CBotToken* &p, CBotCStack* pStack, CBotTypResult type, bool classItem) { CBotCStack* pStk = pStack->TokenStack(p); CBotToken* pp = p; - if (IsOfType( p, ID_NULL )) + if (IsOfType( p, ID_NULL ) || (IsOfType(p, ID_OPBLK) && IsOfType(p, ID_CLBLK))) { CBotInstr* inst = new CBotExprLitNull(); inst->SetToken(pp); return pStack->Return(inst, pStk); // ok with empty element } + p = pp; CBotListArray* inst = new CBotListArray(); + pStk->SetStartError(p->GetStart()); + if (IsOfType( p, ID_OPBLK )) { // each element takes the one after the other if (type.Eq( CBotTypArrayPointer )) { - type = type.GetTypElem(); - pStk->SetStartError(p->GetStart()); - if (nullptr == ( inst->m_expr = CBotListArray::Compile( p, pStk, type ) )) + if (p->GetType() == TokenTypVar) { - goto error; + if (!classItem) + { + inst->m_expr = CBotTwoOpExpr::Compile(p, pStk); + if (!pStk->GetTypResult().Compare(type)) // compatible type ? + { + pStk->SetError(CBotErrBadType1, p->GetStart()); + goto error; + } + } + else + { + pStk->SetError(CBotErrBadLeft, p->GetPrev()); + goto error; + } + } + else + { + if (nullptr == ( inst->m_expr = CBotListArray::Compile( p, pStk, type.GetTypElem() ) )) + { + goto error; + } } - while (IsOfType( p, ID_COMMA )) // other elements? { pStk->SetStartError(p->GetStart()); - - CBotInstr* i = CBotListArray::Compile(p, pStk, type); - if (nullptr == i) + CBotInstr* i = nullptr; + if (p->GetType() == TokenTypVar) { - goto error; + if (!classItem) + { + i = CBotTwoOpExpr::Compile(p, pStk); + if (nullptr == i || !pStk->GetTypResult().Compare(type)) // compatible type ? + { + pStk->SetError(CBotErrBadType1, p->GetStart()); + goto error; + } + } + else + { + pStk->SetError(CBotErrBadLeft, p->GetPrev()); + goto error; + } + } + else + { + i = CBotListArray::Compile(p, pStk, type.GetTypElem()); + if (nullptr == i) + { + goto error; + } } - inst->m_expr->AddNext3(i); + if ( p->GetType() == ID_COMMA ) continue; + if ( p->GetType() == ID_CLBLK ) break; + + pStk->SetError(CBotErrClosePar, p); + goto error; } } else { pStk->SetStartError(p->GetStart()); + if (classItem && IsOfType(p, TokenTypVar, ID_NEW)) // don't allow func() or var between "{ }" + { + pStk->SetError(CBotErrBadLeft, p->GetPrev()); + goto error; + } if (nullptr == ( inst->m_expr = CBotTwoOpExpr::Compile( p, pStk ))) { goto error; } CBotVar* pv = pStk->GetVar(); // result of the expression + CBotTypResult retType; + if (pv != nullptr) retType = pv->GetTypResult(CBotVar::GetTypeMode::CLASS_AS_INTRINSIC); - if (pv == nullptr || !TypesCompatibles( type, pv->GetTypResult())) // compatible type? + if (pv == nullptr || (type.Eq(CBotTypString) && !retType.Eq(CBotTypString)) || + (!(type.Eq(CBotTypPointer) && retType.Eq(CBotTypNullPointer)) && + !TypesCompatibles( type, pv->GetTypResult()) && + !TypeCompatible(type, retType, ID_ASS) ) ) // compatible type? { pStk->SetError(CBotErrBadType1, p->GetStart()); goto error; @@ -105,6 +159,12 @@ CBotInstr* CBotListArray::Compile(CBotToken* &p, CBotCStack* pStack, CBotTypResu { pStk->SetStartError(p->GetStart()); + if (classItem && IsOfType(p, TokenTypVar, ID_NEW)) // don't allow func() or var between "{ }" + { + pStk->SetError(CBotErrBadLeft, p); + goto error; + } + CBotInstr* i = CBotTwoOpExpr::Compile(p, pStk) ; if (nullptr == i) { @@ -112,13 +172,24 @@ CBotInstr* CBotListArray::Compile(CBotToken* &p, CBotCStack* pStack, CBotTypResu } CBotVar* pv = pStk->GetVar(); // result of the expression + CBotTypResult retType; + if (pv != nullptr) retType = pv->GetTypResult(CBotVar::GetTypeMode::CLASS_AS_INTRINSIC); - if (pv == nullptr || !TypesCompatibles( type, pv->GetTypResult())) // compatible type? + if (pv == nullptr || (type.Eq(CBotTypString) && !retType.Eq(CBotTypString)) || + (!(type.Eq(CBotTypPointer) && retType.Eq(CBotTypNullPointer)) && + !TypesCompatibles( type, pv->GetTypResult()) && + !TypeCompatible(type, retType, ID_ASS) ) ) // compatible type? { pStk->SetError(CBotErrBadType1, p->GetStart()); goto error; } inst->m_expr->AddNext3(i); + + if (p->GetType() == ID_COMMA) continue; + if (p->GetType() == ID_CLBLK) break; + + pStk->SetError(CBotErrClosePar, p); + goto error; } } diff --git a/src/CBot/CBotInstr/CBotListArray.h b/src/CBot/CBotInstr/CBotListArray.h index c5f800b..5c9eafd 100644 --- a/src/CBot/CBotInstr/CBotListArray.h +++ b/src/CBot/CBotInstr/CBotListArray.h @@ -38,9 +38,10 @@ public: * \param p * \param pStack * \param type + * \param classItem * \return */ - static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack, CBotTypResult type); + static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack, CBotTypResult type, bool classItem = false); /*! * \brief Execute Executes the definition of an array. -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/colobot.git _______________________________________________ Pkg-games-commits mailing list Pkg-games-commits@lists.alioth.debian.org http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-games-commits