diff --git a/src/CBot/CBotInstr/CBotExprUnaire.cpp b/src/CBot/CBotInstr/CBotExprUnaire.cpp index 0080a468..e4d1ec3f 100644 --- a/src/CBot/CBotInstr/CBotExprUnaire.cpp +++ b/src/CBot/CBotInstr/CBotExprUnaire.cpp @@ -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(); CBotToken* pp = p; @@ -52,7 +52,10 @@ CBotInstr* CBotExprUnaire::Compile(CBotToken* &p, CBotCStack* pStack) CBotExprUnaire* inst = new CBotExprUnaire(); 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 return pStack->Return(inst, pStk); diff --git a/src/CBot/CBotInstr/CBotExprUnaire.h b/src/CBot/CBotInstr/CBotExprUnaire.h index e7e58c74..b15d2552 100644 --- a/src/CBot/CBotInstr/CBotExprUnaire.h +++ b/src/CBot/CBotInstr/CBotExprUnaire.h @@ -34,12 +34,13 @@ public: ~CBotExprUnaire(); /*! - * \brief Compile - * \param p - * \param pStack - * \return + * \brief Compile an expression with a unary operator + * \param p[in, out] Pointer to first token of the expression, will be updated to point to first token after the expression + * \param pStack Current compilation stack frame + * \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 diff --git a/src/CBot/CBotInstr/CBotParExpr.cpp b/src/CBot/CBotInstr/CBotParExpr.cpp index b0c2f1c1..0a608c32 100644 --- a/src/CBot/CBotInstr/CBotParExpr.cpp +++ b/src/CBot/CBotInstr/CBotParExpr.cpp @@ -132,7 +132,7 @@ CBotInstr* CBotParExpr::Compile(CBotToken* &p, CBotCStack* pStack) 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; + // 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? if (p->GetType() == TokenTypNum || p->GetType() == TokenTypDef ) diff --git a/test/unit/CBot/CBot_test.cpp b/test/unit/CBot/CBot_test.cpp index 2f8bb503..5d3b72c3 100644 --- a/test/unit/CBot/CBot_test.cpp +++ b/test/unit/CBot/CBot_test.cpp @@ -2385,4 +2385,20 @@ TEST_F(CBotUT, ParametersWithDefaultValues) "\n", 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" + ); }