[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