From b42c1376e5efa8def4c6e3621f6a69714102c5b9 Mon Sep 17 00:00:00 2001 From: Grunaka Date: Sun, 8 Nov 2015 17:49:25 +0100 Subject: [PATCH] Move CBotToken class in its own header and source files. --- src/CBot/CBotDll.h | 152 +--------------------- src/CBot/CBotToken.cpp | 78 ++++++------ src/CBot/CBotToken.h | 276 +++++++++++++++++++++++++++++++++++++--- src/CBot/CMakeLists.txt | 22 ++-- src/script/script.cpp | 1 + 5 files changed, 310 insertions(+), 219 deletions(-) diff --git a/src/CBot/CBotDll.h b/src/CBot/CBotDll.h index 57ee15b7..dbeaf8f8 100644 --- a/src/CBot/CBotDll.h +++ b/src/CBot/CBotDll.h @@ -26,8 +26,13 @@ #pragma once -#include +// Modules inlcude #include "resource.h" + +// Local include + +// Global include +#include #include #include @@ -990,151 +995,6 @@ public: }; -#define MAXDEFNUM 1000 // limited number of DefineNum - -///////////////////////////////////////////////////////////////////////////////////// -// Token management (tokens) - -#define TokenTypKeyWord 1 // a keyword of the language (see TokenKeyWord) -#define TokenTypNum 2 // number -#define TokenTypString 3 // string -#define TokenTypVar 4 // a variable name -#define TokenTypDef 5 // value according DefineNum - -#define TokenKeyWord 2000 // keywords of the language -#define TokenKeyDeclare 2100 // keywords of declarations (int, float,..) -#define TokenKeyVal 2200 // keywords representing the value (true, false, null, nan) -#define TokenKeyOp 2300 // operators - -/** - * \class CBotToken - * Responsible for token management - */ -class CBotToken -{ -private: - static - CBotStringArray m_ListKeyWords; // list of keywords of language - static - int m_ListIdKeyWords[200]; // the corresponding codes - - static - CBotStringArray m_ListKeyDefine; // names defined by a DefineNum - static - long m_ListKeyNums[MAXDEFNUM]; // the ​​associated values - -private: - CBotToken* m_next; // following in the list - CBotToken* m_prev; - int m_type; // type of Token - long m_IdKeyWord; // number of the keyword if it is a - // or value of the "define" - - CBotString m_Text; // word found as token - CBotString m_Sep; // following separators - - int m_start; // position in the original text (program) - int m_end; // the same for the end of the token - - /** - * \brief Check whether given parameter is a keyword - */ - static - int GetKeyWords(const char* w); // is it a keyword? - static - bool GetKeyDefNum(const char* w, CBotToken* &token); - - /** - * \brief Loads the list of keywords - */ - static - void LoadKeyWords(); - -public: - /** - * \brief Constructors - */ - CBotToken(); - CBotToken(const CBotToken* pSrc); - CBotToken(const CBotString& mot, const CBotString& sep, int start=0, int end=0); - CBotToken(const char* mot, const char* sep = nullptr); - - /** - * \brief Destructor - */ - ~CBotToken(); - /** - * \brief Returns the type of token - */ - int GetType(); - - /** - * \brief makes the string corresponding to this token - */ - CBotString& GetString(); - - /** - * \brief makes the following separator token - */ - CBotString& GetSep(); - - /** - * \brief position of the beginning in the text - */ - int GetStart(); - /** - * \brief end position in the text - */ - int GetEnd(); - - /** - * \brief gives the next token in the list - */ - CBotToken* GetNext(); - /** - * \brief gives the previous token in a list - */ - CBotToken* GetPrev(); - - /** - * \brief transforms the entire program - */ - static - CBotToken* CompileTokens(const char* p, int& error); - - /** - * \brief releases the list - */ - static - void Delete(CBotToken* pToken); // libère la liste - - - // fonctions non utiles en export - static - bool DefineNum(const char* name, long val); - void SetString(const char* name); - - void SetPos(int start, int end); - long GetIdKey(); - /** - * \brief adds a token (a copy) - */ - void AddNext(CBotToken* p); - - /** - * finds the next token - */ - static - CBotToken* NextToken(char* &program, int& error, bool first = false); - - const CBotToken& - operator=(const CBotToken& src); - - static - void Free(); -}; - - /* //////////////////////////////////////////////////////////////////////// diff --git a/src/CBot/CBotToken.cpp b/src/CBot/CBotToken.cpp index 12529467..2b06c0ff 100644 --- a/src/CBot/CBotToken.cpp +++ b/src/CBot/CBotToken.cpp @@ -17,24 +17,21 @@ * along with this program. If not, see http://gnu.org/licenses */ - -////////////////////////////////////////////////////////////////// -// Managing Tokens -// the text of a program is first transformed -// into a sequence of tokens for easy interpretation -// it will only treat the case as an error -// where there is an illegal character in a string - - +// Modules inlcude #include "CBot.h" + +// Local include + +// Global include #include +//////////////////////////////////////////////////////////////////////////////// CBotStringArray CBotToken::m_ListKeyWords; int CBotToken::m_ListIdKeyWords[200]; CBotStringArray CBotToken::m_ListKeyDefine; long CBotToken::m_ListKeyNums[MAXDEFNUM]; -//! contructors +//////////////////////////////////////////////////////////////////////////////// CBotToken::CBotToken() { m_next = nullptr; @@ -43,6 +40,7 @@ CBotToken::CBotToken() m_IdKeyWord = -1; } +//////////////////////////////////////////////////////////////////////////////// CBotToken::CBotToken(const CBotToken* pSrc) { m_next = nullptr; @@ -71,6 +69,7 @@ CBotToken::CBotToken(const CBotToken* pSrc) } } +//////////////////////////////////////////////////////////////////////////////// CBotToken::CBotToken(const CBotString& mot, const CBotString& sep, int start, int end) { m_Text = mot; // word (mot) found as token @@ -95,17 +94,20 @@ CBotToken::CBotToken(const char* mot, const char* sep) m_IdKeyWord = -1; } +//////////////////////////////////////////////////////////////////////////////// CBotToken::~CBotToken() { delete m_next; // recursive m_next = nullptr; } +//////////////////////////////////////////////////////////////////////////////// void CBotToken::Free() { m_ListKeyDefine.SetSize(0); } +//////////////////////////////////////////////////////////////////////////////// const CBotToken& CBotToken::operator=(const CBotToken& src) { delete m_next; @@ -123,7 +125,7 @@ const CBotToken& CBotToken::operator=(const CBotToken& src) return *this; } - +//////////////////////////////////////////////////////////////////////////////// int CBotToken::GetType() { if (this == nullptr) return 0; @@ -131,69 +133,66 @@ int CBotToken::GetType() return m_type; } +//////////////////////////////////////////////////////////////////////////////// long CBotToken::GetIdKey() { return m_IdKeyWord; } +//////////////////////////////////////////////////////////////////////////////// CBotToken* CBotToken::GetNext() { if (this == nullptr) return nullptr; return m_next; } +//////////////////////////////////////////////////////////////////////////////// CBotToken* CBotToken::GetPrev() { if (this == nullptr) return nullptr; return m_prev; } -void CBotToken::AddNext(CBotToken* p) -{ - CBotToken* n = new CBotToken(p); - CBotToken* pt = this; - - while ( pt->m_next != nullptr ) pt = pt->m_next; - - pt->m_next = n; - n->m_prev = pt; -} - - -CBotString& CBotToken::GetString() +//////////////////////////////////////////////////////////////////////////////// +CBotString CBotToken::GetString() { return m_Text; } -CBotString& CBotToken::GetSep() +//////////////////////////////////////////////////////////////////////////////// +CBotString CBotToken::GetSep() { return m_Sep; } +//////////////////////////////////////////////////////////////////////////////// void CBotToken::SetString(const char* name) { m_Text = name; } - +//////////////////////////////////////////////////////////////////////////////// int CBotToken::GetStart() { if (this == nullptr) return -1; return m_start; } +//////////////////////////////////////////////////////////////////////////////// int CBotToken::GetEnd() { if (this == nullptr) return -1; return m_end; } +//////////////////////////////////////////////////////////////////////////////// void CBotToken::SetPos(int start, int end) { m_start = start; m_end = end; } +//////////////////////////////////////////////////////////////////////////////// bool CharInList(const char c, const char* list) { int i = 0; @@ -205,6 +204,7 @@ bool CharInList(const char c, const char* list) } } +//////////////////////////////////////////////////////////////////////////////// bool Char2InList(const char c, const char cc, const char* list) { int i = 0; @@ -225,11 +225,7 @@ static char num[] = "0123456789"; // point (single) i static char hexnum[] = "0123456789ABCDEFabcdef"; static char nch[] = "\"\r\n\t"; // forbidden in chains -//static char* duo = "+=-=*=/===!=<=>=++--///**/||&&"; // double operators - -// looking for the next token in a sentence -// do not start with separators -// which are made in the previous token +//////////////////////////////////////////////////////////////////////////////// CBotToken* CBotToken::NextToken(char* &program, int& error, bool first) { CBotString mot; // the word which is found @@ -389,6 +385,7 @@ bis: } } +//////////////////////////////////////////////////////////////////////////////// CBotToken* CBotToken::CompileTokens(const char* program, int& error) { CBotToken *nxt, *prv, *tokenbase; @@ -431,14 +428,13 @@ CBotToken* CBotToken::CompileTokens(const char* program, int& error) return tokenbase; } +//////////////////////////////////////////////////////////////////////////////// void CBotToken::Delete(CBotToken* pToken) { delete pToken; } - -// search if a word is part of the keywords - +//////////////////////////////////////////////////////////////////////////////// int CBotToken::GetKeyWords(const char* w) { int i; @@ -458,6 +454,7 @@ int CBotToken::GetKeyWords(const char* w) return -1; } +//////////////////////////////////////////////////////////////////////////////// bool CBotToken::GetKeyDefNum(const char* w, CBotToken* &token) { int i; @@ -476,12 +473,7 @@ bool CBotToken::GetKeyDefNum(const char* w, CBotToken* &token) return false; } - -/// \todo Fixme Figure out how this should work. - -// recreates the list of keywords and its IDs basing on some resources -// defines of TokenKey.. are in CBotDll.h - +//////////////////////////////////////////////////////////////////////////////// void CBotToken::LoadKeyWords() { CBotString s; @@ -517,6 +509,7 @@ void CBotToken::LoadKeyWords() } } +//////////////////////////////////////////////////////////////////////////////// bool CBotToken::DefineNum(const char* name, long val) { int i; @@ -533,6 +526,7 @@ bool CBotToken::DefineNum(const char* name, long val) return true; } +//////////////////////////////////////////////////////////////////////////////// bool IsOfType(CBotToken* &p, int type1, int type2) { if (p->GetType() == type1 || @@ -543,8 +537,8 @@ bool IsOfType(CBotToken* &p, int type1, int type2) } return false; } -// Same with any number of arguments -// There must be a zero as the last argument + +//////////////////////////////////////////////////////////////////////////////// bool IsOfTypeList(CBotToken* &p, int type1, ...) { int i = type1; diff --git a/src/CBot/CBotToken.h b/src/CBot/CBotToken.h index 3e0269ec..b82cdfea 100644 --- a/src/CBot/CBotToken.h +++ b/src/CBot/CBotToken.h @@ -17,28 +17,264 @@ * along with this program. If not, see http://gnu.org/licenses */ - -// interpreter of the lanuage CBot for game COLOBOT -// writing a program is first transformed into a list of tokens -// before tackling the compiler itself -// for example -// int var = 3 * ( pos.y + x ) -// is decomposed into (each line is a token) -// int -// var -// = -// 3 -// * -// ( -// pos.y -// + -// x -// ) - #pragma once -class CBotToken; +// Modules inlcude +#include "CBotDll.h" +// Local include + +// Global include + +///////////////////////////////////////////////////////////////////////////////////// +// Token management (tokens) + +#define TokenTypKeyWord 1 // a keyword of the language (see TokenKeyWord) +#define TokenTypNum 2 // number +#define TokenTypString 3 // string +#define TokenTypVar 4 // a variable name +#define TokenTypDef 5 // value according DefineNum + +#define TokenKeyWord 2000 // keywords of the language +#define TokenKeyDeclare 2100 // keywords of declarations (int, float,..) +#define TokenKeyVal 2200 // keywords representing the value (true, false, null, nan) +#define TokenKeyOp 2300 // operators + +#define MAXDEFNUM 1000 // limited number of DefineNum + +/** + * \class CBotToken + * Responsible for token management. A CBot program is a text string. This string + * is first transformed into a list of token. It will only treat the case as an + * error where there is an illegal character in a string. + * For example : + * int var = 3 * ( pos.y + x ) + * is decomposed into (each line is a token) + * int + * var + * = + * 3 + * * + * ( + * pos.y + * + + * x + * ) + */ + +class CBotToken +{ + +public: + + /*! + * \brief CBotToken Default Constructor. + */ + CBotToken(); + CBotToken(const CBotToken* pSrc); + CBotToken(const CBotString& mot, + const CBotString& sep, + int start=0, + int end=0); + CBotToken(const char* mot, const char* sep = nullptr); + + /*! + * \brief ~CBotToken Destructor. Be careful when you delete a CBotToken that + * is in a linked list all the following CBotToken will be deleted too. + */ + ~CBotToken(); + + /*! + * \brief GetType Return the token type or the keyword id. + * \return The token type or the keyword id. + */ + int GetType(); + + /*! + * \brief GetString Return the token string. + * \return The token string if a string has been set. An empty string + * otherwise. + */ + CBotString GetString(); + + /*! + * \brief SetString Set the token string. + * \param [in] name The new string to set. + */ + void SetString(const char* name); + + /*! + * \brief GetSep Return the token separator. + * \return The token separator a separator has been set. An empty separator + * otherwise. + */ + CBotString GetSep(); + + /*! + * \brief GetStart Return the start position of the string token in the + * original CBotProgram. + * \return The start position of the string token or -1 if no string has + * been set. + */ + int GetStart(); + + /*! + * \brief GetEnd Return the end position of the string token in the + * original CBotProgram. + * \return The start position of the string token or -1 if no string has + * been set. + */ + int GetEnd(); + + /*! + * \brief GetNext Gives the next CBotToken in the list. + * \return The next CBotToken if set nullptr otherwise. + */ + CBotToken* GetNext(); + + /*! + * \brief GetPrev Gives the previous CBotToken in the list. + * \return The previous CBotToken if set nullptr otherwise. + */ + CBotToken* GetPrev(); + + /*! + * \brief SetPos Set the token position in the CBot program. + * \param [in] start The start position of the token. + * \param [in] end The end position of the token. + */ + void SetPos(int start, int end); + + /*! + * \brief GetIdKey Get the token id key. + * \return The id key. + */ + long GetIdKey(); + + /*! + * \brief operator = + * \param [in] src The CBotToken to copy. + * \return The CBotToken with the copied value. + */ + const CBotToken& operator=(const CBotToken& src); + + /*! + * \brief CompileTokens This function will transform the entire CBot program + * in CBotToken. If an error occured during the processing an error number + * will be set. Each CBotToken will be linked with the previous one and the + * next one. + * \param [in] p The program string. + * \param [out] error The error code. + * \return The first token of the linked liste. + * \todo Replace the error code by an enum. + */ + static CBotToken* CompileTokens(const char* p, int& error); + + /*! + * \brief NextToken Looking for the next token in the string. The string must + * not start with separators. The separator is part of the previous token. + * \param [in] program The program string. + * \param [out] error The error code. + * \param [in] first True if this is the first call false othewise. + * \return A CBotTOken. + */ + static CBotToken* NextToken(char* &program, int& error, bool first = false); + + /** + * \brief Delete Releases the CBotToken linked list. + * \deprecated This function is deprecated because it only delete a pointer. + * \todo Remove this function. + */ + static void Delete(CBotToken* pToken); + + /*! + * \brief DefineNum This function define a language keyword with an associated + * number. + * \param [in] name The new word to define. + * \param [in] val The number associated with the keyword. + * \return Ture if the number is available false oterhwise. + */ + static bool DefineNum(const char* name, long val); + + /*! + * \brief Free Free the array created with DefineNum. + * \see DefineNum + */ + static void Free(); + +private: + + //! The next token in the linked list + CBotToken* m_next; // following in the list + //! The previous token in the linked list + CBotToken* m_prev; + //! The token type + int m_type; // type of Token + //! The id of the keyword + long m_IdKeyWord; + + //! The token string + CBotString m_Text; + //! The token separator + CBotString m_Sep; + + //! The strat position of the token in the CBotProgram + int m_start; + //! The end position of the token in the CBotProgram + int m_end; + + /*! + * \brief GetKeyWords Check if the word is a keyword. + * \param w The word to compare. + * \return -1 if this is not a keyword the keyword number otherwise. + */ + static int GetKeyWords(const char* w); // is it a keyword? + + /*! + * \brief GetKeyDefNum Check if this is a defined word and set the defined + * word type in a CBotToken. + * \param [in] w The word to compaire. + * \param [out] token The token in which the type will be set. + * \return True if the defined word is found false otherwise. + */ + static bool GetKeyDefNum(const char* w, CBotToken* &token); + + /*! + * \brief LoadKeyWords Loads the list of keywords. The list of keyword is + * CBotString::s_keywordString. This keywords are keywords languages (if, +, + * for, while, case, extern ...) + * \todo Fixme Figure out how this should work. + */ + static void LoadKeyWords(); + + //! List of keywords of the CBot language (if, +, for, while, case, extern ...) + static CBotStringArray m_ListKeyWords; + //! List of id correponding to the keywords of the CBot language + static int m_ListIdKeyWords[200]; + + //! List of CBot language error and list of colobot specific keywords + //! This keywords are defined in : + //! - void CScriptFunctions::Init() + //! - void CBotProgram::Init() + static CBotStringArray m_ListKeyDefine; + //! List of id correponding to the defined words + static long m_ListKeyNums[MAXDEFNUM]; + +}; + +/*! + * \brief IsOfType This function tell if a token is of a specific type. + * \param [in] p The token to compare. + * \param [in] type1 First token type to comapre to the token. + * \param [in] type2 Second token type to comapre to the token. + * \return True if the type of the token match one of a parameter. + */ extern bool IsOfType(CBotToken* &p, int type1, int type2 = -1); -extern bool IsOfTypeList(CBotToken* &p, int type1, ...); +/*! + * \brief IsOfType This function tell if a token is of a specific type. + * \param [in] p The token to compare. + * \param [in] type1 The list of token type to comapre to the token. + * \return True if the type of the token match one of a parameter. + */ +extern bool IsOfTypeList(CBotToken* &p, int type1, ...); diff --git a/src/CBot/CMakeLists.txt b/src/CBot/CMakeLists.txt index 8bb8a5cf..dc7707f7 100644 --- a/src/CBot/CMakeLists.txt +++ b/src/CBot/CMakeLists.txt @@ -1,15 +1,15 @@ set(SOURCES -CBot.cpp -CBotClass.cpp -CBotFunction.cpp -CBotIf.cpp -CBotProgram.cpp -CBotStack.cpp -CBotString.cpp -CBotToken.cpp -CBotTwoOpExpr.cpp -CBotVar.cpp -CBotWhile.cpp + CBot.cpp + CBotClass.cpp + CBotFunction.cpp + CBotIf.cpp + CBotProgram.cpp + CBotStack.cpp + CBotString.cpp + CBotToken.cpp + CBotTwoOpExpr.cpp + CBotVar.cpp + CBotWhile.cpp ) if(CBOT_STATIC) diff --git a/src/script/script.cpp b/src/script/script.cpp index 9bfb1dac..4ba1f173 100644 --- a/src/script/script.cpp +++ b/src/script/script.cpp @@ -42,6 +42,7 @@ #include "ui/controls/interface.h" #include "ui/controls/list.h" +#include "CBot/CBotToken.h" const int CBOT_IPF = 100; // CBOT: default number of instructions / frame