Fix using negative numbers in default arguments

Issue #919
master
melex750 2017-03-03 02:11:10 -05:00
parent b032dad578
commit f80db9e8fb
4 changed files with 33 additions and 8 deletions

View File

@ -41,7 +41,7 @@ CBotExprUnaire::~CBotExprUnaire()
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
CBotInstr* CBotExprUnaire::Compile(CBotToken* &p, CBotCStack* pStack) CBotInstr* CBotExprUnaire::Compile(CBotToken* &p, CBotCStack* pStack, bool bLiteral)
{ {
int op = p->GetType(); int op = p->GetType();
CBotToken* pp = p; CBotToken* pp = p;
@ -52,7 +52,10 @@ CBotInstr* CBotExprUnaire::Compile(CBotToken* &p, CBotCStack* pStack)
CBotExprUnaire* inst = new CBotExprUnaire(); CBotExprUnaire* inst = new CBotExprUnaire();
inst->SetToken(pp); inst->SetToken(pp);
if (nullptr != (inst->m_expr = CBotParExpr::Compile(p, pStk ))) if (!bLiteral) inst->m_expr = CBotParExpr::Compile(p, pStk);
else inst->m_expr = CBotParExpr::CompileLitExpr(p, pStk);
if (inst->m_expr != nullptr)
{ {
if (op == ID_ADD && pStk->GetType() < CBotTypBoolean) // only with the number if (op == ID_ADD && pStk->GetType() < CBotTypBoolean) // only with the number
return pStack->Return(inst, pStk); return pStack->Return(inst, pStk);

View File

@ -34,12 +34,13 @@ public:
~CBotExprUnaire(); ~CBotExprUnaire();
/*! /*!
* \brief Compile * \brief Compile an expression with a unary operator
* \param p * \param p[in, out] Pointer to first token of the expression, will be updated to point to first token after the expression
* \param pStack * \param pStack Current compilation stack frame
* \return * \param bLiteral If true, compiles only literal expressions Ex: ~11, -4.0, !false, not true
* \return The compiled instruction or nullptr
*/ */
static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack); static CBotInstr* Compile(CBotToken* &p, CBotCStack* pStack, bool bLiteral = false);
/*! /*!
* \brief Execute * \brief Execute

View File

@ -132,7 +132,7 @@ CBotInstr* CBotParExpr::Compile(CBotToken* &p, CBotCStack* pStack)
return pStack->Return(nullptr, pStk); return pStack->Return(nullptr, pStk);
} }
return CompileLitExpr(p, pStack); return CBotParExpr::CompileLitExpr(p, pStack);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -142,6 +142,11 @@ CBotInstr* CBotParExpr::CompileLitExpr(CBotToken* &p, CBotCStack* pStack)
CBotToken* pp = p; CBotToken* pp = p;
// is this a unary operation?
CBotInstr* inst = CBotExprUnaire::Compile(p, pStk, true);
if (inst != nullptr || !pStk->IsOk())
return pStack->Return(inst, pStk);
// is it a number or DefineNum? // is it a number or DefineNum?
if (p->GetType() == TokenTypNum || if (p->GetType() == TokenTypNum ||
p->GetType() == TokenTypDef ) p->GetType() == TokenTypDef )

View File

@ -2385,4 +2385,20 @@ TEST_F(CBotUT, ParametersWithDefaultValues)
"\n", "\n",
CBotErrAmbiguousCall CBotErrAmbiguousCall
); );
ExecuteTest(
"extern void DefaultValueUnaryExpression() {\n"
" TestNumbers();\n"
" TestBool();\n"
"}\n"
"void TestNumbers(int i = -1, float f = -1, int ii = ~1) {\n"
" ASSERT(i == -1);\n"
" ASSERT(f == -1.0);\n"
" ASSERT(ii == ~1);\n"
"}\n"
"void TestBool(bool b = !false, bool b2 = not false) {\n"
" ASSERT(true == b);\n"
" ASSERT(true == b2);\n"
"}\n"
);
} }