From 7b200a09228a5c6683d6556102b6413716a661f6 Mon Sep 17 00:00:00 2001 From: Grunaka Date: Sun, 22 Nov 2015 15:47:46 +0100 Subject: [PATCH] Moving global CompileParams, TypeCompatible and TypesCompatibles from CBot.cpp to CBotInstrUtils.cpp. --- src/CBot/CBot.cpp | 139 -------------------- src/CBot/CBot.h | 5 - src/CBot/CBotInstr/CBotClassInst.cpp | 3 + src/CBot/CBotInstr/CBotExpression.cpp | 3 + src/CBot/CBotInstr/CBotFunction.cpp | 2 + src/CBot/CBotInstr/CBotInstrMethode.cpp | 2 + src/CBot/CBotInstr/CBotInstrUtils.cpp | 167 ++++++++++++++++++++++++ src/CBot/CBotInstr/CBotInstrUtils.h | 61 +++++++++ src/CBot/CBotInstr/CBotListArray.cpp | 2 + src/CBot/CBotInstr/CBotNew.cpp | 2 + src/CBot/CBotInstr/CBotReturn.cpp | 3 + src/CBot/CBotInstr/CBotTwoOpExpr.cpp | 3 + src/CBot/CMakeLists.txt | 1 + 13 files changed, 249 insertions(+), 144 deletions(-) create mode 100644 src/CBot/CBotInstr/CBotInstrUtils.cpp create mode 100644 src/CBot/CBotInstr/CBotInstrUtils.h diff --git a/src/CBot/CBot.cpp b/src/CBot/CBot.cpp index 1822df7b..da8109f4 100644 --- a/src/CBot/CBot.cpp +++ b/src/CBot/CBot.cpp @@ -83,145 +83,6 @@ // Global include #include -////////////////////////////////////////////////////////////////////////////////////////// - -// compile a list of parameters - -CBotInstr* CompileParams(CBotToken* &p, CBotCStack* pStack, CBotVar** ppVars) -{ - bool first = true; - CBotInstr* ret = nullptr; // to return to the list - - CBotCStack* pile = pStack; - int i = 0; - - if (IsOfType(p, ID_OPENPAR)) - { - int start, end; - if (!IsOfType(p, ID_CLOSEPAR)) while (true) - { - start = p->GetStart(); - pile = pile->TokenStack(); // keeps the result on the stack - - if (first) pStack->SetStartError(start); - first = false; - - CBotInstr* param = CBotExpression::Compile(p, pile); - end = p->GetStart(); - - if (!pile->IsOk()) - { - return pStack->Return(nullptr, pile); - } - - if (ret == nullptr) ret = param; - else ret->AddNext(param); // construct the list - - if (param != nullptr) - { - if (pile->GetTypResult().Eq(99)) - { - delete pStack->TokenStack(); - pStack->SetError(TX_VOID, p->GetStart()); - return nullptr; - } - ppVars[i] = pile->GetVar(); - ppVars[i]->GetToken()->SetPos(start, end); - i++; - - if (IsOfType(p, ID_COMMA)) continue; // skips the comma - if (IsOfType(p, ID_CLOSEPAR)) break; - } - - pStack->SetError(TX_CLOSEPAR, p->GetStart()); - delete pStack->TokenStack(); - return nullptr; - } - } - ppVars[i] = nullptr; - return ret; -} - -///////////////////////////////////////////////////////////// -// check if two results are consistent to make an operation - -bool TypeCompatible(CBotTypResult& type1, CBotTypResult& type2, int op) -{ - int t1 = type1.GetType(); - int t2 = type2.GetType(); - - int max = (t1 > t2) ? t1 : t2; - - if (max == 99) return false; // result is void? - - // special case for strin concatenation - if (op == ID_ADD && max >= CBotTypString) return true; - if (op == ID_ASSADD && max >= CBotTypString) return true; - if (op == ID_ASS && t1 == CBotTypString) return true; - - if (max >= CBotTypBoolean) - { - if ( (op == ID_EQ || op == ID_NE) && - (t1 == CBotTypPointer && t2 == CBotTypNullPointer)) return true; - if ( (op == ID_EQ || op == ID_NE || op == ID_ASS) && - (t2 == CBotTypPointer && t1 == CBotTypNullPointer)) return true; - if ( (op == ID_EQ || op == ID_NE) && - (t1 == CBotTypArrayPointer && t2 == CBotTypNullPointer)) return true; - if ( (op == ID_EQ || op == ID_NE || op == ID_ASS) && - (t2 == CBotTypArrayPointer && t1 == CBotTypNullPointer)) return true; - if (t2 != t1) return false; - if (t1 == CBotTypArrayPointer) return type1.Compare(type2); - if (t1 == CBotTypPointer || - t1 == CBotTypClass || - t1 == CBotTypIntrinsic ) - { - CBotClass* c1 = type1.GetClass(); - CBotClass* c2 = type2.GetClass(); - - return c1->IsChildOf(c2) || c2->IsChildOf(c1); - // accept the case in reverse - // the transaction will be denied at runtime if the pointer is not - // compatible - } - - return true; - } - - type1.SetType(max); - type2.SetType(max); - return true; -} - -// check if two variables are compatible for parameter passing - -bool TypesCompatibles(const CBotTypResult& type1, const CBotTypResult& type2) -{ - int t1 = type1.GetType(); - int t2 = type2.GetType(); - - if (t1 == CBotTypIntrinsic) t1 = CBotTypClass; - if (t2 == CBotTypIntrinsic) t2 = CBotTypClass; - - int max = (t1 > t2) ? t1 : t2; - - if (max == 99) return false; // result is void? - - if (max >= CBotTypBoolean) - { - if (t2 != t1) return false; - - if (max == CBotTypArrayPointer) - return TypesCompatibles(type1.GetTypElem(), type2.GetTypElem()); - - if (max == CBotTypClass || max == CBotTypPointer) - return type1.GetClass() == type2.GetClass() ; - - return true ; - } - return true; -} - - ///////////////////////////////////////////////////////////////////////////////////// // file management diff --git a/src/CBot/CBot.h b/src/CBot/CBot.h index a732d7ae..2f2bdffa 100644 --- a/src/CBot/CBot.h +++ b/src/CBot/CBot.h @@ -54,11 +54,6 @@ class CBotDefParam; // paramerer list of a function extern bool SaveVar(FILE* pf, CBotVar* pVar); -extern CBotInstr* CompileParams(CBotToken* &p, CBotCStack* pStack, CBotVar** ppVars); - -extern bool TypeCompatible( CBotTypResult& type1, CBotTypResult& type2, int op = 0 ); -extern bool TypesCompatibles( const CBotTypResult& type1, const CBotTypResult& type2 ); - extern bool WriteWord(FILE* pf, unsigned short w); extern bool ReadWord(FILE* pf, unsigned short& w); extern bool ReadLong(FILE* pf, long& w); diff --git a/src/CBot/CBotInstr/CBotClassInst.cpp b/src/CBot/CBotInstr/CBotClassInst.cpp index 5d2e0a66..d556dd77 100644 --- a/src/CBot/CBotInstr/CBotClassInst.cpp +++ b/src/CBot/CBotInstr/CBotClassInst.cpp @@ -19,6 +19,9 @@ // Modules inlcude #include "CBotClassInst.h" + +#include "CBotInstr/CBotInstrUtils.h" + #include "CBotLeftExprVar.h" #include "CBotTwoOpExpr.h" #include "CBotInstArray.h" diff --git a/src/CBot/CBotInstr/CBotExpression.cpp b/src/CBot/CBotInstr/CBotExpression.cpp index b6b97837..a3612426 100644 --- a/src/CBot/CBotInstr/CBotExpression.cpp +++ b/src/CBot/CBotInstr/CBotExpression.cpp @@ -19,6 +19,9 @@ // Modules inlcude #include "CBotExpression.h" + +#include "CBotInstr/CBotInstrUtils.h" + #include "CBotTwoOpExpr.h" #include "CBotStack.h" diff --git a/src/CBot/CBotInstr/CBotFunction.cpp b/src/CBot/CBotInstr/CBotFunction.cpp index d325020e..0a629c39 100644 --- a/src/CBot/CBotInstr/CBotFunction.cpp +++ b/src/CBot/CBotInstr/CBotFunction.cpp @@ -21,6 +21,8 @@ // Modules inlcude #include "CBotFunction.h" +#include "CBotInstr/CBotInstrUtils.h" + #include "CBot.h" #include "CBotInstr/CBotBlock.h" diff --git a/src/CBot/CBotInstr/CBotInstrMethode.cpp b/src/CBot/CBotInstr/CBotInstrMethode.cpp index 46adf723..26f188f8 100644 --- a/src/CBot/CBotInstr/CBotInstrMethode.cpp +++ b/src/CBot/CBotInstr/CBotInstrMethode.cpp @@ -20,6 +20,8 @@ // Modules inlcude #include "CBotInstrMethode.h" +#include "CBotInstr/CBotInstrUtils.h" + #include "CBotStack.h" #include "CBotCStack.h" #include "CBotClass.h" diff --git a/src/CBot/CBotInstr/CBotInstrUtils.cpp b/src/CBot/CBotInstr/CBotInstrUtils.cpp new file mode 100644 index 00000000..576cfa30 --- /dev/null +++ b/src/CBot/CBotInstr/CBotInstrUtils.cpp @@ -0,0 +1,167 @@ +/* + * This file is part of the Colobot: Gold Edition source code + * Copyright (C) 2001-2015, Daniel Roux, EPSITEC SA & TerranovaTeam + * http://epsitec.ch; http://colobot.info; http://github.com/colobot + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://gnu.org/licenses + */ + +// Modules inlcude +#include "CBotInstrUtils.h" + +#include "CBotToken.h" +#include "CBotCStack.h" +#include "CBotTypResult.h" +#include "CBotExpression.h" +#include "CBotClass.h" + +#include "CBotVar/CBotVar.h" + +#include "resource.h" + +// Local include + +// Global include + +//////////////////////////////////////////////////////////////////////////////// +CBotInstr* CompileParams(CBotToken* &p, CBotCStack* pStack, CBotVar** ppVars) +{ + bool first = true; + CBotInstr* ret = nullptr; // to return to the list + + CBotCStack* pile = pStack; + int i = 0; + + if (IsOfType(p, ID_OPENPAR)) + { + int start, end; + if (!IsOfType(p, ID_CLOSEPAR)) while (true) + { + start = p->GetStart(); + pile = pile->TokenStack(); // keeps the result on the stack + + if (first) pStack->SetStartError(start); + first = false; + + CBotInstr* param = CBotExpression::Compile(p, pile); + end = p->GetStart(); + + if (!pile->IsOk()) + { + return pStack->Return(nullptr, pile); + } + + if (ret == nullptr) ret = param; + else ret->AddNext(param); // construct the list + + if (param != nullptr) + { + if (pile->GetTypResult().Eq(99)) + { + delete pStack->TokenStack(); + pStack->SetError(TX_VOID, p->GetStart()); + return nullptr; + } + ppVars[i] = pile->GetVar(); + ppVars[i]->GetToken()->SetPos(start, end); + i++; + + if (IsOfType(p, ID_COMMA)) continue; // skips the comma + if (IsOfType(p, ID_CLOSEPAR)) break; + } + + pStack->SetError(TX_CLOSEPAR, p->GetStart()); + delete pStack->TokenStack(); + return nullptr; + } + } + ppVars[i] = nullptr; + return ret; +} + +//////////////////////////////////////////////////////////////////////////////// +bool TypeCompatible(CBotTypResult& type1, CBotTypResult& type2, int op) +{ + int t1 = type1.GetType(); + int t2 = type2.GetType(); + + int max = (t1 > t2) ? t1 : t2; + + if (max == 99) return false; // result is void? + + // special case for strin concatenation + if (op == ID_ADD && max >= CBotTypString) return true; + if (op == ID_ASSADD && max >= CBotTypString) return true; + if (op == ID_ASS && t1 == CBotTypString) return true; + + if (max >= CBotTypBoolean) + { + if ( (op == ID_EQ || op == ID_NE) && + (t1 == CBotTypPointer && t2 == CBotTypNullPointer)) return true; + if ( (op == ID_EQ || op == ID_NE || op == ID_ASS) && + (t2 == CBotTypPointer && t1 == CBotTypNullPointer)) return true; + if ( (op == ID_EQ || op == ID_NE) && + (t1 == CBotTypArrayPointer && t2 == CBotTypNullPointer)) return true; + if ( (op == ID_EQ || op == ID_NE || op == ID_ASS) && + (t2 == CBotTypArrayPointer && t1 == CBotTypNullPointer)) return true; + if (t2 != t1) return false; + if (t1 == CBotTypArrayPointer) return type1.Compare(type2); + if (t1 == CBotTypPointer || + t1 == CBotTypClass || + t1 == CBotTypIntrinsic ) + { + CBotClass* c1 = type1.GetClass(); + CBotClass* c2 = type2.GetClass(); + + return c1->IsChildOf(c2) || c2->IsChildOf(c1); + // accept the case in reverse + // the transaction will be denied at runtime if the pointer is not + // compatible + } + + return true; + } + + type1.SetType(max); + type2.SetType(max); + return true; +} + +//////////////////////////////////////////////////////////////////////////////// +bool TypesCompatibles(const CBotTypResult& type1, const CBotTypResult& type2) +{ + int t1 = type1.GetType(); + int t2 = type2.GetType(); + + if (t1 == CBotTypIntrinsic) t1 = CBotTypClass; + if (t2 == CBotTypIntrinsic) t2 = CBotTypClass; + + int max = (t1 > t2) ? t1 : t2; + + if (max == 99) return false; // result is void? + + if (max >= CBotTypBoolean) + { + if (t2 != t1) return false; + + if (max == CBotTypArrayPointer) + return TypesCompatibles(type1.GetTypElem(), type2.GetTypElem()); + + if (max == CBotTypClass || max == CBotTypPointer) + return type1.GetClass() == type2.GetClass() ; + + return true ; + } + return true; +} diff --git a/src/CBot/CBotInstr/CBotInstrUtils.h b/src/CBot/CBotInstr/CBotInstrUtils.h new file mode 100644 index 00000000..4365aca6 --- /dev/null +++ b/src/CBot/CBotInstr/CBotInstrUtils.h @@ -0,0 +1,61 @@ +/* + * This file is part of the Colobot: Gold Edition source code + * Copyright (C) 2001-2015, Daniel Roux, EPSITEC SA & TerranovaTeam + * http://epsitec.ch; http://colobot.info; http://github.com/colobot + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://gnu.org/licenses + */ + +#pragma once + +// Modules inlcude + +// Local include + +// Global include + +// Forward declaration +class CBotInstr; +class CBotToken; +class CBotCStack; +class CBotVar; +class CBotTypResult; + +/*! + * \brief CompileParams Compile a list of parameters. + * \param p + * \param pStack + * \param ppVars + * \return + */ +CBotInstr* CompileParams(CBotToken* &p, CBotCStack* pStack, CBotVar** ppVars); + +/*! + * \brief TypeCompatible Check if two results are consistent to make an + * operation. + * \param type1 + * \param type2 + * \param op + * \return + */ +bool TypeCompatible(CBotTypResult& type1, CBotTypResult& type2, int op = 0); + +/*! + * \brief TypesCompatibles Check if two variables are compatible for parameter + * passing. + * \param type1 + * \param type2 + * \return + */ +bool TypesCompatibles(const CBotTypResult& type1, const CBotTypResult& type2); diff --git a/src/CBot/CBotInstr/CBotListArray.cpp b/src/CBot/CBotInstr/CBotListArray.cpp index 6ac0d6a0..ce1a5f8a 100644 --- a/src/CBot/CBotInstr/CBotListArray.cpp +++ b/src/CBot/CBotInstr/CBotListArray.cpp @@ -20,6 +20,8 @@ // Modules inlcude #include "CBotListArray.h" +#include "CBotInstr/CBotInstrUtils.h" + #include "CBotExprNull.h" #include "CBotTwoOpExpr.h" diff --git a/src/CBot/CBotInstr/CBotNew.cpp b/src/CBot/CBotInstr/CBotNew.cpp index 6f7d8605..b7e36316 100644 --- a/src/CBot/CBotInstr/CBotNew.cpp +++ b/src/CBot/CBotInstr/CBotNew.cpp @@ -24,6 +24,8 @@ #include "CBotCStack.h" #include "CBotClass.h" +#include "CBotInstr/CBotInstrUtils.h" + #include "CBotVar/CBotVar.h" // Local include diff --git a/src/CBot/CBotInstr/CBotReturn.cpp b/src/CBot/CBotInstr/CBotReturn.cpp index 70c849d2..9f5d00f7 100644 --- a/src/CBot/CBotInstr/CBotReturn.cpp +++ b/src/CBot/CBotInstr/CBotReturn.cpp @@ -19,6 +19,9 @@ // Modules inlcude #include "CBotReturn.h" + +#include "CBotInstr/CBotInstrUtils.h" + #include "CBotExpression.h" #include "CBotStack.h" diff --git a/src/CBot/CBotInstr/CBotTwoOpExpr.cpp b/src/CBot/CBotInstr/CBotTwoOpExpr.cpp index 6a7477f4..0d97f407 100644 --- a/src/CBot/CBotInstr/CBotTwoOpExpr.cpp +++ b/src/CBot/CBotInstr/CBotTwoOpExpr.cpp @@ -19,6 +19,9 @@ // Modules inlcude #include "CBotTwoOpExpr.h" + +#include "CBotInstr/CBotInstrUtils.h" + #include "CBotParExpr.h" #include "CBotLogicExpr.h" #include "CBotExpression.h" diff --git a/src/CBot/CMakeLists.txt b/src/CBot/CMakeLists.txt index d8bda9ff..e2fa17ce 100644 --- a/src/CBot/CMakeLists.txt +++ b/src/CBot/CMakeLists.txt @@ -13,6 +13,7 @@ set(SOURCES CBotStringArray.cpp CBotTypResult.cpp CBotInstr/CBotInstr.cpp + CBotInstr/CBotInstrUtils.cpp CBotInstr/CBotWhile.cpp CBotInstr/CBotDo.cpp CBotInstr/CBotFor.cpp