Move CBotToken class in its own header and source files.

dev-time-step
Grunaka 2015-11-08 17:49:25 +01:00
parent 6492908cef
commit b42c1376e5
5 changed files with 310 additions and 219 deletions

View File

@ -26,8 +26,13 @@
#pragma once
#include <stdio.h>
// Modules inlcude
#include "resource.h"
// Local include
// Global include
#include <stdio.h>
#include <map>
#include <cstring>
@ -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();
};
/*
////////////////////////////////////////////////////////////////////////

View File

@ -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 <cstdarg>
////////////////////////////////////////////////////////////////////////////////
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;

View File

@ -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, ...);

View File

@ -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)

View File

@ -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