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

Reply via email to