[colobot] 54/100: Fix execution of default arguments
Didier Raboud
odyx at moszumanska.debian.org
Thu Jun 1 18:10:18 UTC 2017
This is an automated email from the git hooks/post-receive script.
odyx pushed a commit to branch debian/master
in repository colobot.
commit b032dad578cdaf07d77f0bf52520a15984bb88a9
Author: melex750 <melex750 at users.noreply.github.com>
Date: Fri Mar 3 01:09:09 2017 -0500
Fix execution of default arguments
---
src/CBot/CBotDefParam.cpp | 38 ++++++++++---
src/CBot/CBotInstr/CBotFunction.cpp | 110 +++++++++++++++++++++++++++---------
2 files changed, 112 insertions(+), 36 deletions(-)
diff --git a/src/CBot/CBotDefParam.cpp b/src/CBot/CBotDefParam.cpp
index 8b54f5a..b3a11a6 100644
--- a/src/CBot/CBotDefParam.cpp
+++ b/src/CBot/CBotDefParam.cpp
@@ -136,30 +136,38 @@ bool CBotDefParam::Execute(CBotVar** ppVars, CBotStack* &pj)
CBotDefParam* p = this;
bool useDefault = false;
+ CBotStack* pile = pj->AddStack();
while ( p != nullptr )
{
- // creates a local variable on the stack
- CBotVar* newvar = CBotVar::Create(p->m_token.GetString(), p->m_type);
+ pile = pile->AddStack();
+ if (pile->GetState() == 1) // already done?
+ {
+ if (ppVars != nullptr && ppVars[i] != nullptr) ++i;
+ p = p->m_next;
+ continue; // next param
+ }
CBotVar* pVar = nullptr;
- CBotStack* pile = nullptr; // stack for default expression
if (useDefault || (ppVars == nullptr || ppVars[i] == nullptr))
{
assert(p->m_expr != nullptr);
- pile = pj->AddStack();
useDefault = true;
- while (pile->IsOk() && !p->m_expr->Execute(pile));
- if (!pile->IsOk()) return pj->Return(pile); // return the error
+ if (!p->m_expr->Execute(pile)) return false; // interupt here
pVar = pile->GetVar();
}
else
pVar = ppVars[i];
+ pile->SetState(1); // mark this param done
+
+ // creates a local variable on the stack
+ CBotVar* newvar = CBotVar::Create(p->m_token.GetString(), p->m_type);
+
// serves to make the transformation of types:
if ((useDefault && pVar != nullptr) ||
(ppVars != nullptr && pVar != nullptr))
@@ -202,7 +210,6 @@ bool CBotDefParam::Execute(CBotVar** ppVars, CBotStack* &pj)
pj->AddVar(newvar); // add a variable
p = p->m_next;
if (!useDefault) i++;
- if (pile != nullptr) pile->Delete();
}
return true;
@@ -217,14 +224,27 @@ bool CBotDefParam::HasDefault()
////////////////////////////////////////////////////////////////////////////////
void CBotDefParam::RestoreState(CBotStack* &pj, bool bMain)
{
-// int i = 0;
+ assert(this != nullptr);
CBotDefParam* p = this;
+ CBotStack* pile = nullptr;
+ if (bMain) pile = pj->RestoreStack();
+
while ( p != nullptr )
{
+ if (bMain && pile != nullptr)
+ {
+ pile = pile->RestoreStack();
+ if (pile != nullptr && pile->GetState() == 0)
+ {
+ assert(p->m_expr != nullptr);
+ p->m_expr->RestoreState(pile, true);
+ return;
+ }
+ }
// creates a local variable on the stack
CBotVar* var = pj->FindVar(p->m_token.GetString());
- var->SetUniqNum(p->m_nIdent);
+ if (var != nullptr) var->SetUniqNum(p->m_nIdent);
p = p->m_next;
}
}
diff --git a/src/CBot/CBotInstr/CBotFunction.cpp b/src/CBot/CBotInstr/CBotFunction.cpp
index 0f6a980..c24f986 100644
--- a/src/CBot/CBotInstr/CBotFunction.cpp
+++ b/src/CBot/CBotInstr/CBotFunction.cpp
@@ -370,11 +370,18 @@ bool CBotFunction::Execute(CBotVar** ppVars, CBotStack* &pj, CBotVar* pInstance)
pile->SetProgram(m_pProg); // bases for routines
+ if ( pile->IfStep() ) return false;
+
if ( pile->GetState() == 0 )
{
if (m_param != nullptr)
{
+ // stack for parameters and default args
+ CBotStack* pile3b = pile->AddStack();
+ pile3b->SetState(1);
+
if ( !m_param->Execute(ppVars, pile) ) return false; // define parameters
+ pile3b->Delete(); // done with param stack
}
pile->IncState();
}
@@ -408,8 +415,6 @@ bool CBotFunction::Execute(CBotVar** ppVars, CBotStack* &pj, CBotVar* pInstance)
pile->IncState();
}
- if ( pile->IfStep() ) return false;
-
if ( !m_block->Execute(pile) )
{
if ( pile->GetError() < 0 )
@@ -438,7 +443,22 @@ void CBotFunction::RestoreState(CBotVar** ppVars, CBotStack* &pj, CBotVar* pInst
pile2->Delete();
}
- m_param->RestoreState(pile2, true); // parameters
+ if ( pile->GetState() == 0 )
+ {
+ if (m_param != nullptr)
+ {
+ CBotStack* pile3b = pile2->RestoreStack();
+
+ if (pile3b != nullptr && pile3b->GetState() == 1)
+ m_param->RestoreState(pile2, true); // restore executing default arguments
+ else
+ m_param->RestoreState(pile2, false); // restore parameter IDs
+ }
+ return;
+ }
+
+ if (m_param != nullptr)
+ m_param->RestoreState(pile2, false); // restore parameter IDs
if ( !m_MasterClass.empty() )
{
@@ -670,7 +690,10 @@ int CBotFunction::DoCall(CBotProgram* program, const std::list<CBotFunction*>& l
if ( pStk1->GetState() == 0 )
{
- if ( !pt->m_MasterClass.empty() )
+ // stack for parameters and default args
+ CBotStack* pStk3b = pStk3->AddStack();
+
+ if (pStk3b->GetState() == 0 && !pt->m_MasterClass.empty())
{
CBotVar* pInstance = program->m_thisVar;
// make "this" known
@@ -696,20 +719,21 @@ int CBotFunction::DoCall(CBotProgram* program, const std::list<CBotFunction*>& l
pThis->SetUniqNum(-2);
pStk1->AddVar(pThis);
}
+ pStk3b->SetState(1); // set 'this' was created
// initializes the variables as parameters
if (pt->m_param != nullptr)
{
- if (!pt->m_param->Execute(ppVars, pStk3)) // interupts only if error on a default value
+ if (!pt->m_param->Execute(ppVars, pStk3)) // interupt here
{
- if ( pt->m_pProg != program )
+ if (!pStk3->IsOk() && pt->m_pProg != program)
{
pStk3->SetPosError(pToken); // indicates the error on the procedure call
}
- return pStack->Return(pStk3);
+ return false;
}
}
-
+ pStk3b->Delete(); // done with param stack
pStk1->IncState();
}
@@ -778,12 +802,21 @@ void CBotFunction::RestoreCall(const std::list<CBotFunction*>& localFunctionList
if ( pStk1->GetState() == 0 )
{
- pt->m_param->RestoreState(pStk3, true);
+ if (pt->m_param != nullptr)
+ {
+ CBotStack* pStk3b = pStk3->RestoreStack();
+
+ if (pStk3b != nullptr && pStk3b->GetState() == 1)
+ pt->m_param->RestoreState(pStk3, true); // restore executing default arguments
+ else
+ pt->m_param->RestoreState(pStk3, false); // restore parameter IDs
+ }
return;
}
// initializes the variables as parameters
- pt->m_param->RestoreState(pStk3, false);
+ if (pt->m_param != nullptr)
+ pt->m_param->RestoreState(pStk3, false); // restore parameter IDs
pt->m_block->RestoreState(pStk3, true);
}
}
@@ -811,33 +844,42 @@ int CBotFunction::DoCall(const std::list<CBotFunction*>& localFunctionList, long
if ( pStk->GetState() == 0 )
{
- // sets the variable "this" on the stack
- CBotVar* pthis = CBotVar::Create("this", CBotTypNullPointer);
- pthis->Copy(pThis, false);
- pthis->SetUniqNum(-2); // special value
- pStk->AddVar(pthis);
-
- CBotClass* pClass = pThis->GetClass()->GetParent();
- if ( pClass )
+ // stack for parameters and default args
+ CBotStack* pStk3b = pStk3->AddStack();
+
+ if (pStk3b->GetState() == 0)
{
- // sets the variable "super" on the stack
- CBotVar* psuper = CBotVar::Create("super", CBotTypNullPointer);
- psuper->Copy(pThis, false); // in fact identical to "this"
- psuper->SetUniqNum(-3); // special value
- pStk->AddVar(psuper);
+ // sets the variable "this" on the stack
+ CBotVar* pthis = CBotVar::Create("this", CBotTypNullPointer);
+ pthis->Copy(pThis, false);
+ pthis->SetUniqNum(-2); // special value
+ pStk->AddVar(pthis);
+
+ CBotClass* pClass = pThis->GetClass()->GetParent();
+ if ( pClass )
+ {
+ // sets the variable "super" on the stack
+ CBotVar* psuper = CBotVar::Create("super", CBotTypNullPointer);
+ psuper->Copy(pThis, false); // in fact identical to "this"
+ psuper->SetUniqNum(-3); // special value
+ pStk->AddVar(psuper);
+ }
}
+ pStk3b->SetState(1); // set 'this' was created
+
// initializes the variables as parameters
if (pt->m_param != nullptr)
{
- if (!pt->m_param->Execute(ppVars, pStk3)) // interupts only if error on a default value
+ if (!pt->m_param->Execute(ppVars, pStk3)) // interupt here
{
- if ( pt->m_pProg != pProgCurrent )
+ if (!pStk3->IsOk() && pt->m_pProg != pProgCurrent)
{
pStk3->SetPosError(pToken); // indicates the error on the procedure call
}
- return pStack->Return(pStk3);
+ return false;
}
}
+ pStk3b->Delete(); // done with param stack
pStk->IncState();
}
@@ -905,7 +947,21 @@ bool CBotFunction::RestoreCall(const std::list<CBotFunction*>& localFunctionList
CBotStack* pStk3 = pStk->RestoreStack(nullptr); // to set parameters passed
if ( pStk3 == nullptr ) return true;
- pt->m_param->RestoreState(pStk3, true); // parameters
+ if ( pStk->GetState() == 0 )
+ {
+ if (pt->m_param != nullptr)
+ {
+ CBotStack* pStk3b = pStk3->RestoreStack();
+ if (pStk3b != nullptr && pStk3b->GetState() == 1)
+ pt->m_param->RestoreState(pStk3, true); // restore executing default arguments
+ else
+ pt->m_param->RestoreState(pStk3, false); // restore parameter IDs
+ }
+ return true;
+ }
+
+ if (pt->m_param != nullptr)
+ pt->m_param->RestoreState(pStk3, false); // restore parameter IDs
if ( pStk->GetState() > 1 && // latching is effective?
pt->m_bSynchro )
--
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