[colobot] 01/145: Fix syntax and type checking for CBotListArray
Didier Raboud
odyx at moszumanska.debian.org
Mon Jul 11 12:56:11 UTC 2016
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 <melex750 at 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
More information about the Pkg-games-commits
mailing list