Merged PR #737: Fix for various issues with initializing variables in CBOT
commit
14721001e5
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include "CBot/CBotClass.h"
|
||||
|
||||
#include "CBot/CBotInstr/CBotInstrUtils.h"
|
||||
#include "CBot/CBotInstr/CBotNew.h"
|
||||
#include "CBot/CBotInstr/CBotLeftExprVar.h"
|
||||
#include "CBot/CBotInstr/CBotTwoOpExpr.h"
|
||||
|
@ -32,6 +33,7 @@
|
|||
#include "CBot/CBotExternalCall.h"
|
||||
#include "CBot/CBotStack.h"
|
||||
#include "CBot/CBotCStack.h"
|
||||
#include "CBot/CBotDefParam.h"
|
||||
#include "CBot/CBotUtils.h"
|
||||
#include "CBot/CBotFileUtils.h"
|
||||
#include "CBot/CBotCallMethode.h"
|
||||
|
@ -549,6 +551,7 @@ bool CBotClass::CompileDefItem(CBotToken* &p, CBotCStack* pStack, bool bSecond)
|
|||
|
||||
while (pStack->IsOk())
|
||||
{
|
||||
CBotTypResult type2 = CBotTypResult(type); // reset type after comma
|
||||
std::string pp = p->GetString();
|
||||
if ( IsOfType(p, ID_NOT) )
|
||||
{
|
||||
|
@ -561,29 +564,27 @@ bool CBotClass::CompileDefItem(CBotToken* &p, CBotCStack* pStack, bool bSecond)
|
|||
while ( IsOfType( p, ID_OPBRK ) ) // a table?
|
||||
{
|
||||
CBotInstr* i = nullptr;
|
||||
|
||||
pStack->SetStartError( p->GetStart() );
|
||||
if ( p->GetType() != ID_CLBRK )
|
||||
{
|
||||
i = CBotExpression::Compile( p, pStack ); // expression for the value
|
||||
if (i == nullptr || pStack->GetType() != CBotTypInt) // must be a number
|
||||
{
|
||||
pStack->SetError(CBotErrBadIndex, p->GetStart());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
i = new CBotEmpty(); // special if not a formula
|
||||
|
||||
type = CBotTypResult(CBotTypArrayPointer, type);
|
||||
|
||||
if (!pStack->IsOk() || !IsOfType( p, ID_CLBRK ) )
|
||||
{
|
||||
pStack->SetError(CBotErrCloseIndex, p->GetStart());
|
||||
return false;
|
||||
}
|
||||
|
||||
/* CBotVar* pv = pStack->GetVar();
|
||||
if ( pv->GetType()>= CBotTypBoolean )
|
||||
{
|
||||
pStack->SetError(CBotErrBadType1, p->GetStart());
|
||||
return false;
|
||||
}*/
|
||||
type2 = CBotTypResult(CBotTypArrayPointer, type2);
|
||||
|
||||
if (limites == nullptr) limites = i;
|
||||
else limites->AddNext3(i);
|
||||
|
||||
if (IsOfType(p, ID_CLBRK)) continue;
|
||||
pStack->SetError(CBotErrCloseIndex, p->GetStart());
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( p->GetType() == ID_OPENPAR )
|
||||
|
@ -604,9 +605,14 @@ bool CBotClass::CompileDefItem(CBotToken* &p, CBotCStack* pStack, bool bSecond)
|
|||
// return a method precompiled in pass 1
|
||||
CBotFunction* pf = m_pMethod;
|
||||
CBotFunction* prev = nullptr;
|
||||
while ( pf != nullptr )
|
||||
CBotToken* ppp = p;
|
||||
CBotCStack* pStk = pStack->TokenStack(nullptr, true);
|
||||
CBotDefParam* params = CBotDefParam::Compile(p, pStk );
|
||||
delete pStk;
|
||||
p = ppp;
|
||||
while ( pf != nullptr ) // search by name and parameters
|
||||
{
|
||||
if (pf->GetName() == pp) break;
|
||||
if (pf->GetName() == pp && pf->CheckParam( params )) break;
|
||||
prev = pf;
|
||||
pf = pf->Next();
|
||||
}
|
||||
|
@ -672,7 +678,7 @@ bool CBotClass::CompileDefItem(CBotToken* &p, CBotCStack* pStack, bool bSecond)
|
|||
}
|
||||
|
||||
// definition of an element
|
||||
if (type.Eq(0))
|
||||
if (type2.Eq(0))
|
||||
{
|
||||
pStack->SetError(CBotErrNoTerminator, p);
|
||||
return false;
|
||||
|
@ -681,14 +687,38 @@ bool CBotClass::CompileDefItem(CBotToken* &p, CBotCStack* pStack, bool bSecond)
|
|||
CBotInstr* i = nullptr;
|
||||
if ( IsOfType(p, ID_ASS ) )
|
||||
{
|
||||
if ( type.Eq(CBotTypArrayPointer) )
|
||||
pStack->SetStartError(p->GetStart());
|
||||
if ( IsOfType(p, ID_SEP) )
|
||||
{
|
||||
i = CBotListArray::Compile(p, pStack, type.GetTypElem());
|
||||
pStack->SetError(CBotErrNoExpression, p->GetStart());
|
||||
return false;
|
||||
}
|
||||
if ( type2.Eq(CBotTypArrayPointer) )
|
||||
{
|
||||
if ( nullptr == (i = CBotListArray::Compile(p, pStack, type2.GetTypElem())) )
|
||||
{
|
||||
if (pStack->IsOk())
|
||||
{
|
||||
i = CBotTwoOpExpr::Compile(p, pStack);
|
||||
if (i == nullptr || !pStack->GetTypResult().Compare(type2))
|
||||
{
|
||||
pStack->SetError(CBotErrBadType1, p->GetStart());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// it has an assignmet to calculate
|
||||
i = CBotTwoOpExpr::Compile(p, pStack);
|
||||
|
||||
if ( !(type.Eq(CBotTypPointer) && pStack->GetTypResult().Eq(CBotTypNullPointer)) &&
|
||||
!TypesCompatibles( type2, pStack->GetTypResult()) )
|
||||
{
|
||||
pStack->SetError(CBotErrBadType1, p->GetStart());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if ( !pStack->IsOk() ) return false;
|
||||
}
|
||||
|
@ -696,7 +726,7 @@ bool CBotClass::CompileDefItem(CBotToken* &p, CBotCStack* pStack, bool bSecond)
|
|||
|
||||
if ( !bSecond )
|
||||
{
|
||||
CBotVar* pv = CBotVar::Create(pp, type);
|
||||
CBotVar* pv = CBotVar::Create(pp, type2);
|
||||
pv -> SetStatic( bStatic );
|
||||
pv -> SetPrivate( mProtect );
|
||||
|
||||
|
|
|
@ -235,6 +235,7 @@ enum CBotError : int
|
|||
CBotErrBadIndex = 5040, //!< wrong index type "[ false ]"
|
||||
CBotErrPrivate = 5041, //!< protected item
|
||||
CBotErrNoPublic = 5042, //!< missing word "public"
|
||||
CBotErrNoExpression = 5043, //!< expression expected after =
|
||||
|
||||
// Runtime errors
|
||||
CBotErrZeroDiv = 6000, //!< division by zero
|
||||
|
|
|
@ -72,19 +72,26 @@ CBotInstr* CBotDefArray::Compile(CBotToken* &p, CBotCStack* pStack, CBotTypResul
|
|||
CBotInstr* i;
|
||||
while (IsOfType(p, ID_OPBRK))
|
||||
{
|
||||
pStk->SetStartError(p->GetStart());
|
||||
if (p->GetType() != ID_CLBRK)
|
||||
i = CBotExpression::Compile(p, pStk); // expression for the value
|
||||
{
|
||||
i = CBotExpression::Compile(p, pStk); // expression for the value
|
||||
if (i == nullptr || pStk->GetType() != CBotTypInt) // must be a number
|
||||
{
|
||||
pStk->SetError(CBotErrBadIndex, p->GetStart());
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
else
|
||||
i = new CBotEmpty(); // if no special formula
|
||||
|
||||
inst->AddNext3b(i); // construct a list
|
||||
type = CBotTypResult(CBotTypArrayPointer, type);
|
||||
|
||||
if (!pStk->IsOk() || !IsOfType(p, ID_CLBRK ))
|
||||
{
|
||||
pStk->SetError(CBotErrCloseIndex, p->GetStart());
|
||||
goto error;
|
||||
}
|
||||
if (IsOfType(p, ID_CLBRK)) continue;
|
||||
|
||||
pStk->SetError(CBotErrCloseIndex, p->GetStart());
|
||||
goto error;
|
||||
}
|
||||
|
||||
CBotVar* var = CBotVar::Create(*vartoken, type); // create an instance
|
||||
|
@ -96,17 +103,23 @@ CBotInstr* CBotDefArray::Compile(CBotToken* &p, CBotCStack* pStack, CBotTypResul
|
|||
|
||||
if (IsOfType(p, ID_ASS)) // with an assignment
|
||||
{
|
||||
if ((inst->m_listass = CBotTwoOpExpr::Compile(p, pStk)) != nullptr)
|
||||
pStk->SetStartError(p->GetStart());
|
||||
if ( IsOfType(p, ID_SEP) )
|
||||
{
|
||||
if (!pStk->GetTypResult().Compare(type)) // compatible type ?
|
||||
{
|
||||
pStk->SetError(CBotErrBadType1, p->GetStart());
|
||||
goto error;
|
||||
}
|
||||
pStk->SetError(CBotErrNoExpression, p->GetPrev());
|
||||
goto error;
|
||||
}
|
||||
else
|
||||
if ( nullptr == (inst->m_listass = CBotListArray::Compile(p, pStk, type.GetTypElem())) )
|
||||
{
|
||||
inst->m_listass = CBotListArray::Compile(p, pStk, type.GetTypElem());
|
||||
if (pStk->IsOk())
|
||||
{
|
||||
inst->m_listass = CBotTwoOpExpr::Compile(p, pStk);
|
||||
if (inst->m_listass == nullptr || !pStk->GetTypResult().Compare(type)) // compatible type ?
|
||||
{
|
||||
pStk->SetError(CBotErrBadType1, p->GetStart());
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -82,16 +82,17 @@ CBotInstr* CBotDefBoolean::Compile(CBotToken* &p, CBotCStack* pStack, bool cont,
|
|||
|
||||
inst = static_cast<CBotDefBoolean*>(CBotDefArray::Compile(p, pStk, CBotTypBoolean));
|
||||
|
||||
if (!pStk->IsOk() )
|
||||
{
|
||||
pStk->SetError(CBotErrCloseIndex, p->GetStart());
|
||||
goto error;
|
||||
}
|
||||
goto suite; // no assignment, variable already created
|
||||
}
|
||||
|
||||
if (IsOfType(p, ID_ASS))
|
||||
{
|
||||
pStk->SetStartError(p->GetStart());
|
||||
if ( IsOfType(p, ID_SEP) )
|
||||
{
|
||||
pStk->SetError(CBotErrNoExpression, p->GetStart());
|
||||
goto error;
|
||||
}
|
||||
if (nullptr == ( inst->m_expr = CBotTwoOpExpr::Compile( p, pStk )))
|
||||
{
|
||||
goto error;
|
||||
|
@ -109,7 +110,7 @@ CBotInstr* CBotDefBoolean::Compile(CBotToken* &p, CBotCStack* pStack, bool cont,
|
|||
(static_cast<CBotLeftExprVar*>(inst->m_var))->m_nIdent = CBotVar::NextUniqNum());
|
||||
pStack->AddVar(var);
|
||||
suite:
|
||||
if (IsOfType(p, ID_COMMA))
|
||||
if (pStk->IsOk() && IsOfType(p, ID_COMMA))
|
||||
{
|
||||
if (nullptr != ( inst->m_next2b = CBotDefBoolean::Compile(p, pStk, true, noskip)))
|
||||
{
|
||||
|
|
|
@ -101,11 +101,6 @@ CBotInstr* CBotDefClass::Compile(CBotToken* &p, CBotCStack* pStack, CBotClass* p
|
|||
|
||||
inst = static_cast<CBotDefClass*>(CBotDefArray::Compile(p, pStk, type ));
|
||||
|
||||
if (!pStk->IsOk() )
|
||||
{
|
||||
pStk->SetError(CBotErrCloseIndex, p->GetStart());
|
||||
goto error;
|
||||
}
|
||||
goto suite; // no assignment, variable already created
|
||||
}
|
||||
|
||||
|
@ -159,12 +154,19 @@ CBotInstr* CBotDefClass::Compile(CBotToken* &p, CBotCStack* pStack, CBotClass* p
|
|||
|
||||
if (IsOfType(p, ID_ASS)) // with a assignment?
|
||||
{
|
||||
pStk->SetStartError(p->GetStart());
|
||||
if (inst->m_hasParams)
|
||||
{
|
||||
pStk->SetError(CBotErrNoTerminator, p->GetStart());
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ( IsOfType(p, ID_SEP) )
|
||||
{
|
||||
pStk->SetError(CBotErrNoExpression, p->GetStart());
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ( nullptr == ( inst->m_expr = CBotTwoOpExpr::Compile( p, pStk )) )
|
||||
{
|
||||
goto error;
|
||||
|
@ -200,7 +202,7 @@ CBotInstr* CBotDefClass::Compile(CBotToken* &p, CBotCStack* pStack, CBotClass* p
|
|||
var->SetInit(CBotVar::InitType::IS_POINTER); // marks the pointer as init
|
||||
}
|
||||
suite:
|
||||
if (IsOfType(p, ID_COMMA)) // several chained definitions
|
||||
if (pStk->IsOk() && IsOfType(p, ID_COMMA)) // several chained definitions
|
||||
{
|
||||
if ( nullptr != ( inst->m_next = CBotDefClass::Compile(p, pStk, pClass) )) // compiles the following
|
||||
{
|
||||
|
@ -208,7 +210,7 @@ suite:
|
|||
}
|
||||
}
|
||||
|
||||
if (IsOfType(p, ID_SEP)) // complete instruction
|
||||
if (!pStk->IsOk() || IsOfType(p, ID_SEP)) // complete instruction
|
||||
{
|
||||
return pStack->Return(inst, pStk);
|
||||
}
|
||||
|
|
|
@ -81,16 +81,17 @@ CBotInstr* CBotDefFloat::Compile(CBotToken* &p, CBotCStack* pStack, bool cont, b
|
|||
p = vartoken;
|
||||
inst = static_cast<CBotDefFloat*>(CBotDefArray::Compile(p, pStk, CBotTypFloat));
|
||||
|
||||
if (!pStk->IsOk() )
|
||||
{
|
||||
pStk->SetError(CBotErrCloseIndex, p->GetStart());
|
||||
goto error;
|
||||
}
|
||||
goto suite; // no assignment, variable already created
|
||||
}
|
||||
|
||||
if (IsOfType(p, ID_ASS))
|
||||
{
|
||||
pStk->SetStartError(p->GetStart());
|
||||
if ( IsOfType(p, ID_SEP) )
|
||||
{
|
||||
pStk->SetError(CBotErrNoExpression, p->GetStart());
|
||||
goto error;
|
||||
}
|
||||
if (nullptr == ( inst->m_expr = CBotTwoOpExpr::Compile( p, pStk )))
|
||||
{
|
||||
goto error;
|
||||
|
@ -108,7 +109,7 @@ CBotInstr* CBotDefFloat::Compile(CBotToken* &p, CBotCStack* pStack, bool cont, b
|
|||
(static_cast<CBotLeftExprVar*>(inst->m_var))->m_nIdent = CBotVar::NextUniqNum());
|
||||
pStack->AddVar(var);
|
||||
suite:
|
||||
if (IsOfType(p, ID_COMMA))
|
||||
if (pStk->IsOk() && IsOfType(p, ID_COMMA))
|
||||
{
|
||||
if (nullptr != ( inst->m_next2b = CBotDefFloat::Compile(p, pStk, true, noskip)))
|
||||
{
|
||||
|
|
|
@ -84,25 +84,18 @@ CBotInstr* CBotDefInt::Compile(CBotToken* &p, CBotCStack* pStack, bool cont, boo
|
|||
|
||||
CBotInstr* inst2 = CBotDefArray::Compile(p, pStk, CBotTypInt);
|
||||
|
||||
if (!pStk->IsOk() )
|
||||
{
|
||||
pStk->SetError(CBotErrCloseIndex, p->GetStart());
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (IsOfType(p, ID_COMMA)) // several definition chained
|
||||
{
|
||||
if (nullptr != ( inst2->m_next2b = CBotDefInt::Compile(p, pStk, true, noskip))) // compile the next one
|
||||
{
|
||||
return pStack->Return(inst2, pStk);
|
||||
}
|
||||
}
|
||||
inst = static_cast<CBotDefInt*>(inst2);
|
||||
goto suite; // no assignment, variable already created
|
||||
}
|
||||
|
||||
if (IsOfType(p, ID_ASS)) // with an assignment?
|
||||
{
|
||||
pStk->SetStartError(p->GetStart());
|
||||
if ( IsOfType(p, ID_SEP) )
|
||||
{
|
||||
pStk->SetError(CBotErrNoExpression, p->GetStart());
|
||||
goto error;
|
||||
}
|
||||
if (nullptr == ( inst->m_expr = CBotTwoOpExpr::Compile( p, pStk )))
|
||||
{
|
||||
goto error;
|
||||
|
@ -121,15 +114,15 @@ CBotInstr* CBotDefInt::Compile(CBotToken* &p, CBotCStack* pStack, bool cont, boo
|
|||
(static_cast<CBotLeftExprVar*>(inst->m_var))->m_nIdent = CBotVar::NextUniqNum());
|
||||
pStack->AddVar(var); // place it on the stack
|
||||
}
|
||||
|
||||
if (IsOfType(p, ID_COMMA)) // chained several definitions
|
||||
suite:
|
||||
if (pStk->IsOk() && IsOfType(p, ID_COMMA)) // chained several definitions
|
||||
{
|
||||
if (nullptr != ( inst->m_next2b = CBotDefInt::Compile(p, pStk, true, noskip))) // compile next one
|
||||
{
|
||||
return pStack->Return(inst, pStk);
|
||||
}
|
||||
}
|
||||
suite:
|
||||
|
||||
if (noskip || IsOfType(p, ID_SEP)) // instruction is completed
|
||||
{
|
||||
return pStack->Return(inst, pStk);
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "CBot/CBotInstr/CBotDefString.h"
|
||||
|
||||
#include "CBot/CBotInstr/CBotLeftExprVar.h"
|
||||
#include "CBot/CBotInstr/CBotDefArray.h"
|
||||
#include "CBot/CBotInstr/CBotTwoOpExpr.h"
|
||||
|
||||
#include "CBot/CBotStack.h"
|
||||
|
@ -61,6 +62,7 @@ CBotInstr* CBotDefString::Compile(CBotToken* &p, CBotCStack* pStack, bool cont,
|
|||
inst->m_expr = nullptr;
|
||||
|
||||
CBotToken* vartoken = p;
|
||||
CBotVar* var = nullptr;
|
||||
inst->SetToken(vartoken);
|
||||
|
||||
if (nullptr != (inst->m_var = CBotLeftExprVar::Compile( p, pStk )))
|
||||
|
@ -73,8 +75,27 @@ CBotInstr* CBotDefString::Compile(CBotToken* &p, CBotCStack* pStack, bool cont,
|
|||
goto error;
|
||||
}
|
||||
|
||||
if (IsOfType(p, ID_OPBRK))
|
||||
{
|
||||
delete inst; // type is not CBotDefString
|
||||
p = vartoken; // returns the variable name
|
||||
|
||||
// compiles an array declaration
|
||||
|
||||
CBotInstr* inst2 = CBotDefArray::Compile(p, pStk, CBotTypString);
|
||||
|
||||
inst = static_cast<CBotDefString*>(inst2);
|
||||
goto suite; // no assignment, variable already created
|
||||
}
|
||||
|
||||
if (IsOfType(p, ID_ASS))
|
||||
{
|
||||
pStk->SetStartError(p->GetStart());
|
||||
if ( IsOfType(p, ID_SEP) )
|
||||
{
|
||||
pStk->SetError(CBotErrNoExpression, p->GetStart());
|
||||
goto error;
|
||||
}
|
||||
if (nullptr == ( inst->m_expr = CBotTwoOpExpr::Compile( p, pStk )))
|
||||
{
|
||||
goto error;
|
||||
|
@ -86,13 +107,13 @@ CBotInstr* CBotDefString::Compile(CBotToken* &p, CBotCStack* pStack, bool cont,
|
|||
}*/
|
||||
}
|
||||
|
||||
CBotVar* var = CBotVar::Create(*vartoken, CBotTypString);
|
||||
var = CBotVar::Create(*vartoken, CBotTypString);
|
||||
var->SetInit(inst->m_expr != nullptr ? CBotVar::InitType::DEF : CBotVar::InitType::UNDEF);
|
||||
var->SetUniqNum(
|
||||
(static_cast<CBotLeftExprVar*>(inst->m_var))->m_nIdent = CBotVar::NextUniqNum());
|
||||
pStack->AddVar(var);
|
||||
|
||||
if (IsOfType(p, ID_COMMA))
|
||||
suite:
|
||||
if (pStk->IsOk() && IsOfType(p, ID_COMMA))
|
||||
{
|
||||
if (nullptr != ( inst->m_next2b = CBotDefString::Compile(p, pStk, true, noskip)))
|
||||
{
|
||||
|
|
|
@ -51,12 +51,13 @@ CBotInstr* CBotListArray::Compile(CBotToken* &p, CBotCStack* pStack, CBotTypResu
|
|||
|
||||
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();
|
||||
|
||||
|
@ -65,25 +66,45 @@ CBotInstr* CBotListArray::Compile(CBotToken* &p, CBotCStack* pStack, CBotTypResu
|
|||
// 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 (nullptr == ( inst->m_expr = CBotListArray::Compile( p, pStk, type.GetTypElem() ) ))
|
||||
{
|
||||
goto error;
|
||||
if (pStk->IsOk())
|
||||
{
|
||||
inst->m_expr = CBotTwoOpExpr::Compile(p, pStk);
|
||||
if (inst->m_expr == nullptr || !pStk->GetTypResult().Compare(type)) // compatible type ?
|
||||
{
|
||||
pStk->SetError(CBotErrBadType1, p->GetStart());
|
||||
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 (nullptr == ( i = CBotListArray::Compile(p, pStk, type.GetTypElem() ) ))
|
||||
{
|
||||
goto error;
|
||||
if (pStk->IsOk())
|
||||
{
|
||||
i = CBotTwoOpExpr::Compile(p, pStk);
|
||||
if (i == nullptr || !pStk->GetTypResult().Compare(type)) // 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;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -95,7 +116,8 @@ CBotInstr* CBotListArray::Compile(CBotToken* &p, CBotCStack* pStack, CBotTypResu
|
|||
}
|
||||
CBotVar* pv = pStk->GetVar(); // result of the expression
|
||||
|
||||
if (pv == nullptr || !TypesCompatibles( type, pv->GetTypResult())) // compatible type?
|
||||
if (pv == nullptr || (!TypesCompatibles( type, pv->GetTypResult()) &&
|
||||
!(type.Eq(CBotTypPointer) && pv->GetTypResult().Eq(CBotTypNullPointer)) ))
|
||||
{
|
||||
pStk->SetError(CBotErrBadType1, p->GetStart());
|
||||
goto error;
|
||||
|
@ -113,12 +135,19 @@ CBotInstr* CBotListArray::Compile(CBotToken* &p, CBotCStack* pStack, CBotTypResu
|
|||
|
||||
CBotVar* pv = pStk->GetVar(); // result of the expression
|
||||
|
||||
if (pv == nullptr || !TypesCompatibles( type, pv->GetTypResult())) // compatible type?
|
||||
if (pv == nullptr || (!TypesCompatibles( type, pv->GetTypResult()) &&
|
||||
!(type.Eq(CBotTypPointer) && pv->GetTypResult().Eq(CBotTypNullPointer)) ))
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -715,6 +715,7 @@ void InitializeRestext()
|
|||
stringsCbot[CBot::CBotErrBadIndex] = TR("Incorrect index type");
|
||||
stringsCbot[CBot::CBotErrPrivate] = TR("Private element");
|
||||
stringsCbot[CBot::CBotErrNoPublic] = TR("Public required");
|
||||
stringsCbot[CBot::CBotErrNoExpression] = TR("expression expected after =");
|
||||
|
||||
stringsCbot[CBot::CBotErrZeroDiv] = TR("Dividing by zero");
|
||||
stringsCbot[CBot::CBotErrNotInit] = TR("Variable not initialized");
|
||||
|
|
Loading…
Reference in New Issue