From a1c83c7d0a45fd6cbd8cbd1662aa0a0f0c7e1396 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Konopacki?= Date: Tue, 7 Aug 2012 12:46:19 +0200 Subject: CBot library comments further translations --- src/CBot/CBotDll.h | 790 ++++----- src/CBot/CBotIf.cpp | 320 ++-- src/CBot/CBotVar.cpp | 4493 +++++++++++++++++++++++++------------------------- 3 files changed, 2827 insertions(+), 2776 deletions(-) diff --git a/src/CBot/CBotDll.h b/src/CBot/CBotDll.h index f2e2297..47388a6 100644 --- a/src/CBot/CBotDll.h +++ b/src/CBot/CBotDll.h @@ -12,7 +12,10 @@ // * 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://www.gnu.org/licenses/.//////////////////////////////////////////////////////////////////////// +// * along with this program. If not, see http://www.gnu.org/licenses/. +//////////////////////////////////////////////////////////////////////// + +#pragma once #ifndef _CBOTDLL_H_ #define _CBOTDLL_H_ /** @@ -39,7 +42,7 @@ class CBotFunction; // user functions class CBotVar; // variables class CBotVarClass; // instance of class class CBotVarPointer; // pointer to an instance of class -class CBotCall; // fonctions +class CBotCall; // functions class CBotCallMethode; // methods class CBotDefParam; // parameter list class CBotCStack; // stack @@ -84,79 +87,80 @@ class CBotTypResult { public: /** - * \brief CBotTypResult constructor of an object + * \brief CBotTypResult constructor for simple types (CBotTypInt to CBotTypString) * \param type type of created result, see CBotType */ CBotTypResult(int type); + // for simple types (CBotTypInt à CBotTypString) - /** - * \brief CBotTypResult constructor for simple types (CBotTypInt to CBotTypString) - * \param type type of created result, see CBotType - * \param name - */ - // pour les types simples (CBotTypInt à CBotTypString) + CBotTypResult(int type, const char* name); - // pour les types pointeur et classe intrinsic + // for pointer types and intrinsic classes + CBotTypResult(int type, CBotClass* pClass); - // idem à partir de l'instance d'une classe + // for the instance of a class + CBotTypResult(int type, CBotTypResult elem); - // pour les tableaux de variables - + // for arrays of variables + CBotTypResult(const CBotTypResult& typ); - // pour les assignations + // for assignments + CBotTypResult(); - // pour par défaut + // for default + ~CBotTypResult(); int GivType(int mode = 0) const; - // rend le type CBotTyp* du résultat + // returns type CBotType* as a result void SetType(int n); - // modifie le type + // modifies a type CBotClass* GivClass() const; - // rend le pointeur à la classe (pour les CBotTypClass, CBotTypPointer) + // makes the pointer to the class (for CBotTypClass, CBotTypPointer) int GivLimite() const; - // rend la taille limite du tableau (CBotTypArray) + // returns limit size of table (CBotTypArray) void SetLimite(int n); - // fixe une limite au tableau + // set limit to the table void SetArray(int* max ); - // idem avec une liste de dimension (tableaux de tableaux) + // set limits for a list of dimensions (arrays of arrays) CBotTypResult& GivTypElem() const; - // rend le type des éléments du tableau (CBotTypArray) + // returns type of array elements (CBotTypArray) + // rend le type des éléments du tableau (CBotTypArray) bool Compare(const CBotTypResult& typ) const; - // compare si les types sont compatibles + // compares whether the types are compatible bool Eq(int type) const; - // compare le type + // compare type + + CBotTypResult& operator=(const CBotTypResult& src); + // copy a complete type in another - CBotTypResult& - operator=(const CBotTypResult& src); - // copie un type complet dans un autre private: int m_type; - CBotTypResult* m_pNext; // pour les types de types - CBotClass* m_pClass; // pour les dérivés de classe - int m_limite; // limitation des tableaux + CBotTypResult* m_pNext; // for the types of type + CBotClass* m_pClass; // for the derivatives of class + int m_limite; // limits of tables friend class CBotVarClass; friend class CBotVarPointer; }; /* -// pour définir un résultat en sortie, utiliser par exemple +// to define a result as output, using for example - // pour rendre un simple Float + // to return a simple Float return CBotTypResult( CBotTypFloat ); - // pour rendre un tableau de string + // to return a string array return CBotTypResult( CBotTypArray, CBotTypResult( CBotTypString ) ); - // pour rendre un tableau de tableau de "point" + // to return un array of array of "point" class CBotTypResult typPoint( CBotTypIntrinsic, "point" ); CBotTypResult arrPoint( CBotTypArray, typPoint ); return CBotTypResult( CBotTypArray, arrPoint ); @@ -164,87 +168,88 @@ private: //////////////////////////////////////////////////////////////////////// -// Gestion des erreurs compilation et exécution +// Error Handling of compilation and execution //////////////////////////////////////////////////////////////////////// -// voici la liste des erreurs pouvant être retournées par le module -// pour la compilation +// Here are the list of errors that can be returned by the module +// for compilation -#define CBotErrOpenPar 5000 // manque la parenthèse ouvrante -#define CBotErrClosePar 5001 // manque la parenthèse fermante -#define CBotErrNotBoolean 5002 // l'expression doit être un boolean -#define CBotErrUndefVar 5003 // variable non déclarée -#define CBotErrBadLeft 5004 // assignation impossible ( 5 = ... ) -#define CBotErrNoTerminator 5005 // point-virgule attendu -#define CBotErrCaseOut 5006 // case en dehors d'un switch +#define CBotErrOpenPar 5000 // missing the opening parenthesis +#define CBotErrClosePar 5001 // missing the closing parenthesis +#define CBotErrNotBoolean 5002 // expression must be a boolean +#define CBotErrUndefVar 5003 // undeclared variable +#define CBotErrBadLeft 5004 // assignment impossible ( 5 = ... ) +#define CBotErrNoTerminator 5005 // semicolon expected +#define CBotErrCaseOut 5006 // case outside a switch // CBotErrNoTerm 5007, plus utile -#define CBotErrCloseBlock 5008 // manque " } " -#define CBotErrElseWhitoutIf 5009 // else sans if correspondant -#define CBotErrOpenBlock 5010 // manque " { " -#define CBotErrBadType1 5011 // mauvais type pour l'assignation -#define CBotErrRedefVar 5012 // redéfinition de la variable -#define CBotErrBadType2 5013 // 2 opérandes de type incompatibles -#define CBotErrUndefCall 5014 // routine inconnue -#define CBotErrNoDoubleDots 5015 // " : " attendu +#define CBotErrCloseBlock 5008 // missing " } " +#define CBotErrElseWhitoutIf 5009 // else without matching if +#define CBotErrOpenBlock 5010 // missing " { " +#define CBotErrBadType1 5011 // wrong type for the assignment +#define CBotErrRedefVar 5012 // redefinition of the variable +#define CBotErrBadType2 5013 // Two operands are incompatible +#define CBotErrUndefCall 5014 // routine undefined +#define CBotErrNoDoubleDots 5015 // " : " expected // CBotErrWhile 5016, plus utile -#define CBotErrBreakOutside 5017 // break en dehors d'une boucle -#define CBotErrUndefLabel 5019 // label inconnu -#define CBotErrLabel 5018 // label ne peut se mettre ici -#define CBotErrNoCase 5020 // manque " case " -#define CBotErrBadNum 5021 // nombre attendu -#define CBotErrVoid 5022 // " void " pas possible ici -#define CBotErrNoType 5023 // déclaration de type attendue -#define CBotErrNoVar 5024 // nom de variable attendu -#define CBotErrNoFunc 5025 // nom de fonction attendu -#define CBotErrOverParam 5026 // trop de paramètres -#define CBotErrRedefFunc 5027 // cette fonction existe déjà -#define CBotErrLowParam 5028 // pas assez de paramètres -#define CBotErrBadParam 5029 // mauvais types de paramètres -#define CBotErrNbParam 5030 // mauvais nombre de paramètres -#define CBotErrUndefItem 5031 // élément n'existe pas dans la classe -#define CBotErrUndefClass 5032 // variable n'est pas une classe -#define CBotErrNoConstruct 5033 // pas de constructeur approprié -#define CBotErrRedefClass 5034 // classe existe déjà -#define CBotErrCloseIndex 5035 // " ] " attendu -#define CBotErrReserved 5036 // mot réservé (par un DefineNum) -#define CBotErrBadNew 5037 // mauvais paramètre pour new -#define CBotErrOpenIndex 5038 // " [ " attendu -#define CBotErrBadString 5039 // chaîne de caractère attendue -#define CBotErrBadIndex 5040 // mauvais type d'index "[ false ]" -#define CBotErrPrivate 5041 // élément protégé -#define CBotErrNoPublic 5042 // manque le mot "public" - -// voici la liste des erreurs pouvant être retournées par le module -// pour l'exécution - -#define CBotErrZeroDiv 6000 // division par zéro -#define CBotErrNotInit 6001 // variable non initialisée -#define CBotErrBadThrow 6002 // throw d'une valeur négative -#define CBotErrNoRetVal 6003 // fonction n'a pas retourné de résultat -#define CBotErrNoRun 6004 // Run() sans fonction active -#define CBotErrUndefFunc 6005 // appel d'une fonction qui n'existe plus -#define CBotErrNotClass 6006 // cette classe n'existe pas -#define CBotErrNull 6007 // pointeur null -#define CBotErrNan 6008 // calcul avec un NAN -#define CBotErrOutArray 6009 // index hors du tableau -#define CBotErrStackOver 6010 // dépassement de la pile -#define CBotErrDeletedPtr 6011 // pointeur à un objet détruit - -#define CBotErrFileOpen 6012 // ouverture du fichier impossible -#define CBotErrNotOpen 6013 // canal pas ouvert -#define CBotErrRead 6014 // erreur à la lecture -#define CBotErrWrite 6015 // erreur à l'écriture - -// d'autres valeurs peuvent être rendues -// par exemple les exceptions rendues par les routines externes -// et les " throw " avec un nombre quelconque. +#define CBotErrBreakOutside 5017 // break outside of a loop +#define CBotErrUndefLabel 5019 // label udnefined +#define CBotErrLabel 5018 // label ne peut se mettre ici (label can not get here) +#define CBotErrNoCase 5020 // missing " case " +#define CBotErrBadNum 5021 // expected number +#define CBotErrVoid 5022 // " void " not possible here +#define CBotErrNoType 5023 // type declaration expected +#define CBotErrNoVar 5024 // variable name expected +#define CBotErrNoFunc 5025 // expected function name +#define CBotErrOverParam 5026 // too many parameters +#define CBotErrRedefFunc 5027 // this function already exists +#define CBotErrLowParam 5028 // not enough parameters +#define CBotErrBadParam 5029 // wrong types of parameters +#define CBotErrNbParam 5030 // wrong number of parameters +#define CBotErrUndefItem 5031 // element does not exist in the class +#define CBotErrUndefClass 5032 // variable is not a class +#define CBotErrNoConstruct 5033 // no appropriate constructor +#define CBotErrRedefClass 5034 // class already exists +#define CBotErrCloseIndex 5035 // " ] " expected +#define CBotErrReserved 5036 // reserved word (for a DefineNum) +#define CBotErrBadNew 5037 // wrong setting for new +#define CBotErrOpenIndex 5038 // " [ " expected +#define CBotErrBadString 5039 // expected string +#define CBotErrBadIndex 5040 // wrong index type "[ false ]" +#define CBotErrPrivate 5041 // protected item +#define CBotErrNoPublic 5042 // missing word "public" + +// here is the list of errors that can be returned by the module +// for the execution + +#define CBotErrZeroDiv 6000 // division by zero +#define CBotErrNotInit 6001 // uninitialized variable +#define CBotErrBadThrow 6002 // throw a negative value +#define CBotErrNoRetVal 6003 // function did not return results +#define CBotErrNoRun 6004 // Run() without active function +#define CBotErrUndefFunc 6005 // calling a function that no longer exists +#define CBotErrNotClass 6006 // this class does not exist +#define CBotErrNull 6007 // null pointer +#define CBotErrNan 6008 // calculation with a NAN +#define CBotErrOutArray 6009 // index out of array +#define CBotErrStackOver 6010 // stack overflow +#define CBotErrDeletedPtr 6011 // pointer to an object destroyed + +#define CBotErrFileOpen 6012 // cannot open the file +#define CBotErrNotOpen 6013 // channel not open +#define CBotErrRead 6014 // error while reading +#define CBotErrWrite 6015 // writing error + + +// other values ​​may be returned +// for example exceptions returned by external routines +// and " throw " with any number. //////////////////////////////////////////////////////////////////////// // -// car CString fait partie de MFC pas utilisé ici. +// as part of MFC CString not used here. // -// ( toutes les fonctions ne sont pas encore implémentées ) +// ( all functions are not implemented yet ) /** \brief CBotString Class used to work on strings */ class CBotString @@ -320,27 +325,27 @@ private: }; -// idem avec la gestion en tableau +// Class used to array management class CBotStringArray : public CBotString { private: - int m_nSize; // nombre d'éléments - int m_nMaxSize; // taille réservée - CBotString* m_pData; // ^aux données + int m_nSize; // number of elements + int m_nMaxSize; // reserved size + CBotString* m_pData; // ^data public: CBotStringArray(); ~CBotStringArray(); void SetSize(int nb); - int GivSize(); + int GivSize(); void Add(const CBotString& str); CBotString& operator[](int nIndex); CBotString& ElementAt(int nIndex); }; -// différents mode pour GetPosition +// different modes for GetPosition enum CBotGet { GetPosExtern = 1, @@ -350,44 +355,41 @@ enum CBotGet }; //////////////////////////////////////////////////////////////////// -// classe principale gérant un programme CBot +// main class managing CBot program // class CBotProgram { private: - CBotFunction* m_Prog; // les fonctions définies par l'utilisateur - CBotFunction* m_pRun; // la fonction de base pour l'exécution - CBotClass* m_pClass; // les classes définies dans cette partie - CBotStack* m_pStack; // la pile d'exécution - CBotVar* m_pInstance; // instance de la classe parent + CBotFunction* m_Prog; // the user-defined functions + CBotFunction* m_pRun; // the basic function for the execution + CBotClass* m_pClass; // classes defined in this part + CBotStack* m_pStack; // execution stack + CBotVar* m_pInstance; // instance of the parent class friend class CBotFunction; int m_ErrorCode; int m_ErrorStart; int m_ErrorEnd; - long m_Ident; // identificateur associé + long m_Ident; // associated identifier public: - static - CBotString m_DebugVarStr; // a fin de debug - bool m_bDebugDD; // idem déclanchable par robot - - bool m_bCompileClass; + static CBotString m_DebugVarStr; // end of a debug + bool m_bDebugDD; // idem déclanchable par robot \TODO ??? + bool m_bCompileClass; public: - static - void Init(); - // initialise le module (défini les mots clefs pour les erreurs) - // doit être fait une fois (et une seule) au tout début + static void Init(); + // initializes the module (defined keywords for errors) + // should be done once (and only one) at the beginning static void Free(); - // libère les zones mémoires statiques + // frees the static memory areas static int GivVersion(); - // donne la version de la librairie CBOT + // gives the version of the library CBOT CBotProgram(); @@ -395,88 +397,87 @@ public: ~CBotProgram(); bool Compile( const char* program, CBotStringArray& ListFonctions, void* pUser = NULL); - // compile le programme donné en texte - // retourne false s'il y a une erreur à la compilation - // voir GetCompileError() pour récupérer l'erreur - // ListFonctions retourne le nom des fonctions déclarées extern - // pUser permet de passer un pointeur pour les routines définies par AddFunction + // compiles the program given in text + // returns false if an error at compile + // see GetCompileError () to retrieve the error + // ListFonctions returns the names of functions declared as extern + // pUser can pass a pointer to routines defined by AddFunction void SetIdent(long n); - // associe un identificateur avec l'instance CBotProgram + // associates an identifier with the instance CBotProgram long GivIdent(); - // redonne l'identificateur + // gives the identifier int GivError(); bool GetError(int& code, int& start, int& end); bool GetError(int& code, int& start, int& end, CBotProgram* &pProg); - // si true - // donne l'erreur trouvée à la compilation - // ou à l'exécution - // start et end délimite le bloc où se trouve l'erreur - // pProg permet de savoir dans quel "module" s'est produite l'erreur d'exécution - static - CBotString GivErrorText(int code); + // if true + // gives the error found in the compilation + // or execution + // delimits the start and end block where the error + // pProg lets you know what "module" has produced runtime error + static CBotString GivErrorText(int code); bool Start(const char* name); - // définie quelle fonction doit être exécutée - // retourne false si la fontion name n'est pas trouvée - // le programme ne fait rien, il faut appeller Run() pour cela + // defines what function should be executed + // returns false if the funtion name is not found + // the program does nothing, we must call Run () for this bool Run(void* pUser = NULL, int timer = -1); - // exécute le programme - // retourne false si le programme a été suspendu - // retourne true si le programme s'est terminé avec ou sans erreur - // timer = 0 permet de faire une avance pas à pas + // executes the program + // returns false if the program was suspended + // returns true if the program ended with or without error + // timer = 0 allows to advance step by step bool GetRunPos(const char* &FunctionName, int &start, int &end); - // donne la position dans le programme en exécution - // retourne false si on n'est pas en exécution (programme terminé) - // FunctionName est un pointeur rendu sur le nom de la fonction - // start et end la position dans le texte du token en traitement + // gives the position in the executing program + // returns false if it is not running (program completion) + // FunctionName is a pointer made to the name of the function + // start and end position in the text of the token processing CBotVar* GivStackVars(const char* &FunctionName, int level); - // permet d'obtenir le pointeur aux variables sur la pile d'exécution - // level est un paramètre d'entrée, 0 pour le dernier niveau, -1, -2, etc pour les autres niveau - // la valeur retournée (CBotVar*) est une liste de variable (ou NULL) - // qui peut être traité que la liste des paramètres reçu par une routine - // FunctionName donne le nom de la fonction où se trouvent ces variables - // FunctionName == NULL signifiant qu'on est plus dans le programme (selon level) + // provides the pointer to the variables on the execution stack + // level is an input parameter, 0 for the last level, -1, -2, etc. for the other levels + // the return value (CBotVar *) is a variable list (or NULL) + // that can be processed as the list of parameters received by a routine + // FunctionName gives the name of the function where are these variables + // FunctionName == NULL means that is more in a program (depending on level) void Stop(); - // arrête l'exécution du programme - // quitte donc le mode "suspendu" + // stops execution of the program + // therefore quits "suspend" mode static void SetTimer(int n); - // défini le nombre de pas (parties d'instructions) à faire - // dans Run() avant de rendre la main "false" + // defines the number of steps (parts of instructions) to done + // in Run() before rendering hand "false" \TODO avant de rendre la main "false" static bool AddFunction(const char* name, bool rExec (CBotVar* pVar, CBotVar* pResult, int& Exception, void* pUser), CBotTypResult rCompile (CBotVar* &pVar, void* pUser)); - // cet appel permet d'ajouter de manière externe (**) - // une nouvelle fonction utilisable par le programme CBot + // call this to add externally (**) + // a new function used by the program CBoT static bool DefineNum(const char* name, long val); bool SaveState(FILE* pf); - // sauvegarde l'état d'exécution dans le fichier - // le fichier doit avoir été ouvert avec l'appel fopen de cette dll - // sinon le système plante + // backup the execution status in the file + // the file must have been opened with the fopen call this dll (\TODO this library??) + // if the system crashes bool RestoreState(FILE* pf); - // rétablie l'état de l'exécution depuis le fichier - // le programme compilé doit évidemment être identique + // restores the state of execution from file + // the compiled program must obviously be the same bool GetPosition(const char* name, int& start, int& stop, CBotGet modestart = GetPosExtern, CBotGet modestop = GetPosBloc); - // donne la position d'une routine dans le texte d'origine - // le mode permet de choisir l'élément à trouver pour le début et la fin - // voir les modes ci-dessus dans CBotGet + // gives the position of a routine in the original text + // the user can select the item to find from the beginning to the end + // see the above modes in CBotGet CBotFunction* GivFunctions(); @@ -484,7 +485,7 @@ public: /////////////////////////////////////////////////////////////////////////////// -// routines pour la gestion d'un fichier (FILE*) +// routines for file management (* FILE) FILE* fOpen(const char* name, const char* mode); int fClose(FILE* filehandle); size_t fWrite(const void *buffer, size_t elemsize, size_t length, FILE* filehandle); @@ -494,33 +495,33 @@ public: #if 0 /* (**) Note: - Pour définir une fonction externe, il faut procéder ainsi: + To define an external function, proceed as follows: - a) définir une routine pour la compilation - cette routine reçois la liste des paramètres (sans valeurs) - et retourne soit un type de résultat (CBotTyp... ou 0 = void) - soit un numéro d'erreur - b) définir une routine pour l'exécution - cette rourine reCoit la liste des paramètres (avec valeurs), - une variable pour stocker le résultat (selon le type donné à la compilation) + a) define a routine for compilation + this routine receive list of parameters (no values) + and either returns a result type (CBotTyp... or 0 = void) + or an error number + b) define a routine for the execution + this routine receive list of parameters (with valeurs), + a variable to store the result (according to the given type at compile time) - Par exemple, une routine qui calcule la moyenne d'une liste de paramètres */ + For example, a routine which calculates the mean of a parameter list */ -int cMoyenne(CBotVar* &pVar, CBotString& ClassName) +int cMean(CBotVar* &pVar, CBotString& ClassName) { - if ( pVar == NULL ) return 6001; // il n'y a aucun paramètre ! + if ( pVar == NULL ) return 6001; // there is no parameter! while ( pVar != NULL ) { - if ( pVar->GivType() > CBotTypDouble ) return 6002; // ce n'est pas un nombre + if ( pVar->GivType() > CBotTypDouble ) return 6002; // this is not a number pVar = pVar -> GivNext(); } - return CBotTypFloat; // le type du résultat pourrait dépendre des paramètres ! + return CBotTypFloat; // the type of the result may depend on the parameters! } -bool rMoyenne(CBotVar* pVar, CBotVar* pResult, int& Exception) +bool rMean(CBotVar* pVar, CBotVar* pResult, int& Exception) { float total = 0; int nb = 0; @@ -530,70 +531,70 @@ bool rMoyenne(CBotVar* pVar, CBotVar* pResult, int& Exception) pVar = pVar->GivNext(); nb++; } - pResult->SetValFloat(total/nb); // retourne la valeur moyenne + pResult->SetValFloat(total/nb); // returns the mean value - return true; // opération totalement terminée + return true; // operation fully completed } #endif ///////////////////////////////////////////////////////////////////////////////// -// Classe pour la gestion des variables +// Class for managing variables -// peuvent être utile à l'exterieur du module -// ( il n'est pour l'instant pas prévu de pouvoir créer ces objets en externe ) +// may be useful to the outside of the module +// ( it is currently not expected to be able to create these objects in outer ) -// résultats pour GivInit() -#define IS_UNDEF 0 // variable indéfinie -#define IS_DEF 1 // variable définie -#define IS_NAN 999 // variable définie comme étant not a number +// results of GivInit() +#define IS_UNDEF 0 // undefined variable +#define IS_DEF 1 // variable defined +#define IS_NAN 999 // variable defined as not a number -// type de variable SetPrivate / IsPrivate -#define PR_PUBLIC 0 // variable publique +// variable type SetPrivate / IsPrivate +#define PR_PUBLIC 0 // public variable #define PR_READ 1 // read only -#define PR_PROTECT 2 // protected (héritage) -#define PR_PRIVATE 3 // strictement privée +#define PR_PROTECT 2 // protected (inheritance) +#define PR_PRIVATE 3 // strictly private class CBotVar { protected: - CBotToken* m_token; // le token correspondant + CBotToken* m_token; // the corresponding token - CBotVar* m_next; // liste de variables + CBotVar* m_next; // list of variables friend class CBotStack; friend class CBotCStack; friend class CBotInstrCall; friend class CBotProgram; - CBotTypResult m_type; // type de valeur + CBotTypResult m_type; // type of value - int m_binit; // pas initialisée ? - CBotVarClass* m_pMyThis; // ^élément this correspondant - void* m_pUserPtr; // ^données user s'il y a lieu - bool m_bStatic; // élément static (dans une classe) - int m_mPrivate; // élément public, protected ou private ? + int m_binit; // not initialized? + CBotVarClass* m_pMyThis; // ^ corresponding this element + void* m_pUserPtr; // ^user data if necessary + bool m_bStatic; // static element (in class) + int m_mPrivate; // element public, protected or private? - CBotInstr* m_InitExpr; // expression pour le contenu initial - CBotInstr* m_LimExpr; // liste des limites pour un tableau + CBotInstr* m_InitExpr; // expression for the original content + CBotInstr* m_LimExpr; // list of limits for a table friend class CBotClass; friend class CBotVarClass; friend class CBotVarPointer; friend class CBotVarArray; - long m_ident; // identificateur unique - static long m_identcpt; // compteur + long m_ident; // unique identifier + static long m_identcpt; // counter public: CBotVar(); -virtual ~CBotVar( ); // destructeur +virtual ~CBotVar( ); // destructor static CBotVar* Create( const char* name, CBotTypResult type); - // idem à partir du type complet + // creates from a complete type static CBotVar* Create( const char* name, CBotClass* pClass); - // idem pour une instance d'une classe connue + // creates from one instance of a known class static CBotVar* Create( const CBotToken* name, int type ); @@ -608,31 +609,32 @@ virtual ~CBotVar( ); // destructeur void SetUserPtr(void* pUser); - // associe un pointeur utilisateur à une instance + // associate a user pointer to an instance virtual void SetIdent(long UniqId); - // associe un identificateur unique à une instance - // ( c'est à l'utilisateur de s'assurer que l'id est unique) + // associates a unique identifier to an instance + // ( it is used to ensure that the id is unique) void* GivUserPtr(); - // rend le pointeur associé à la variable + // makes the pointer associated with the variable - CBotString GivName(); // le nom de la variable, s'il est connu + CBotString GivName(); // the name of the variable, if known //////////////////////////////////////////////////////////////////////////////////// - void SetName(const char* name); // change le nom de la variable + void SetName(const char* name); // changes the name of the variable - int GivType(int mode = 0); // rend le type de base (int) de la variable + int GivType(int mode = 0); // returns the base type (int) of the variable + // TODO check it //////////////////////////////////////////////////////////////////////////////////////// - CBotTypResult GivTypResult(int mode = 0); // rend le type complet de la variable + CBotTypResult GivTypResult(int mode = 0); // returns the complete type of the variable CBotToken* GivToken(); void SetType(CBotTypResult& type); - void SetInit(int bInit); // met la variable dans l'état IS_UNDEF, IS_DEF, IS_NAN + void SetInit(int bInit); // is the variable in the state IS_UNDEF, IS_DEF, IS_NAN - int GivInit(); // donne l'état de la variable + int GivInit(); // gives the state of the variable void SetStatic(bool bStatic); bool IsStatic(); @@ -644,51 +646,51 @@ virtual ~CBotVar( ); // destructeur virtual void ConstructorSet(); - void SetVal(CBotVar* var); // remprend une valeur - + void SetVal(CBotVar* var); // remprend une valeur + // TODO remprend value virtual - CBotVar* GivItem(const char* name); // rend un élément d'une classe selon son nom (*) + CBotVar* GivItem(const char* name); // returns an element of a class according to its name (*) virtual - CBotVar* GivItemRef(int nIdent); // idem à partir du n° ref - + CBotVar* GivItemRef(int nIdent); // idem à partir du n° ref + // TODO ditto from ref no. virtual CBotVar* GivItem(int row, bool bGrow = false); virtual - CBotVar* GivItemList(); // donne la liste des éléments + CBotVar* GivItemList(); // lists the elements - CBotVar* GivStaticVar(); // rend le pointeur à la variable si elle est statique + CBotVar* GivStaticVar(); // makes the pointer to the variable if it is static bool IsElemOfClass(const char* name); - // dit si l'élément appartient à la classe "name" - // rend true si l'objet est d'une classe fille + // said if the element belongs to the class "name" + // makes true if the object is a subclass - CBotVar* GivNext(); // prochaine variable dans la liste (paramètres) + CBotVar* GivNext(); // next variable in the list (parameters) //////////////////////////////////////////////////////////////////////////////////////////// - void AddNext(CBotVar* pVar); // ajoute dans une liste + void AddNext(CBotVar* pVar); // added to a list virtual - void Copy(CBotVar* pSrc, bool bName = true); // fait une copie de la variable + void Copy(CBotVar* pSrc, bool bName = true); // makes a copy of the variable virtual void SetValInt(int val, const char* name = NULL); - // initialise avec une valeur entière (#) + // initialized with an integer value (#) ///////////////////////////////////////////////////////////////////////////////// - virtual void SetValFloat(float val); // initialise avec une valeur réelle (#) + virtual void SetValFloat(float val); // initialized with a real value (#) //////////////////////////////////////////////////////////////////////////////// - virtual void SetValString(const char* p);// initialise avec une valeur chaîne (#) + virtual void SetValString(const char* p);// initialized with a string value (#) //////////////////////////////////////////////////////////////////////////////// - virtual int GivValInt(); // demande la valeur entière (#) + virtual int GivValInt(); // request the full value (#) //////////////////////////////////////////////////////////////////////// - virtual float GivValFloat(); // demande la valeur réelle (#) + virtual float GivValFloat(); // gets real value (#) /////////////////////////////////////////////////////////////////////// virtual - CBotString GivValString(); // demande la valeur chaîne (#) + CBotString GivValString(); // request the string value (#) /////////////////////////////////////////////////////////////////////// virtual void SetClass(CBotClass* pClass); @@ -701,11 +703,11 @@ virtual ~CBotVar( ); // destructeur // virtual void SetIndirection(CBotVar* pVar); virtual void Add(CBotVar* left, CBotVar* right); // addition - virtual void Sub(CBotVar* left, CBotVar* right); // soustraction + virtual void Sub(CBotVar* left, CBotVar* right); // subtraction virtual void Mul(CBotVar* left, CBotVar* right); // multiplication virtual int Div(CBotVar* left, CBotVar* right); // division - virtual int Modulo(CBotVar* left, CBotVar* right); // reste de division - virtual void Power(CBotVar* left, CBotVar* right); // puissance + virtual int Modulo(CBotVar* left, CBotVar* right); // remainder of division + virtual void Power(CBotVar* left, CBotVar* right); // power virtual bool Lo(CBotVar* left, CBotVar* right); virtual bool Hi(CBotVar* left, CBotVar* right); @@ -745,98 +747,98 @@ virtual ~CBotVar( ); // destructeur }; /* NOTE (#) - les méthodes SetValInt() SetValFloat() et SetValString() - ne peuvent êtes appellées qu'avec des objets respectivement entier, réelle ou chaîne - toujours s'assurer du type de la variable avant d'appeller ces méthodes + methods SetValInt() SetValFloat() et SetValString() + can be called with objects which are respectively integer, real or string + Always be sure of the type of the variable before calling these methods if ( pVar->GivType() == CBotInt() ) pVar->SetValFloat( 3.3 ); // plante !! - les méthodes GivValInt(), GivValFloat() et GivValString() - font des conversions de valeur, - GivValString() fonctionne sur des nombres (rend la chaîne correspondante) - par contre il ne faut pas faire de GivValInt() avec une variable de type chaîne ! + methods GivValInt(), GivValFloat() et GivValString() + use value conversions, + GivValString() works on numbers (makes the corresponding string) + but do not make GivValInt () with a string variable! */ //////////////////////////////////////////////////////////////////////// -// Gestion des classes +// management of classes //////////////////////////////////////////////////////////////////////// -// classe pour définir de nouvelle classes dans le language CBOT -// par exemple pour définir la classe CPoint (x,y) +// class to define new classes in the language CBOT +// for example to define the class CPoint (x, y) class CBotClass { private: static - CBotClass* m_ExClass; // liste des classes existante à un moment donné - CBotClass* m_ExNext; // pour cette liste générale - CBotClass* m_ExPrev; // pour cette liste générale + CBotClass* m_ExClass; // list of classes existing at a given time + CBotClass* m_ExNext; // for this general list + CBotClass* m_ExPrev; // for this general list private: - CBotClass* m_pParent; // classe parent - CBotString m_name; // nom de cette classe-ci - int m_nbVar; // nombre de variables dans la chaîne - CBotVar* m_pVar; // contenu de la classe - bool m_bIntrinsic; // classe intrinsèque - CBotClass* m_next; // chaine les classe - CBotCallMethode* m_pCalls; // liste des méthodes définie en externe - CBotFunction* m_pMethod; // liste des méthodes compilées + CBotClass* m_pParent; // parent class + CBotString m_name; // name of this class + int m_nbVar; // number of variables in the chain + CBotVar* m_pVar; // content of the class + bool m_bIntrinsic; // intrinsic class + CBotClass* m_next; // the string class + CBotCallMethode* m_pCalls; // list of methods defined in external + CBotFunction* m_pMethod; // compiled list of methods void (*m_rMaj) ( CBotVar* pThis, void* pUser ); friend class CBotVarClass; - int m_cptLock; // pour Lock / UnLock - int m_cptOne; // pour réentrance Lock - CBotProgram* m_ProgInLock[5];// processus en attente pour synchro + int m_cptLock; // for Lock / UnLock + int m_cptOne; // Lock for reentrancy + CBotProgram* m_ProgInLock[5];// processes waiting for sync public: - bool m_IsDef; // marque si est définie ou pas encore + bool m_IsDef; // mark if is set or not CBotClass( const char* name, - CBotClass* pParent, bool bIntrinsic = false ); // constructeur - // Dès qu'une classe est créée, elle est connue - // partout dans CBot - // le mode intrinsic donne une classe qui n'est pas gérée par des pointeurs + CBotClass* pParent, bool bIntrinsic = false ); // constructor + // Once a class is created, it is known + // around CBoT + // intrinsic mode gives a class that is not managed by pointers - ~CBotClass( ); // destructeur + ~CBotClass( ); // destructor bool AddFunction(const char* name, bool rExec (CBotVar* pThis, CBotVar* pVar, CBotVar* pResult, int& Exception), CBotTypResult rCompile (CBotVar* pThis, CBotVar* &pVar)); - // cet appel permet d'ajouter de manière externe (**) - // une nouvelle méthode utilisable par les objets de cette classe + // this call allows to add as external (**) + // new method used by the objects of this class bool AddUpdateFunc( void rMaj ( CBotVar* pThis, void* pUser ) ); - // défini la routine qui sera appellée pour mettre à jour les élements de la classe + // defines routine to be called to update the elements of the class bool AddItem(CBotString name, CBotTypResult type, int mPrivate = PR_PUBLIC); - // ajoute un élément à la classe + // adds an element to the class // bool AddItem(CBotString name, CBotClass* pClass); - // idem pour des éléments appartenant à pClass + // the same for elements belonging to pClass bool AddItem(CBotVar* pVar); - // idem en passant le pointeur à une instance d'une variable - // l'objet est pris tel quel, il ne faut donc pas le détruire + // adds an item by passing the pointer to an instance of a variable + // the object is taken as is, so do not destroyed - // idem en donnant un élément de type CBotVar + // adds an element by giving an element of type CBotVar void AddNext(CBotClass* pClass); - CBotString GivName(); // rend le nom de la classe - CBotClass* GivParent(); // donne la classe père (ou NULL) + CBotString GivName(); // gives the name of the class + CBotClass* GivParent(); // gives the parent class (or NULL) - // dit si une classe est dérivée (Extends) d'une autre - // rend true aussi si les classes sont identiques + // true if a class is derived (Extends) of another + // return true also if the classes are identical bool IsChildOf(CBotClass* pClass); static - CBotClass* Find(CBotToken* &pToken); // trouve une classe d'après son nom - + CBotClass* Find(CBotToken* &pToken); // trouve une classe d'après son nom + // return a class by it's its name static CBotClass* Find(const char* name); - CBotVar* GivVar(); // rend la liste des variables - CBotVar* GivItem(const char* name); // l'une des variables selon son nom + CBotVar* GivVar(); // return the list of variables + CBotVar* GivItem(const char* name); // one of the variables according to its name CBotVar* GivItemRef(int nIdent); CBotTypResult CompileMethode(const char* name, CBotVar* pThis, CBotVar** ppParams, @@ -845,7 +847,7 @@ public: bool ExecuteMethode(long& nIdent, const char* name, CBotVar* pThis, CBotVar** ppParams, CBotVar* &pResult, CBotStack* &pStack, CBotToken* pToken); void RestoreMethode(long& nIdent, const char* name, CBotVar* pThis, CBotVar** ppParams, CBotStack* &pStack); - // compile une classe déclarée par l'utilisateur + // compiles a class declared by the user static CBotClass* Compile(CBotToken* &p, CBotCStack* pStack); static @@ -873,82 +875,120 @@ public: }; -#define MAXDEFNUM 1000 // nombre limite des DefineNum +#define MAXDEFNUM 1000 // limited number of DefineNum ///////////////////////////////////////////////////////////////////////////////////// -// gestion des jetons (tokens) - -#define TokenTypKeyWord 1 // un mot clef du language (voir TokenKeyWord) -#define TokenTypNum 2 // un nombre -#define TokenTypString 3 // une chaine -#define TokenTypVar 4 // un nom de variable -#define TokenTypDef 5 // une valeur selon DefineNum +// Token management (tokens) -#define TokenKeyWord 2000 // les mots clefs du langage -#define TokenKeyDeclare 2100 // mots clefs pour déclarations (int, float,..) -#define TokenKeyVal 2200 // les mots représentant une "valeur" (true, false, null, nan) -#define TokenKeyOp 2300 // les opérateurs +#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 Responsible for token management */ class CBotToken { private: static - CBotStringArray m_ListKeyWords; // liste des mots clefs du language + CBotStringArray m_ListKeyWords; // list of keywords of language static - int m_ListIdKeyWords[200]; // les codes correspondants + int m_ListIdKeyWords[200]; // the corresponding codes static - CBotStringArray m_ListKeyDefine; // les noms définis par un DefineNum + CBotStringArray m_ListKeyDefine; // names defined by a DefineNum static - long m_ListKeyNums[MAXDEFNUM]; // les valeurs associées + long m_ListKeyNums[MAXDEFNUM]; // the ​​associated values private: - CBotToken* m_next; // suivant dans la liste + CBotToken* m_next; // following in the list CBotToken* m_prev; - int m_type; // type de Token - long m_IdKeyWord; // numéro du mot clef si c'en est un - // ou valeur du "define" + 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; // mot trouvé comme token - CBotString m_Sep; // séparateurs qui suivent - - int m_start; // position dans le texte d'origine (programme) - int m_end; // itou pour la fin du token + 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 GivKeyWords(const char* w); // est-ce un mot clef ? + int GivKeyWords(const char* w); // is it a keyword? static bool GivKeyDefNum(const char* w, CBotToken* &token); + /** + * \brief Loads the list of keywords + */ static - void LoadKeyWords(); // fait la liste des mots clefs + 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 = NULL); - // constructeur - ~CBotToken(); // destructeur - int GivType(); // rend le type du token + /** + * \brief Destructor + */ + ~CBotToken(); + /** + * \brief Returns the type of token + */ + int GivType(); - CBotString& GivString(); // rend la chaine correspondant à ce token + /** + * \brief makes the string corresponding to this token + */ + CBotString& GivString(); - CBotString& GivSep(); // rend le séparateur suivant le token + /** + * \brief makes the following separator token + */ + CBotString& GivSep(); - int GivStart(); // position du début dans le texte - int GivEnd(); // position de fin dans le texte + /** + * \brief position of the beginning in the text + */ + int GivStart(); + /** + * \brief end position in the text + */ + int GivEnd(); - CBotToken* GivNext(); // rend le suivant dans la liste - CBotToken* GivPrev(); // rend le Précédent dans la liste + /** + * \brief gives the next token in the list + */ + CBotToken* GivNext(); + /** + * \brief gives the previous token in a list + */ + CBotToken* GivPrev(); + /** + * \brief transforms the entire program + */ static CBotToken* CompileTokens(const char* p, int& error); - // transforme tout le programme + + /** + * \brief releases the list + */ static - void Delete(CBotToken* pToken); // libère la liste + void Delete(CBotToken* pToken); // libère la liste // fonctions non utiles en export @@ -958,11 +998,17 @@ public: void SetPos(int start, int end); long GivIdKey(); - void AddNext(CBotToken* p); // ajoute un token (une copie) + /** + * \brief adds a token (a copy) + */ + void AddNext(CBotToken* p); + /** + * finds the next token + */ static CBotToken* NextToken(char* &program, int& error, bool first = false); - // trouve le prochain token + const CBotToken& operator=(const CBotToken& src); @@ -974,96 +1020,96 @@ public: #if 0 //////////////////////////////////////////////////////////////////////// -// Exemples d'utilisation -// Définition de classes et de fonctions +// Examples of use +// Definition classes and functions -// définie la classe globale CPoint +// define the global class CPoint // -------------------------------- m_pClassPoint = new CBotClass("CPoint", NULL); - // ajoute le composant ".x" + // adds the component ".x" m_pClassPoint->AddItem("x", CBotTypResult(CBotTypFloat)); - // ajoute le composant ".y" + // adds the component ".y" m_pClassPoint->AddItem("y", CBotTypResult(CBotTypFloat)); - // le joueur peut alors utiliser les instructions + // the player can then use the instructions // CPoint position; position.x = 12; position.y = -13.6 -// définie la classe CColobotObject +// define class CColobotObject // -------------------------------- -// cette classe gère tous les objets dans le monde de COLOBOT -// le programme utilisateur "main" appartient à cette classe +// This class manages all the objects in the world of COLOBOT +// the "main" user program belongs to this class m_pClassObject = new CBotClass("CColobotObject", m_pClassBase); - // ajoute le composant ".position" + // adds the component ".position" m_pClassObject->AddItem("position", m_pClassPoint); - // ajoute le composant ".type" + // adds the component ".type" m_pClassObject->AddItem("type", CBotTypResult(CBotTypShort)); - // ajoute une définition de constante - m_pClassObject->AddConst("ROBOT", CBotTypShort, 1); // ROBOT équivalent à la valeur 1 - // ajoute la routine FIND + // adds a definition of constant + m_pClassObject->AddConst("ROBOT", CBotTypShort, 1); // ROBOT equivalent to the value 1 + // adds the FIND routine m_pClassObject->AddFunction( rCompFind, rDoFind ); - // le joueur peut maintenant utiliser les instructions + // the player can now use the instructions // CColobotObject chose; chose = FIND( ROBOT ) -// définie la classe CColobotRobot dérivée de CColobotObject +// define class CColobotRobot derived from CColobotObject // --------------------------------------------------------- -// les programmes "main" associés aux robots font partie de cette classe +// programs "main" associated with robots as a part of this class m_pClassRobot = new CBotClass("CColobotRobot", m_pClassObject); - // ajoute la routine GOTO + // add routine GOTO m_pClassRobot->AddFunction( rCompGoto, rDoGoto ); - // le joueur peut maintenant faire + // the player can now use // GOTO( FIND ( ROBOT ) ); -// crée une instance de la classe Robot +// creates an instance of the class Robot // ------------------------------------ -// par exemple un nouveau robot qui vient d'être fabriqué +// for example a new robot which has just been manufactured CBotVar* m_pMonRobot = new CBotVar("MonRobot", m_pClassRobot); -// compile le programme main pour ce robot-là +// compiles the program by hand for this robot // ------------------------------------------ CString LeProgramme( "void main() {GOTO(0, 0); return 0;}" ); - if ( !m_pMonRobot->Compile( LeProgramme ) ) {gestion d'erreur...}; + if ( !m_pMonRobot->Compile( LeProgramme ) ) {error handling ...}; -// construit une pile pour l'interpréteur +// build a stack for interpreter // -------------------------------------- CBotStack* pStack = new CBotStack(NULL); -// exécute le programme main +// executes the main program // ------------------------- while( false = m_pMonRobot->Execute( "main", pStack )) { - // programme suspendu - // on pourrait passer la main à un autre (en sauvegardant pStack pour ce robot-là) + // program suspended + // could be pass a handle to another (safeguarding pstack for the robot one) }; - // programme "main" terminé ! + // programme "main" finished ! -// routine implémentant l'instruction GOTO( CPoint pos ) +// routine that implements the GOTO (CPoint pos) bool rDoGoto( CBotVar* pVar, CBotVar* pResult, int& exception ) { if (pVar->GivType() != CBotTypeClass || pVar->IsElemOfClas("CPoint") ) { exception = 6522; return false; ) - // le paramètre n'est pas de la bonne classe ? - // NB en fait ce contrôle est déjà fait par la routine pour la compilation + // the parameter is not the right class? + // in fact the control is done to the routine of compilation - m_PosToGo.Copy( pVar ); // garde la position à atteindre (object type CBotVar) + m_PosToGo.Copy( pVar ); // keeps the target position (object type CBotVar) - // ou alors + // or so CBotVar* temp; - temp = pVar->GivItem("x"); // trouve forcément pour un object de type "CPoint" + temp = pVar->GivItem("x"); // is necessary for the object of type CPoint ASSERT (temp != NULL && temp->GivType() == CBotTypFloat); m_PosToGo.x = temp->GivValFloat(); - temp = pVar->GivItem("y"); // trouve forcément pour un object de type "CPoint" + temp = pVar->GivItem("y"); // is necessary for the object of type CPoint ASSERT (temp != NULL && temp->GivType() == CBotTypFloat); m_PosToGo.y = temp->GivValFloat(); - return (m_CurentPos == m_PosToGo); // rend true si la position est atteinte - // rend false s'il faut patienter encore + return (m_CurentPos == m_PosToGo); // makes true if the position is reached + // returns false if one had wait yet } #endif diff --git a/src/CBot/CBotIf.cpp b/src/CBot/CBotIf.cpp index 178992e..c1dc833 100644 --- a/src/CBot/CBotIf.cpp +++ b/src/CBot/CBotIf.cpp @@ -1,159 +1,161 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * 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://www.gnu.org/licenses/./////////////////////////////////////////////////////////////////////// -// instruction if (condition) opération1 else opération2; - -#include "CBot.h" - -// les divers constructeurs / destructeurs -CBotIf::CBotIf() -{ - m_Condition = - m_Block = - m_BlockElse = NULL; // NULL pour pouvoir faire delete directement - name = "CBotIf"; // debug -} - -CBotIf::~CBotIf() -{ - delete m_Condition; // libère la condition - delete m_Block; // libère le bloc d'instruction1 - delete m_BlockElse; // libère le bloc d'instruction2 -} - -// compilation (routine statique) -// appelé lorsque le token "if" a été trouvé - -CBotInstr* CBotIf::Compile(CBotToken* &p, CBotCStack* pStack) -{ - CBotToken* pp = p; // conserve le ^au token (début instruction) - - if (!IsOfType(p, ID_IF)) return NULL; // ne doit jamais arriver - - CBotCStack* pStk = pStack->TokenStack(pp); // un petit bout de pile svp - - CBotIf* inst = new CBotIf(); // crée l'object - inst->SetToken( pp ); - - if ( NULL != (inst->m_Condition = CBotCondition::Compile( p, pStk )) ) - { - // la condition existe bel et bien - - inst->m_Block = CBotBlock::CompileBlkOrInst( p, pStk, true ); - if ( pStk->IsOk() ) - { - // le bloc d'instruction est ok (peut être vide) - - // regarde si l'instruction suivante est le token "else" - if (IsOfType(p, ID_ELSE)) - { - // si oui, compile le bloc d'instruction qui suit - inst->m_BlockElse = CBotBlock::CompileBlkOrInst( p, pStk, true ); - if (!pStk->IsOk()) - { - // il n'y a pas de bloc correct après le else - // libère l'objet, et transmet l'erreur qui est sur la pile - delete inst; - return pStack->Return(NULL, pStk); - } - } - - // rend l'object correct à qui le demande. - return pStack->Return(inst, pStk); - } - } - - // erreur, libère l'objet - delete inst; - // et transmet l'erreur qui se trouve sur la pile. - return pStack->Return(NULL, pStk); -} - - -// exécution de l'instruction - -bool CBotIf :: Execute(CBotStack* &pj) -{ - CBotStack* pile = pj->AddStack(this); // ajoute un élément à la pile - // ou le retrouve en cas de reprise -// if ( pile == EOX ) return true; - - if ( pile->IfStep() ) return false; - - // selon la reprise, on peut être dans l'un des 2 états - if( pile->GivState() == 0 ) - { - // évalue la condition - if ( !m_Condition->Execute(pile) ) return false; // interrompu ici ? - - // termine s'il y a une erreur - if ( !pile->IsOk() ) - { - return pj->Return(pile); // transmet le résultat et libère la pile - } - - // passe dans le second état - if (!pile->SetState(1)) return false; // prêt pour la suite - } - - // second état, évalue les instructions associées - // le résultat de la condition est sur la pile - - if ( pile->GivVal() == true ) // condition était vraie ? - { - if ( m_Block != NULL && // bloc peut être absent - !m_Block->Execute(pile) ) return false; // interrompu ici ? - } - else - { - if ( m_BlockElse != NULL && // s'il existe un bloc alternatif - !m_BlockElse->Execute(pile) ) return false; // interrompu ici - } - - // transmet le résultat et libère la pile - return pj->Return(pile); -} - - -void CBotIf :: RestoreState(CBotStack* &pj, bool bMain) -{ - if ( !bMain ) return; - - CBotStack* pile = pj->RestoreStack(this); // ajoute un élément à la pile - if ( pile == NULL ) return; - - // selon la reprise, on peut être dans l'un des 2 états - if( pile->GivState() == 0 ) - { - // évalue la condition - m_Condition->RestoreState(pile, bMain); // interrompu ici ! - return; - } - - // second état, évalue les instructions associées - // le résultat de la condition est sur la pile - - if ( pile->GivVal() == true ) // condition était vraie ? - { - if ( m_Block != NULL ) // bloc peut être absent - m_Block->RestoreState(pile, bMain); // interrompu ici ! - } - else - { - if ( m_BlockElse != NULL ) // s'il existe un bloc alternatif - m_BlockElse->RestoreState(pile, bMain); // interrompu ici ! - } -} - +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * 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://www.gnu.org/licenses/. + +/////////////////////////////////////////////////////////////////////// +// instruction if (condition) operation1 else operation2; + +#include "CBot.h" + +// various constructors / destructors +CBotIf::CBotIf() +{ + m_Condition = + m_Block = + m_BlockElse = NULL; // NULL so that delete is not possible further + name = "CBotIf"; // debug +} + +CBotIf::~CBotIf() +{ + delete m_Condition; // frees the condition + delete m_Block; // frees the block of instruction1 + delete m_BlockElse; // frees the block of instruction2 +} + +// compilation (static routine) +// called when the token "if" has been found + +CBotInstr* CBotIf::Compile(CBotToken* &p, CBotCStack* pStack) +{ + CBotToken* pp = p; // preserves at the ^ token (starting instruction) + + if (!IsOfType(p, ID_IF)) return NULL; // should never happen + + CBotCStack* pStk = pStack->TokenStack(pp); // un petit bout de pile svp + + CBotIf* inst = new CBotIf(); // create the object + inst->SetToken( pp ); + + if ( NULL != (inst->m_Condition = CBotCondition::Compile( p, pStk )) ) + { + // the condition does exist + + inst->m_Block = CBotBlock::CompileBlkOrInst( p, pStk, true ); + if ( pStk->IsOk() ) + { + // the statement block is ok (can be empty) + + // see if the next instruction is the token "else" + if (IsOfType(p, ID_ELSE)) + { + // if so, compiles the following statement block + inst->m_BlockElse = CBotBlock::CompileBlkOrInst( p, pStk, true ); + if (!pStk->IsOk()) + { + // there is no correct block after the else + // frees the object, and transmits the error that is on the stack + delete inst; + return pStack->Return(NULL, pStk); + } + } + + // return the corrent object to the application + return pStack->Return(inst, pStk); + } + } + + // error, frees the object + delete inst; + // and transmits the error that is on the stack. + return pStack->Return(NULL, pStk); +} + + +// execution of the instruction + +bool CBotIf :: Execute(CBotStack* &pj) +{ + CBotStack* pile = pj->AddStack(this); // adds an item to the stack + // or found in case of recovery +// if ( pile == EOX ) return true; + + if ( pile->IfStep() ) return false; + + // according to recovery, it may be in one of two states + if( pile->GivState() == 0 ) + { + // evaluates the condition + if ( !m_Condition->Execute(pile) ) return false; // interrupted here? + + // terminates if there is an error + if ( !pile->IsOk() ) + { + return pj->Return(pile); // returns the results and releases the stack + } + + // passes into the second state + if (!pile->SetState(1)) return false; // ready for further + } + + // second state, evaluates the associated instructions + // the result of the condition is on the stack + + if ( pile->GivVal() == true ) // condition was true? + { + if ( m_Block != NULL && // block may be absent + !m_Block->Execute(pile) ) return false; // interrupted here? + } + else + { + if ( m_BlockElse != NULL && // if there is an alternate block + !m_BlockElse->Execute(pile) ) return false; // interrupted here + } + + // sends the results and releases the stack + return pj->Return(pile); +} + + +void CBotIf :: RestoreState(CBotStack* &pj, bool bMain) +{ + if ( !bMain ) return; + + CBotStack* pile = pj->RestoreStack(this); // adds an item to the stack + if ( pile == NULL ) return; + + // according to recovery, it may be in one of two states + if( pile->GivState() == 0 ) + { + // evaluates the condition + m_Condition->RestoreState(pile, bMain); // interrupted here! + return; + } + + // second state, evaluates the associated instructions + // the result of the condition is on the stack + + if ( pile->GivVal() == true ) // condition was true? + { + if ( m_Block != NULL ) // block may be absent + m_Block->RestoreState(pile, bMain); // interrupted here! + } + else + { + if ( m_BlockElse != NULL ) // if there is an alternate block + m_BlockElse->RestoreState(pile, bMain); // interrupted here! + } +} + diff --git a/src/CBot/CBotVar.cpp b/src/CBot/CBotVar.cpp index 9070298..0d9bfb3 100644 --- a/src/CBot/CBotVar.cpp +++ b/src/CBot/CBotVar.cpp @@ -1,2245 +1,2248 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch -// * -// * 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://www.gnu.org/licenses/.//////////////////////////////////////////////////////////////////// -// Définition pour la classe CBotVar -// gestion des variables du langage CBot - -// on ne crée jamais d'instance de la class mère CBotVar - - -#include "CBot.h" -#include -#include - -long CBotVar::m_identcpt = 0; - -CBotVar::CBotVar( ) -{ - m_next = NULL; - m_pMyThis = NULL; - m_pUserPtr = NULL; - m_InitExpr = NULL; - m_LimExpr = NULL; - m_type = -1; - m_binit = false; - m_ident = 0; - m_bStatic = false; - m_mPrivate = 0; -} - -CBotVarInt::CBotVarInt( const CBotToken* name ) -{ - m_token = new CBotToken(name); - m_next = NULL; - m_pMyThis = NULL; - m_pUserPtr = NULL; - m_InitExpr = NULL; - m_LimExpr = NULL; - m_type = CBotTypInt; - m_binit = false; - m_bStatic = false; - m_mPrivate = 0; - - m_val = 0; -} - -CBotVarFloat::CBotVarFloat( const CBotToken* name ) -{ - m_token = new CBotToken(name); - m_next = NULL; - m_pMyThis = NULL; - m_pUserPtr = NULL; - m_InitExpr = NULL; - m_LimExpr = NULL; - m_type = CBotTypFloat; - m_binit = false; - m_bStatic = false; - m_mPrivate = 0; - - m_val = 0; -} - -CBotVarString::CBotVarString( const CBotToken* name ) -{ - m_token = new CBotToken(name); - m_next = NULL; - m_pMyThis = NULL; - m_pUserPtr = NULL; - m_InitExpr = NULL; - m_LimExpr = NULL; - m_type = CBotTypString; - m_binit = false; - m_bStatic = false; - m_mPrivate = 0; - - m_val.Empty(); -} - -CBotVarBoolean::CBotVarBoolean( const CBotToken* name ) -{ - m_token = new CBotToken(name); - m_next = NULL; - m_pMyThis = NULL; - m_pUserPtr = NULL; - m_InitExpr = NULL; - m_LimExpr = NULL; - m_type = CBotTypBoolean; - m_binit = false; - m_bStatic = false; - m_mPrivate = 0; - - m_val = 0; -} - -CBotVarClass* CBotVarClass::m_ExClass = NULL; - -CBotVarClass::CBotVarClass( const CBotToken* name, const CBotTypResult& type) -{ -/* -// int nIdent = 0; - InitCBotVarClass( name, type ) //, nIdent ); -} - -CBotVarClass::CBotVarClass( const CBotToken* name, CBotTypResult& type) //, int &nIdent ) -{ - InitCBotVarClass( name, type ); //, nIdent ); -} - -void CBotVarClass::InitCBotVarClass( const CBotToken* name, CBotTypResult& type ) //, int &nIdent ) -{*/ - if ( !type.Eq(CBotTypClass) && - !type.Eq(CBotTypIntrinsic) && // par comodité accepte ces types - !type.Eq(CBotTypPointer) && - !type.Eq(CBotTypArrayPointer) && - !type.Eq(CBotTypArrayBody)) ASM_TRAP(); - - m_token = new CBotToken(name); - m_next = NULL; - m_pMyThis = NULL; - m_pUserPtr = OBJECTCREATED;//NULL; - m_InitExpr = NULL; - m_LimExpr = NULL; - m_pVar = NULL; - m_type = type; - if ( type.Eq(CBotTypArrayPointer) ) m_type.SetType( CBotTypArrayBody ); - else if ( !type.Eq(CBotTypArrayBody) ) m_type.SetType( CBotTypClass ); - // type officel pour cet object - - m_pClass = NULL; - m_pParent = NULL; - m_binit = false; - m_bStatic = false; - m_mPrivate = 0; - m_bConstructor = false; - m_CptUse = 0; - m_ItemIdent = type.Eq(CBotTypIntrinsic) ? 0 : CBotVar::NextUniqNum(); - - // se place tout seul dans la liste - if (m_ExClass) m_ExClass->m_ExPrev = this; - m_ExNext = m_ExClass; - m_ExPrev = NULL; - m_ExClass = this; - - CBotClass* pClass = type.GivClass(); - CBotClass* pClass2 = pClass->GivParent(); - if ( pClass2 != NULL ) - { - // crée également une instance dans la classe père - m_pParent = new CBotVarClass(name, CBotTypResult(type.GivType(),pClass2) ); //, nIdent); - } - - SetClass( pClass ); //, nIdent ); - -} - -CBotVarClass::~CBotVarClass( ) -{ - if ( m_CptUse != 0 ) - ASM_TRAP(); - - if ( m_pParent ) delete m_pParent; - m_pParent = NULL; - - // libère l'objet indirect s'il y a lieu -// if ( m_Indirect != NULL ) -// m_Indirect->DecrementUse(); - - // retire la classe de la liste - if ( m_ExPrev ) m_ExPrev->m_ExNext = m_ExNext; - else m_ExClass = m_ExNext; - - if ( m_ExNext ) m_ExNext->m_ExPrev = m_ExPrev; - m_ExPrev = NULL; - m_ExNext = NULL; - - delete m_pVar; -} - -void CBotVarClass::ConstructorSet() -{ - m_bConstructor = true; -} - - -CBotVar::~CBotVar( ) -{ - delete m_token; - delete m_next; -} - -void CBotVar::debug() -{ - const char* p = (const char*) m_token->GivString(); - CBotString s = (const char*) GivValString(); - const char* v = (const char*) s; - - if ( m_type.Eq(CBotTypClass) ) - { - CBotVar* pv = ((CBotVarClass*)this)->m_pVar; - while (pv != NULL) - { - pv->debug(); - pv = pv->GivNext(); - } - } -} - -void CBotVar::ConstructorSet() -{ - // nop -} - -void CBotVar::SetUserPtr(void* pUser) -{ - m_pUserPtr = pUser; - if (m_type.Eq(CBotTypPointer) && - ((CBotVarPointer*)this)->m_pVarClass != NULL ) - ((CBotVarPointer*)this)->m_pVarClass->SetUserPtr(pUser); -} - -void CBotVar::SetIdent(long n) -{ - if (m_type.Eq(CBotTypPointer) && - ((CBotVarPointer*)this)->m_pVarClass != NULL ) - ((CBotVarPointer*)this)->m_pVarClass->SetIdent(n); -} - -void CBotVar::SetUniqNum(long n) -{ - m_ident = n; - - if ( n == 0 ) ASM_TRAP(); -} - -long CBotVar::NextUniqNum() -{ - if (++m_identcpt < 10000) m_identcpt = 10000; - return m_identcpt; -} - -long CBotVar::GivUniqNum() -{ - return m_ident; -} - - -void* CBotVar::GivUserPtr() -{ - return m_pUserPtr; -} - -bool CBotVar::Save1State(FILE* pf) -{ - // cette routine "virtual" ne doit jamais être appellée, - // il doit y avoir une routine pour chaque classe fille (CBotVarInt, CBotVarFloat, etc) - // ( voir le type dans m_type ) - ASM_TRAP(); - return false; -} - -void CBotVar::Maj(void* pUser, bool bContinu) -{ -/* if (!bContinu && m_pMyThis != NULL) - m_pMyThis->Maj(pUser, true);*/ -} - - -// crée une variable selon son type - -CBotVar* CBotVar::Create(const CBotToken* name, int type ) -{ - CBotTypResult t(type); - return Create(name, t); -} - -CBotVar* CBotVar::Create(const CBotToken* name, CBotTypResult type) -{ - switch (type.GivType()) - { - case CBotTypShort: - case CBotTypInt: - return new CBotVarInt(name); - case CBotTypFloat: - return new CBotVarFloat(name); - case CBotTypBoolean: - return new CBotVarBoolean(name); - case CBotTypString: - return new CBotVarString(name); - case CBotTypPointer: - case CBotTypNullPointer: - return new CBotVarPointer(name, type); - case CBotTypIntrinsic: - return new CBotVarClass(name, type); - - case CBotTypClass: - // crée une nouvelle instance d'une classe - // et retourne le POINTER sur cette instance - { - CBotVarClass* instance = new CBotVarClass(name, type); - CBotVarPointer* pointer = new CBotVarPointer(name, type); - pointer->SetPointer( instance ); - return pointer; - } - - case CBotTypArrayPointer: - return new CBotVarArray(name, type); - - case CBotTypArrayBody: - { - CBotVarClass* instance = new CBotVarClass(name, type); - CBotVarArray* array = new CBotVarArray(name, type); - array->SetPointer( instance ); - - CBotVar* pv = array; - while (type.Eq(CBotTypArrayBody)) - { - type = type.GivTypElem(); - pv = ((CBotVarArray*)pv)->GivItem(0, true); // crée au moins l'élément [0] - } - - return array; - } - } - - ASM_TRAP(); - return NULL; -} - -CBotVar* CBotVar::Create( CBotVar* pVar ) -{ - CBotVar* p = Create(pVar->m_token->GivString(), pVar->GivTypResult(2)); - return p; -} - - -CBotVar* CBotVar::Create( const char* n, CBotTypResult type) -{ - CBotToken name(n); - - switch (type.GivType()) - { - case CBotTypShort: - case CBotTypInt: - return new CBotVarInt(&name); - case CBotTypFloat: - return new CBotVarFloat(&name); - case CBotTypBoolean: - return new CBotVarBoolean(&name); - case CBotTypString: - return new CBotVarString(&name); - case CBotTypPointer: - case CBotTypNullPointer: - { - CBotVarPointer* p = new CBotVarPointer(&name, type); -// p->SetClass(type.GivClass()); - return p; - } - case CBotTypIntrinsic: - { - CBotVarClass* p = new CBotVarClass(&name, type); -// p->SetClass(type.GivClass()); - return p; - } - - case CBotTypClass: - // crée une nouvelle instance d'une classe - // et retourne le POINTER sur cette instance - { - CBotVarClass* instance = new CBotVarClass(&name, type); - CBotVarPointer* pointer = new CBotVarPointer(&name, type); - pointer->SetPointer( instance ); -// pointer->SetClass( type.GivClass() ); - return pointer; - } - - case CBotTypArrayPointer: - return new CBotVarArray(&name, type); - - case CBotTypArrayBody: - { - CBotVarClass* instance = new CBotVarClass(&name, type); - CBotVarArray* array = new CBotVarArray(&name, type); - array->SetPointer( instance ); - - CBotVar* pv = array; - while (type.Eq(CBotTypArrayBody)) - { - type = type.GivTypElem(); - pv = ((CBotVarArray*)pv)->GivItem(0, true); // crée au moins l'élément [0] - } - - return array; - } - } - - ASM_TRAP(); - return NULL; -} - -CBotVar* CBotVar::Create( const char* name, int type, CBotClass* pClass) -{ - CBotToken token( name, "" ); - CBotVar* pVar = Create( &token, type ); - - if ( type == CBotTypPointer && pClass == NULL ) // pointeur "null" ? - return pVar; - - if ( type == CBotTypClass || type == CBotTypPointer || - type == CBotTypIntrinsic ) - { - if (pClass == NULL) - { - delete pVar; - return NULL; - } - pVar->SetClass( pClass ); - } - return pVar; -} - -CBotVar* CBotVar::Create( const char* name, CBotClass* pClass) -{ - CBotToken token( name, "" ); - CBotVar* pVar = Create( &token, CBotTypResult( CBotTypClass, pClass ) ); -// pVar->SetClass( pClass ); - return pVar; -} - -CBotTypResult CBotVar::GivTypResult(int mode) -{ - CBotTypResult r = m_type; - - if ( mode == 1 && m_type.Eq(CBotTypClass) ) - r.SetType(CBotTypPointer); - if ( mode == 2 && m_type.Eq(CBotTypClass) ) - r.SetType(CBotTypIntrinsic); - - return r; -} - -int CBotVar::GivType(int mode) -{ - if ( mode == 1 && m_type.Eq(CBotTypClass) ) - return CBotTypPointer; - if ( mode == 2 && m_type.Eq(CBotTypClass) ) - return CBotTypIntrinsic; - return m_type.GivType(); -} - -void CBotVar::SetType(CBotTypResult& type) -{ - m_type = type; -} - - -int CBotVar::GivInit() -{ - if ( m_type.Eq(CBotTypClass) ) return IS_DEF; // toujours défini ! - - return m_binit; -} - -void CBotVar::SetInit(int bInit) -{ - m_binit = bInit; - if ( bInit == 2 ) m_binit = IS_DEF; // cas spécial - - if ( m_type.Eq(CBotTypPointer) && bInit == 2 ) - { - CBotVarClass* instance = GivPointer(); - if ( instance == NULL ) - { - instance = new CBotVarClass(NULL, m_type); -// instance->SetClass(((CBotVarPointer*)this)->m_pClass); - SetPointer(instance); - } - instance->SetInit(1); - } - - if ( m_type.Eq(CBotTypClass) || m_type.Eq(CBotTypIntrinsic) ) - { - CBotVar* p = ((CBotVarClass*)this)->m_pVar; - while( p != NULL ) - { - p->SetInit( bInit ); - p->m_pMyThis = (CBotVarClass*)this; - p = p->GivNext(); - } - } -} - -CBotString CBotVar::GivName() -{ - return m_token->GivString(); -} - -void CBotVar::SetName(const char* name) -{ - m_token->SetString(name); -} - -CBotToken* CBotVar::GivToken() -{ - return m_token; -} - -CBotVar* CBotVar::GivItem(const char* name) -{ - ASM_TRAP(); - return NULL; -} - -CBotVar* CBotVar::GivItemRef(int nIdent) -{ - ASM_TRAP(); - return NULL; -} - -CBotVar* CBotVar::GivItemList() -{ - ASM_TRAP(); - return NULL; -} - -CBotVar* CBotVar::GivItem(int row, bool bGrow) -{ - ASM_TRAP(); - return NULL; -} - -// dit si une variable appartient à une classe donnée -bool CBotVar::IsElemOfClass(const char* name) -{ - CBotClass* pc = NULL; - - if ( m_type.Eq(CBotTypPointer) ) - { - pc = ((CBotVarPointer*)this)->m_pClass; - } - if ( m_type.Eq(CBotTypClass) ) - { - pc = ((CBotVarClass*)this)->m_pClass; - } - - while ( pc != NULL ) - { - if ( pc->GivName() == name ) return true; - pc = pc->GivParent(); - } - - return false; -} - - -CBotVar* CBotVar::GivStaticVar() -{ - // rend le pointeur à la variable si elle est statique - if ( m_bStatic == 0 || m_pMyThis == NULL ) return this; - - CBotClass* pClass = m_pMyThis->GivClass(); - return pClass->GivItem( m_token->GivString() ); -} - - -CBotVar* CBotVar::GivNext() -{ - return m_next; -} - -void CBotVar::AddNext(CBotVar* pVar) -{ - CBotVar* p = this; - while (p->m_next != NULL) p = p->m_next; - - p->m_next = pVar; -} - -void CBotVar::SetVal(CBotVar* var) -{ - switch (/*var->*/GivType()) - { - case CBotTypBoolean: - SetValInt(var->GivValInt()); - break; - case CBotTypInt: - SetValInt(var->GivValInt(), ((CBotVarInt*)var)->m_defnum); - break; - case CBotTypFloat: - SetValFloat(var->GivValFloat()); - break; - case CBotTypString: - SetValString(var->GivValString()); - break; - case CBotTypPointer: - case CBotTypNullPointer: - case CBotTypArrayPointer: - SetPointer(var->GivPointer()); - break; - case CBotTypClass: - { - delete ((CBotVarClass*)this)->m_pVar; - ((CBotVarClass*)this)->m_pVar = NULL; - Copy(var, false); - } - break; - default: - ASM_TRAP(); - } - - m_binit = var->m_binit; // copie l'état nan s'il y a -} - -void CBotVar::SetStatic(bool bStatic) -{ - m_bStatic = bStatic; -} - -void CBotVar::SetPrivate(int mPrivate) -{ - m_mPrivate = mPrivate; -} - -bool CBotVar::IsStatic() -{ - return m_bStatic; -} - -bool CBotVar::IsPrivate(int mode) -{ - return m_mPrivate >= mode; -} - -int CBotVar::GivPrivate() -{ - return m_mPrivate; -} - - -void CBotVar::SetPointer(CBotVar* pVarClass) -{ - ASM_TRAP(); -} - -CBotVarClass* CBotVar::GivPointer() -{ - ASM_TRAP(); - return NULL; -} - -// toutes ces fonctions doivent être définies dans les classes filles -// dérivées de la classe CBotVar - -int CBotVar::GivValInt() -{ - ASM_TRAP(); - return 0; -} - -float CBotVar::GivValFloat() -{ - ASM_TRAP(); - return 0; -} - -void CBotVar::SetValInt(int c, const char* s) -{ - ASM_TRAP(); -} - -void CBotVar::SetValFloat(float c) -{ - ASM_TRAP(); -} - -void CBotVar::Mul(CBotVar* left, CBotVar* right) -{ - ASM_TRAP(); -} - -void CBotVar::Power(CBotVar* left, CBotVar* right) -{ - ASM_TRAP(); -} - -int CBotVar::Div(CBotVar* left, CBotVar* right) -{ - ASM_TRAP(); - return 0; -} - -int CBotVar::Modulo(CBotVar* left, CBotVar* right) -{ - ASM_TRAP(); - return 0; -} - -void CBotVar::Add(CBotVar* left, CBotVar* right) -{ - ASM_TRAP(); -} - -void CBotVar::Sub(CBotVar* left, CBotVar* right) -{ - ASM_TRAP(); -} - -bool CBotVar::Lo(CBotVar* left, CBotVar* right) -{ - ASM_TRAP(); - return false; -} - -bool CBotVar::Hi(CBotVar* left, CBotVar* right) -{ - ASM_TRAP(); - return false; -} - -bool CBotVar::Ls(CBotVar* left, CBotVar* right) -{ - ASM_TRAP(); - return false; -} - -bool CBotVar::Hs(CBotVar* left, CBotVar* right) -{ - ASM_TRAP(); - return false; -} - -bool CBotVar::Eq(CBotVar* left, CBotVar* right) -{ - ASM_TRAP(); - return false; -} - -bool CBotVar::Ne(CBotVar* left, CBotVar* right) -{ - ASM_TRAP(); - return false; -} - -void CBotVar::And(CBotVar* left, CBotVar* right) -{ - ASM_TRAP(); -} - -void CBotVar::Or(CBotVar* left, CBotVar* right) -{ - ASM_TRAP(); -} - -void CBotVar::XOr(CBotVar* left, CBotVar* right) -{ - ASM_TRAP(); -} - -void CBotVar::ASR(CBotVar* left, CBotVar* right) -{ - ASM_TRAP(); -} - -void CBotVar::SR(CBotVar* left, CBotVar* right) -{ - ASM_TRAP(); -} - -void CBotVar::SL(CBotVar* left, CBotVar* right) -{ - ASM_TRAP(); -} - -void CBotVar::Neg() -{ - ASM_TRAP(); -} - -void CBotVar::Not() -{ - ASM_TRAP(); -} - -void CBotVar::Inc() -{ - ASM_TRAP(); -} -void CBotVar::Dec() -{ - ASM_TRAP(); -} - -void CBotVar::Copy(CBotVar* pSrc, bool bName) -{ - ASM_TRAP(); -} - -void CBotVar::SetValString(const char* p) -{ - ASM_TRAP(); -} - -CBotString CBotVar::GivValString() -{ - ASM_TRAP(); - return CBotString(); -} - -void CBotVar::SetClass(CBotClass* pClass) -{ - ASM_TRAP(); -} - -CBotClass* CBotVar::GivClass() -{ - ASM_TRAP(); - return NULL; -} - -/* -void CBotVar::SetIndirection(CBotVar* pVar) -{ - // nop, uniquement pour CBotVarPointer::SetIndirection -} -*/ - -////////////////////////////////////////////////////////////////////////////////////// - -// copie une variable dans une autre -void CBotVarInt::Copy(CBotVar* pSrc, bool bName) -{ - CBotVarInt* p = (CBotVarInt*)pSrc; - - if ( bName) *m_token = *p->m_token; - m_type = p->m_type; - m_val = p->m_val; - m_binit = p->m_binit; - m_pMyThis = NULL; - m_pUserPtr = p->m_pUserPtr; - - // garde le même idendificateur (par défaut) - if (m_ident == 0 ) m_ident = p->m_ident; - - m_defnum = p->m_defnum; -} - - - - -void CBotVarInt::SetValInt(int val, const char* defnum) -{ - m_val = val; - m_binit = true; - m_defnum = defnum; -} - - - -void CBotVarInt::SetValFloat(float val) -{ - m_val = (int)val; - m_binit = true; -} - -int CBotVarInt::GivValInt() -{ - return m_val; -} - -float CBotVarInt::GivValFloat() -{ - return (float)m_val; -} - -CBotString CBotVarInt::GivValString() -{ - if ( !m_defnum.IsEmpty() ) return m_defnum; - - CBotString res; - - if ( !m_binit ) - { - res.LoadString(TX_UNDEF); - return res; - } - if ( m_binit == IS_NAN ) - { - res.LoadString(TX_NAN); - return res; - } - - char buffer[300]; - sprintf(buffer, "%d", m_val); - res = buffer; - - return res; -} - - -void CBotVarInt::Mul(CBotVar* left, CBotVar* right) -{ - m_val = left->GivValInt() * right->GivValInt(); - m_binit = true; -} - -void CBotVarInt::Power(CBotVar* left, CBotVar* right) -{ - m_val = (int) pow( (double) left->GivValInt() , (double) right->GivValInt() ); - m_binit = true; -} - -int CBotVarInt::Div(CBotVar* left, CBotVar* right) -{ - int r = right->GivValInt(); - if ( r != 0 ) - { - m_val = left->GivValInt() / r; - m_binit = true; - } - return ( r == 0 ? TX_DIVZERO : 0 ); -} - -int CBotVarInt::Modulo(CBotVar* left, CBotVar* right) -{ - int r = right->GivValInt(); - if ( r != 0 ) - { - m_val = left->GivValInt() % r; - m_binit = true; - } - return ( r == 0 ? TX_DIVZERO : 0 ); -} - -void CBotVarInt::Add(CBotVar* left, CBotVar* right) -{ - m_val = left->GivValInt() + right->GivValInt(); - m_binit = true; -} - -void CBotVarInt::Sub(CBotVar* left, CBotVar* right) -{ - m_val = left->GivValInt() - right->GivValInt(); - m_binit = true; -} - -void CBotVarInt::XOr(CBotVar* left, CBotVar* right) -{ - m_val = left->GivValInt() ^ right->GivValInt(); - m_binit = true; -} - -void CBotVarInt::And(CBotVar* left, CBotVar* right) -{ - m_val = left->GivValInt() & right->GivValInt(); - m_binit = true; -} - -void CBotVarInt::Or(CBotVar* left, CBotVar* right) -{ - m_val = left->GivValInt() | right->GivValInt(); - m_binit = true; -} - -void CBotVarInt::SL(CBotVar* left, CBotVar* right) -{ - m_val = left->GivValInt() << right->GivValInt(); - m_binit = true; -} - -void CBotVarInt::ASR(CBotVar* left, CBotVar* right) -{ - m_val = left->GivValInt() >> right->GivValInt(); - m_binit = true; -} - -void CBotVarInt::SR(CBotVar* left, CBotVar* right) -{ - int source = left->GivValInt(); - int shift = right->GivValInt(); - if (shift>=1) source &= 0x7fffffff; - m_val = source >> shift; - m_binit = true; -} - -void CBotVarInt::Neg() -{ - m_val = -m_val; -} - -void CBotVarInt::Not() -{ - m_val = ~m_val; -} - -void CBotVarInt::Inc() -{ - m_val++; - m_defnum.Empty(); -} - -void CBotVarInt::Dec() -{ - m_val--; - m_defnum.Empty(); -} - -bool CBotVarInt::Lo(CBotVar* left, CBotVar* right) -{ - return left->GivValInt() < right->GivValInt(); -} - -bool CBotVarInt::Hi(CBotVar* left, CBotVar* right) -{ - return left->GivValInt() > right->GivValInt(); -} - -bool CBotVarInt::Ls(CBotVar* left, CBotVar* right) -{ - return left->GivValInt() <= right->GivValInt(); -} - -bool CBotVarInt::Hs(CBotVar* left, CBotVar* right) -{ - return left->GivValInt() >= right->GivValInt(); -} - -bool CBotVarInt::Eq(CBotVar* left, CBotVar* right) -{ - return left->GivValInt() == right->GivValInt(); -} - -bool CBotVarInt::Ne(CBotVar* left, CBotVar* right) -{ - return left->GivValInt() != right->GivValInt(); -} - - -////////////////////////////////////////////////////////////////////////////////////// - -// copie une variable dans une autre -void CBotVarFloat::Copy(CBotVar* pSrc, bool bName) -{ - CBotVarFloat* p = (CBotVarFloat*)pSrc; - - if (bName) *m_token = *p->m_token; - m_type = p->m_type; - m_val = p->m_val; - m_binit = p->m_binit; -//- m_bStatic = p->m_bStatic; - m_next = NULL; - m_pMyThis = NULL;//p->m_pMyThis; - m_pUserPtr = p->m_pUserPtr; - - // garde le même idendificateur (par défaut) - if (m_ident == 0 ) m_ident = p->m_ident; -} - - - - -void CBotVarFloat::SetValInt(int val, const char* s) -{ - m_val = (float)val; - m_binit = true; -} - -void CBotVarFloat::SetValFloat(float val) -{ - m_val = val; - m_binit = true; -} - -int CBotVarFloat::GivValInt() -{ - return (int)m_val; -} - -float CBotVarFloat::GivValFloat() -{ - return m_val; -} - -CBotString CBotVarFloat::GivValString() -{ - CBotString res; - - if ( !m_binit ) - { - res.LoadString(TX_UNDEF); - return res; - } - if ( m_binit == IS_NAN ) - { - res.LoadString(TX_NAN); - return res; - } - - char buffer[300]; - sprintf(buffer, "%.2f", m_val); - res = buffer; - - return res; -} - - -void CBotVarFloat::Mul(CBotVar* left, CBotVar* right) -{ - m_val = left->GivValFloat() * right->GivValFloat(); - m_binit = true; -} - -void CBotVarFloat::Power(CBotVar* left, CBotVar* right) -{ - m_val = (float)pow( left->GivValFloat() , right->GivValFloat() ); - m_binit = true; -} - -int CBotVarFloat::Div(CBotVar* left, CBotVar* right) -{ - float r = right->GivValFloat(); - if ( r != 0 ) - { - m_val = left->GivValFloat() / r; - m_binit = true; - } - return ( r == 0 ? TX_DIVZERO : 0 ); -} - -int CBotVarFloat::Modulo(CBotVar* left, CBotVar* right) -{ - float r = right->GivValFloat(); - if ( r != 0 ) - { - m_val = (float)fmod( left->GivValFloat() , r ); - m_binit = true; - } - return ( r == 0 ? TX_DIVZERO : 0 ); -} - -void CBotVarFloat::Add(CBotVar* left, CBotVar* right) -{ - m_val = left->GivValFloat() + right->GivValFloat(); - m_binit = true; -} - -void CBotVarFloat::Sub(CBotVar* left, CBotVar* right) -{ - m_val = left->GivValFloat() - right->GivValFloat(); - m_binit = true; -} - -void CBotVarFloat::Neg() -{ - m_val = -m_val; -} - -void CBotVarFloat::Inc() -{ - m_val++; -} - -void CBotVarFloat::Dec() -{ - m_val--; -} - - -bool CBotVarFloat::Lo(CBotVar* left, CBotVar* right) -{ - return left->GivValFloat() < right->GivValFloat(); -} - -bool CBotVarFloat::Hi(CBotVar* left, CBotVar* right) -{ - return left->GivValFloat() > right->GivValFloat(); -} - -bool CBotVarFloat::Ls(CBotVar* left, CBotVar* right) -{ - return left->GivValFloat() <= right->GivValFloat(); -} - -bool CBotVarFloat::Hs(CBotVar* left, CBotVar* right) -{ - return left->GivValFloat() >= right->GivValFloat(); -} - -bool CBotVarFloat::Eq(CBotVar* left, CBotVar* right) -{ - return left->GivValFloat() == right->GivValFloat(); -} - -bool CBotVarFloat::Ne(CBotVar* left, CBotVar* right) -{ - return left->GivValFloat() != right->GivValFloat(); -} - - -////////////////////////////////////////////////////////////////////////////////////// - -// copie une variable dans une autre -void CBotVarBoolean::Copy(CBotVar* pSrc, bool bName) -{ - CBotVarBoolean* p = (CBotVarBoolean*)pSrc; - - if (bName) *m_token = *p->m_token; - m_type = p->m_type; - m_val = p->m_val; - m_binit = p->m_binit; -//- m_bStatic = p->m_bStatic; - m_next = NULL; - m_pMyThis = NULL;//p->m_pMyThis; - m_pUserPtr = p->m_pUserPtr; - - // garde le même idendificateur (par défaut) - if (m_ident == 0 ) m_ident = p->m_ident; -} - - - - -void CBotVarBoolean::SetValInt(int val, const char* s) -{ - m_val = (bool)val; - m_binit = true; -} - -void CBotVarBoolean::SetValFloat(float val) -{ - m_val = (bool)val; - m_binit = true; -} - -int CBotVarBoolean::GivValInt() -{ - return m_val; -} - -float CBotVarBoolean::GivValFloat() -{ - return (float)m_val; -} - -CBotString CBotVarBoolean::GivValString() -{ - CBotString ret; - - CBotString res; - - if ( !m_binit ) - { - res.LoadString(TX_UNDEF); - return res; - } - if ( m_binit == IS_NAN ) - { - res.LoadString(TX_NAN); - return res; - } - - ret.LoadString( m_val > 0 ? ID_TRUE : ID_FALSE ); - return ret; -} - -void CBotVarBoolean::And(CBotVar* left, CBotVar* right) -{ - m_val = left->GivValInt() && right->GivValInt(); - m_binit = true; -} -void CBotVarBoolean::Or(CBotVar* left, CBotVar* right) -{ - m_val = left->GivValInt() || right->GivValInt(); - m_binit = true; -} - -void CBotVarBoolean::XOr(CBotVar* left, CBotVar* right) -{ - m_val = left->GivValInt() ^ right->GivValInt(); - m_binit = true; -} - -void CBotVarBoolean::Not() -{ - m_val = m_val ? false : true ; -} - -bool CBotVarBoolean::Eq(CBotVar* left, CBotVar* right) -{ - return left->GivValInt() == right->GivValInt(); -} - -bool CBotVarBoolean::Ne(CBotVar* left, CBotVar* right) -{ - return left->GivValInt() != right->GivValInt(); -} - -////////////////////////////////////////////////////////////////////////////////////// - -// copie une variable dans une autre -void CBotVarString::Copy(CBotVar* pSrc, bool bName) -{ - CBotVarString* p = (CBotVarString*)pSrc; - - if (bName) *m_token = *p->m_token; - m_type = p->m_type; - m_val = p->m_val; - m_binit = p->m_binit; -//- m_bStatic = p->m_bStatic; - m_next = NULL; - m_pMyThis = NULL;//p->m_pMyThis; - m_pUserPtr = p->m_pUserPtr; - - // garde le même idendificateur (par défaut) - if (m_ident == 0 ) m_ident = p->m_ident; -} - - -void CBotVarString::SetValString(const char* p) -{ - m_val = p; - m_binit = true; -} - -CBotString CBotVarString::GivValString() -{ - if ( !m_binit ) - { - CBotString res; - res.LoadString(TX_UNDEF); - return res; - } - if ( m_binit == IS_NAN ) - { - CBotString res; - res.LoadString(TX_NAN); - return res; - } - - return m_val; -} - - -void CBotVarString::Add(CBotVar* left, CBotVar* right) -{ - m_val = left->GivValString() + right->GivValString(); - m_binit = true; -} - -bool CBotVarString::Eq(CBotVar* left, CBotVar* right) -{ - return (left->GivValString() == right->GivValString()); -} - -bool CBotVarString::Ne(CBotVar* left, CBotVar* right) -{ - return (left->GivValString() != right->GivValString()); -} - - -bool CBotVarString::Lo(CBotVar* left, CBotVar* right) -{ - return (left->GivValString() == right->GivValString()); -} - -bool CBotVarString::Hi(CBotVar* left, CBotVar* right) -{ - return (left->GivValString() == right->GivValString()); -} - -bool CBotVarString::Ls(CBotVar* left, CBotVar* right) -{ - return (left->GivValString() == right->GivValString()); -} - -bool CBotVarString::Hs(CBotVar* left, CBotVar* right) -{ - return (left->GivValString() == right->GivValString()); -} - - -//////////////////////////////////////////////////////////////// - -// copie une variable dans une autre -void CBotVarClass::Copy(CBotVar* pSrc, bool bName) -{ - pSrc = pSrc->GivPointer(); // si source donné par un pointeur - - if ( pSrc->GivType() != CBotTypClass ) - ASM_TRAP(); - - CBotVarClass* p = (CBotVarClass*)pSrc; - - if (bName) *m_token = *p->m_token; - - m_type = p->m_type; - m_binit = p->m_binit; -//- m_bStatic = p->m_bStatic; - m_pClass = p->m_pClass; - if ( p->m_pParent ) - { - ASM_TRAP(); "que faire du pParent"; - } - -// m_next = NULL; - m_pUserPtr = p->m_pUserPtr; - m_pMyThis = NULL;//p->m_pMyThis; - m_ItemIdent = p->m_ItemIdent; - - // garde le même idendificateur (par défaut) - if (m_ident == 0 ) m_ident = p->m_ident; - - delete m_pVar; - m_pVar = NULL; - - CBotVar* pv = p->m_pVar; - while( pv != NULL ) - { - CBotVar* pn = CBotVar::Create(pv); - pn->Copy( pv ); - if ( m_pVar == NULL ) m_pVar = pn; - else m_pVar->AddNext(pn); - - pv = pv->GivNext(); - } -} - -void CBotVarClass::SetItemList(CBotVar* pVar) -{ - delete m_pVar; - m_pVar = pVar; // remplace le pointeur existant -} - -void CBotVarClass::SetIdent(long n) -{ - m_ItemIdent = n; -} - -void CBotVarClass::SetClass(CBotClass* pClass)//, int &nIdent) -{ - m_type.m_pClass = pClass; - - if ( m_pClass == pClass ) return; - - m_pClass = pClass; - - // initialise les variables associées à cette classe - delete m_pVar; - m_pVar = NULL; - - if (pClass == NULL) return; - - CBotVar* pv = pClass->GivVar(); // premier de la liste - while ( pv != NULL ) - { - // cherche les dimensions max du tableau - CBotInstr* p = pv->m_LimExpr; // les différentes formules - if ( p != NULL ) - { - CBotStack* pile = CBotStack::FirstStack(); // une pile indépendante - int n = 0; - int max[100]; - - while (p != NULL) - { - while( pile->IsOk() && !p->Execute(pile) ) ; // calcul de la taille sans interruptions - CBotVar* v = pile->GivVar(); // résultat - max[n] = v->GivValInt(); // valeur - n++; - p = p->GivNext3(); - } - while (n<100) max[n++] = 0; - - pv->m_type.SetArray( max ); // mémorise les limitations - pile->Delete(); - } - - CBotVar* pn = CBotVar::Create( pv ); // une copie - pn->SetStatic(pv->IsStatic()); - pn->SetPrivate(pv->GivPrivate()); - - if ( pv->m_InitExpr != NULL ) // expression pour l'initialisation ? - { -#if STACKMEM - CBotStack* pile = CBotStack::FirstStack(); // une pile indépendante - - while(pile->IsOk() && !pv->m_InitExpr->Execute(pile, pn)); // évalue l'expression sans timer - - pile->Delete(); -#else - CBotStack* pile = new CBotStack(NULL); // une pile indépendante - while(!pv->m_InitExpr->Execute(pile)); // évalue l'expression sans timer - pn->SetVal( pile->GivVar() ) ; - delete pile; -#endif - } - -// pn->SetUniqNum(CBotVar::NextUniqNum()); // numérote les éléments - pn->SetUniqNum(pv->GivUniqNum()); //++nIdent - pn->m_pMyThis = this; - - if ( m_pVar == NULL) m_pVar = pn; - else m_pVar->AddNext( pn ); - pv = pv->GivNext(); - } -} - -CBotClass* CBotVarClass::GivClass() -{ - return m_pClass; -} - - -void CBotVarClass::Maj(void* pUser, bool bContinu) -{ -/* if (!bContinu && m_pMyThis != NULL) - m_pMyThis->Maj(pUser, true);*/ - - // une routine de mise à jour existe-elle ? - - if ( m_pClass->m_rMaj == NULL ) return; - - // récupère le pointeur user selon la classe - // ou selon le paramètre passé au CBotProgram::Run() - - if ( m_pUserPtr != NULL) pUser = m_pUserPtr; - if ( pUser == OBJECTDELETED || - pUser == OBJECTCREATED ) return; - m_pClass->m_rMaj( this, pUser ); -} - -CBotVar* CBotVarClass::GivItem(const char* name) -{ - CBotVar* p = m_pVar; - - while ( p != NULL ) - { - if ( p->GivName() == name ) return p; - p = p->GivNext(); - } - - if ( m_pParent != NULL ) return m_pParent->GivItem(name); - return NULL; -} - -CBotVar* CBotVarClass::GivItemRef(int nIdent) -{ - CBotVar* p = m_pVar; - - while ( p != NULL ) - { - if ( p->GivUniqNum() == nIdent ) return p; - p = p->GivNext(); - } - - if ( m_pParent != NULL ) return m_pParent->GivItemRef(nIdent); - return NULL; -} - -// pour la gestion d'un tableau -// bExtend permet d'agrandir le tableau, mais pas au dela de la taille fixée par SetArray() - -CBotVar* CBotVarClass::GivItem(int n, bool bExtend) -{ - CBotVar* p = m_pVar; - - if ( n < 0 ) return NULL; - if ( n > MAXARRAYSIZE ) return NULL; - - if ( m_type.GivLimite() >= 0 && n >= m_type.GivLimite() ) return NULL; - - if ( p == NULL && bExtend ) - { - p = CBotVar::Create("", m_type.GivTypElem()); - m_pVar = p; - } - - if ( n == 0 ) return p; - - while ( n-- > 0 ) - { - if ( p->m_next == NULL ) - { - if ( bExtend ) p->m_next = CBotVar::Create("", m_type.GivTypElem()); - if ( p->m_next == NULL ) return NULL; - } - p = p->m_next; - } - - return p; -} - -CBotVar* CBotVarClass::GivItemList() -{ - return m_pVar; -} - - -CBotString CBotVarClass::GivValString() -{ -// if ( m_Indirect != NULL) return m_Indirect->GivValString(); - - CBotString res; - - if ( m_pClass != NULL ) // pas utilisé pour un array - { - res = m_pClass->GivName() + CBotString("( "); - - CBotVarClass* my = this; - while ( my != NULL ) - { - CBotVar* pv = my->m_pVar; - while ( pv != NULL ) - { - res += pv->GivName() + CBotString("="); - - if ( pv->IsStatic() ) - { - CBotVar* pvv = my->m_pClass->GivItem(pv->GivName()); - res += pvv->GivValString(); - } - else - { - res += pv->GivValString(); - } - pv = pv->GivNext(); - if ( pv != NULL ) res += ", "; - } - my = my->m_pParent; - if ( my != NULL ) - { - res += ") extends "; - res += my->m_pClass->GivName(); - res += " ("; - } - } - } - else - { - res = "( "; - - CBotVar* pv = m_pVar; - while ( pv != NULL ) - { - res += pv->GivValString(); - if ( pv->GivNext() != NULL ) res += ", "; - pv = pv->GivNext(); - } - } - - res += " )"; - return res; -} - -void CBotVarClass::IncrementUse() -{ - m_CptUse++; -} - -void CBotVarClass::DecrementUse() -{ - m_CptUse--; - if ( m_CptUse == 0 ) - { - // s'il y en a un, appel le destructeur - // mais seulement si un constructeur avait été appelé. - if ( m_bConstructor ) - { - m_CptUse++; // ne revient pas dans le destructeur - - // m_error est static dans le stack - // sauve la valeur pour la remettre ensuite - int err, start, end; - CBotStack* pile = NULL; - err = pile->GivError(start,end); // pile == NULL ça ne derange pas !! - - pile = CBotStack::FirstStack(); // efface l'erreur - CBotVar* ppVars[1]; - ppVars[0] = NULL; - - CBotVar* pThis = CBotVar::Create("this", CBotTypNullPointer); - pThis->SetPointer(this); - CBotVar* pResult = NULL; - - CBotString nom = "~" + m_pClass->GivName(); - long ident = 0; - - while ( pile->IsOk() && !m_pClass->ExecuteMethode(ident, nom, pThis, ppVars, pResult, pile, NULL)) ; // attend la fin - - pile->ResetError(err, start,end); - - pile->Delete(); - delete pThis; - m_CptUse--; - } - - delete this; // s'auto-détruit !! - } -} - -CBotVarClass* CBotVarClass::GivPointer() -{ - return this; -} - - -// trouve une instance selon son numéro unique - -CBotVarClass* CBotVarClass::Find(long id) -{ - CBotVarClass* p = m_ExClass; - - while ( p != NULL ) - { - if ( p->m_ItemIdent == id ) return p; - p = p->m_ExNext; - } - - return NULL; -} - -bool CBotVarClass::Eq(CBotVar* left, CBotVar* right) -{ - CBotVar* l = left->GivItemList(); - CBotVar* r = right->GivItemList(); - - while ( l != NULL && r != NULL ) - { - if ( l->Ne(l, r) ) return false; - l = l->GivNext(); - r = r->GivNext(); - } - - // devrait toujours arrivé simultanément au bout (mêmes classes) - return l == r; -} - -bool CBotVarClass::Ne(CBotVar* left, CBotVar* right) -{ - CBotVar* l = left->GivItemList(); - CBotVar* r = right->GivItemList(); - - while ( l != NULL && r != NULL ) - { - if ( l->Ne(l, r) ) return true; - l = l->GivNext(); - r = r->GivNext(); - } - - // devrait toujours arrivé simultanément au bout (mêmes classes) - return l != r; -} - -///////////////////////////////////////////////////////////////////////////// -// gestion des tableaux de variables - -CBotVarArray::CBotVarArray(const CBotToken* name, CBotTypResult& type ) -{ - if ( !type.Eq(CBotTypArrayPointer) && - !type.Eq(CBotTypArrayBody)) ASM_TRAP(); - - m_token = new CBotToken(name); - m_next = NULL; - m_pMyThis = NULL; - m_pUserPtr = NULL; - - m_type = type; - m_type.SetType(CBotTypArrayPointer); - m_binit = false; - - m_pInstance = NULL; // la liste des éléments du tableau -} - -CBotVarArray::~CBotVarArray() -{ - if ( m_pInstance != NULL ) m_pInstance->DecrementUse(); // une référence en moins -} - -// copie une variable dans une autre -void CBotVarArray::Copy(CBotVar* pSrc, bool bName) -{ - if ( pSrc->GivType() != CBotTypArrayPointer ) - ASM_TRAP(); - - CBotVarArray* p = (CBotVarArray*)pSrc; - - if ( bName) *m_token = *p->m_token; - m_type = p->m_type; - m_pInstance = p->GivPointer(); - - if ( m_pInstance != NULL ) - m_pInstance->IncrementUse(); // une référence en plus - - m_binit = p->m_binit; -//- m_bStatic = p->m_bStatic; - m_pMyThis = NULL;//p->m_pMyThis; - m_pUserPtr = p->m_pUserPtr; - - // garde le même idendificateur (par défaut) - if (m_ident == 0 ) m_ident = p->m_ident; -} - -void CBotVarArray::SetPointer(CBotVar* pVarClass) -{ - m_binit = true; // init, même sur un pointeur null - - if ( m_pInstance == pVarClass) return; // spécial, ne pas décrémenter et réincrémenter - // car le décrément peut détruire l'object - - if ( pVarClass != NULL ) - { - if ( pVarClass->GivType() == CBotTypArrayPointer ) - pVarClass = pVarClass->GivPointer(); // le vrai pointeur à l'objet - - if ( !pVarClass->m_type.Eq(CBotTypClass) && - !pVarClass->m_type.Eq(CBotTypArrayBody)) - ASM_TRAP(); - - ((CBotVarClass*)pVarClass)->IncrementUse(); // une référence en plus - } - - if ( m_pInstance != NULL ) m_pInstance->DecrementUse(); - m_pInstance = (CBotVarClass*)pVarClass; -} - - -CBotVarClass* CBotVarArray::GivPointer() -{ - if ( m_pInstance == NULL ) return NULL; - return m_pInstance->GivPointer(); -} - -CBotVar* CBotVarArray::GivItem(int n, bool bExtend) -{ - if ( m_pInstance == NULL ) - { - if ( !bExtend ) return NULL; - // crée une instance pour le tableau - - CBotVarClass* instance = new CBotVarClass(NULL, m_type); - SetPointer( instance ); - } - return m_pInstance->GivItem(n, bExtend); -} - -CBotVar* CBotVarArray::GivItemList() -{ - if ( m_pInstance == NULL) return NULL; - return m_pInstance->GivItemList(); -} - -CBotString CBotVarArray::GivValString() -{ - if ( m_pInstance == NULL ) return ( CBotString( "Null pointer" ) ) ; - return m_pInstance->GivValString(); -} - -bool CBotVarArray::Save1State(FILE* pf) -{ - if ( !WriteType(pf, m_type) ) return false; - return SaveVar(pf, m_pInstance); // sauve l'instance qui gère le tableau -} - - -///////////////////////////////////////////////////////////////////////////// -// gestion des pointeurs à une instance donnée - -CBotVarPointer::CBotVarPointer(const CBotToken* name, CBotTypResult& type ) -{ - if ( !type.Eq(CBotTypPointer) && - !type.Eq(CBotTypNullPointer) && - !type.Eq(CBotTypClass) && // par commodité accepte Class et Intrinsic - !type.Eq(CBotTypIntrinsic) ) ASM_TRAP(); - - m_token = new CBotToken(name); - m_next = NULL; - m_pMyThis = NULL; - m_pUserPtr = NULL; - - m_type = type; - if ( !type.Eq(CBotTypNullPointer) ) - m_type.SetType(CBotTypPointer); // quoi qu'il en soit, c'est un pointeur - m_binit = false; - m_pClass = NULL; - m_pVarClass = NULL; // sera défini par un SetPointer() - - SetClass(type.GivClass() ); -} - -CBotVarPointer::~CBotVarPointer() -{ - if ( m_pVarClass != NULL ) m_pVarClass->DecrementUse(); // une référence en moins -} - - -void CBotVarPointer::Maj(void* pUser, bool bContinu) -{ -/* if ( !bContinu && m_pMyThis != NULL ) - m_pMyThis->Maj(pUser, false);*/ - - if ( m_pVarClass != NULL) m_pVarClass->Maj(pUser, false); -} - -CBotVar* CBotVarPointer::GivItem(const char* name) -{ - if ( m_pVarClass == NULL) // pas d'instance existant ? - return m_pClass->GivItem(name); // rend le pointeur dans la classe elle-même - - return m_pVarClass->GivItem(name); -} - -CBotVar* CBotVarPointer::GivItemRef(int nIdent) -{ - if ( m_pVarClass == NULL) // pas d'instance existant ? - return m_pClass->GivItemRef(nIdent);// rend le pointeur dans la classe elle-même - - return m_pVarClass->GivItemRef(nIdent); -} - -CBotVar* CBotVarPointer::GivItemList() -{ - if ( m_pVarClass == NULL) return NULL; - return m_pVarClass->GivItemList(); -} - -CBotString CBotVarPointer::GivValString() -{ - CBotString s = "Pointer to "; - if ( m_pVarClass == NULL ) s = "Null pointer" ; - else s += m_pVarClass->GivValString(); - return s; -} - - -void CBotVarPointer::ConstructorSet() -{ - if ( m_pVarClass != NULL) m_pVarClass->ConstructorSet(); -} - -// initialise le pointeur vers l'instance d'une classe - -void CBotVarPointer::SetPointer(CBotVar* pVarClass) -{ - m_binit = true; // init, même sur un pointeur null - - if ( m_pVarClass == pVarClass) return; // spécial, ne pas décrémenter et réincrémenter - // car le décrément peut détruire l'object - - if ( pVarClass != NULL ) - { - if ( pVarClass->GivType() == CBotTypPointer ) - pVarClass = pVarClass->GivPointer(); // le vrai pointeur à l'objet - -// if ( pVarClass->GivType() != CBotTypClass ) - if ( !pVarClass->m_type.Eq(CBotTypClass) ) - ASM_TRAP(); - - ((CBotVarClass*)pVarClass)->IncrementUse(); // une référence en plus - m_pClass = ((CBotVarClass*)pVarClass)->m_pClass; - m_pUserPtr = pVarClass->m_pUserPtr; // pas vraiment indispensable - m_type = CBotTypResult(CBotTypPointer, m_pClass); // un pointeur de quel genre - } - - if ( m_pVarClass != NULL ) m_pVarClass->DecrementUse(); - m_pVarClass = (CBotVarClass*)pVarClass; - -} - -CBotVarClass* CBotVarPointer::GivPointer() -{ - if ( m_pVarClass == NULL ) return NULL; - return m_pVarClass->GivPointer(); -} - -void CBotVarPointer::SetIdent(long n) -{ - if ( m_pVarClass == NULL ) return; - m_pVarClass->SetIdent( n ); -} - -long CBotVarPointer::GivIdent() -{ - if ( m_pVarClass == NULL ) return 0; - return m_pVarClass->m_ItemIdent; -} - - -void CBotVarPointer::SetClass(CBotClass* pClass) -{ -// int nIdent = 0; - m_type.m_pClass = m_pClass = pClass; - if ( m_pVarClass != NULL ) m_pVarClass->SetClass(pClass); //, nIdent); -} - -CBotClass* CBotVarPointer::GivClass() -{ - if ( m_pVarClass != NULL ) return m_pVarClass->GivClass(); - - return m_pClass; -} - - -bool CBotVarPointer::Save1State(FILE* pf) -{ - if ( m_pClass ) - { - if (!WriteString(pf, m_pClass->GivName())) return false; // nom de la classe - } - else - { - if (!WriteString(pf, "")) return false; - } - - if (!WriteLong(pf, GivIdent())) return false; // la référence unique - - // sauve aussi une copie de l'instance - return SaveVar(pf, GivPointer()); -} - -// copie une variable dans une autre -void CBotVarPointer::Copy(CBotVar* pSrc, bool bName) -{ - if ( pSrc->GivType() != CBotTypPointer && - pSrc->GivType() != CBotTypNullPointer) - ASM_TRAP(); - - CBotVarPointer* p = (CBotVarPointer*)pSrc; - - if ( bName) *m_token = *p->m_token; - m_type = p->m_type; -// m_pVarClass = p->m_pVarClass; - m_pVarClass = p->GivPointer(); - - if ( m_pVarClass != NULL ) - m_pVarClass->IncrementUse(); // une référence en plus - - m_pClass = p->m_pClass; - m_binit = p->m_binit; -//- m_bStatic = p->m_bStatic; - m_next = NULL; - m_pMyThis = NULL;//p->m_pMyThis; - m_pUserPtr = p->m_pUserPtr; - - // garde le même idendificateur (par défaut) - if (m_ident == 0 ) m_ident = p->m_ident; -} - -bool CBotVarPointer::Eq(CBotVar* left, CBotVar* right) -{ - CBotVarClass* l = left->GivPointer(); - CBotVarClass* r = right->GivPointer(); - - if ( l == r ) return true; - if ( l == NULL && r->GivUserPtr() == OBJECTDELETED ) return true; - if ( r == NULL && l->GivUserPtr() == OBJECTDELETED ) return true; - return false; -} - -bool CBotVarPointer::Ne(CBotVar* left, CBotVar* right) -{ - CBotVarClass* l = left->GivPointer(); - CBotVarClass* r = right->GivPointer(); - - if ( l == r ) return false; - if ( l == NULL && r->GivUserPtr() == OBJECTDELETED ) return false; - if ( r == NULL && l->GivUserPtr() == OBJECTDELETED ) return false; - return true; -} - - - -/////////////////////////////////////////////////////// -// gestion des types de résultats - - -CBotTypResult::CBotTypResult(int type) -{ - m_type = type; - m_pNext = NULL; - m_pClass = NULL; - m_limite = -1; -} - -CBotTypResult::CBotTypResult(int type, const char* name) -{ - m_type = type; - m_pNext = NULL; - m_pClass = NULL; - m_limite = -1; - - if ( type == CBotTypPointer || - type == CBotTypClass || - type == CBotTypIntrinsic ) - { - m_pClass = CBotClass::Find(name); - if ( m_pClass && m_pClass->IsIntrinsic() ) m_type = CBotTypIntrinsic; - } -} - -CBotTypResult::CBotTypResult(int type, CBotClass* pClass) -{ - m_type = type; - m_pNext = NULL; - m_pClass = pClass; - m_limite = -1; - - if ( m_pClass && m_pClass->IsIntrinsic() ) m_type = CBotTypIntrinsic; -} - -CBotTypResult::CBotTypResult(int type, CBotTypResult elem) -{ - m_type = type; - m_pNext = NULL; - m_pClass = NULL; - m_limite = -1; - - if ( type == CBotTypArrayPointer || - type == CBotTypArrayBody ) - m_pNext = new CBotTypResult( elem ); -} - -CBotTypResult::CBotTypResult(const CBotTypResult& typ) -{ - m_type = typ.m_type; - m_pClass = typ.m_pClass; - m_pNext = NULL; - m_limite = typ.m_limite; - - if ( typ.m_pNext ) - m_pNext = new CBotTypResult( *typ.m_pNext ); -} - -CBotTypResult::CBotTypResult() -{ - m_type = 0; - m_limite = -1; - m_pNext = NULL; - m_pClass = NULL; -} - -CBotTypResult::~CBotTypResult() -{ - delete m_pNext; -} - -int CBotTypResult::GivType(int mode) const -{ -#ifdef _DEBUG - if ( m_type == CBotTypPointer || - m_type == CBotTypClass || - m_type == CBotTypIntrinsic ) - - if ( m_pClass == NULL ) ASM_TRAP(); - - - if ( m_type == CBotTypArrayPointer ) - if ( m_pNext == NULL ) ASM_TRAP(); -#endif - if ( mode == 3 && m_type == CBotTypNullPointer ) return CBotTypPointer; - return m_type; -} - -void CBotTypResult::SetType(int n) -{ - m_type = n; -} - -CBotClass* CBotTypResult::GivClass() const -{ - return m_pClass; -} - -CBotTypResult& CBotTypResult::GivTypElem() const -{ - return *m_pNext; -} - -int CBotTypResult::GivLimite() const -{ - return m_limite; -} - -void CBotTypResult::SetLimite(int n) -{ - m_limite = n; -} - -void CBotTypResult::SetArray( int* max ) -{ - m_limite = *max; - if (m_limite < 1) m_limite = -1; - - if ( m_pNext != NULL ) // dernière dimension ? - { - m_pNext->SetArray( max+1 ); - } -} - - - -bool CBotTypResult::Compare(const CBotTypResult& typ) const -{ - if ( m_type != typ.m_type ) return false; - - if ( m_type == CBotTypArrayPointer ) return m_pNext->Compare(*typ.m_pNext); - - if ( m_type == CBotTypPointer || - m_type == CBotTypClass || - m_type == CBotTypIntrinsic ) - { - return m_pClass == typ.m_pClass; - } - - return true; -} - -bool CBotTypResult::Eq(int type) const -{ - return m_type == type; -} - -CBotTypResult& - CBotTypResult::operator=(const CBotTypResult& src) -{ - m_type = src.m_type; - m_limite = src.m_limite; - m_pClass = src.m_pClass; - m_pNext = NULL; - if ( src.m_pNext != NULL ) - { - m_pNext = new CBotTypResult(*src.m_pNext); - } - return *this; -} - - +// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * 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://www.gnu.org/licenses/. + +//////////////////////////////////////////////////////////////////// +// Definition for the class CBotVar +// variables management of the language CBoT + +// it never creates an instance of the class mother CBotVar + +#include "CBot.h" +#include +#include + +long CBotVar::m_identcpt = 0; + +CBotVar::CBotVar( ) +{ + m_next = NULL; + m_pMyThis = NULL; + m_pUserPtr = NULL; + m_InitExpr = NULL; + m_LimExpr = NULL; + m_type = -1; + m_binit = false; + m_ident = 0; + m_bStatic = false; + m_mPrivate = 0; +} + +CBotVarInt::CBotVarInt( const CBotToken* name ) +{ + m_token = new CBotToken(name); + m_next = NULL; + m_pMyThis = NULL; + m_pUserPtr = NULL; + m_InitExpr = NULL; + m_LimExpr = NULL; + m_type = CBotTypInt; + m_binit = false; + m_bStatic = false; + m_mPrivate = 0; + + m_val = 0; +} + +CBotVarFloat::CBotVarFloat( const CBotToken* name ) +{ + m_token = new CBotToken(name); + m_next = NULL; + m_pMyThis = NULL; + m_pUserPtr = NULL; + m_InitExpr = NULL; + m_LimExpr = NULL; + m_type = CBotTypFloat; + m_binit = false; + m_bStatic = false; + m_mPrivate = 0; + + m_val = 0; +} + +CBotVarString::CBotVarString( const CBotToken* name ) +{ + m_token = new CBotToken(name); + m_next = NULL; + m_pMyThis = NULL; + m_pUserPtr = NULL; + m_InitExpr = NULL; + m_LimExpr = NULL; + m_type = CBotTypString; + m_binit = false; + m_bStatic = false; + m_mPrivate = 0; + + m_val.Empty(); +} + +CBotVarBoolean::CBotVarBoolean( const CBotToken* name ) +{ + m_token = new CBotToken(name); + m_next = NULL; + m_pMyThis = NULL; + m_pUserPtr = NULL; + m_InitExpr = NULL; + m_LimExpr = NULL; + m_type = CBotTypBoolean; + m_binit = false; + m_bStatic = false; + m_mPrivate = 0; + + m_val = 0; +} + +CBotVarClass* CBotVarClass::m_ExClass = NULL; + +CBotVarClass::CBotVarClass( const CBotToken* name, const CBotTypResult& type) +{ +/* +// int nIdent = 0; + InitCBotVarClass( name, type ) //, nIdent ); +} + +CBotVarClass::CBotVarClass( const CBotToken* name, CBotTypResult& type) //, int &nIdent ) +{ + InitCBotVarClass( name, type ); //, nIdent ); +} + +void CBotVarClass::InitCBotVarClass( const CBotToken* name, CBotTypResult& type ) //, int &nIdent ) +{*/ + if ( !type.Eq(CBotTypClass) && + !type.Eq(CBotTypIntrinsic) && // by convenience there accepts these types + !type.Eq(CBotTypPointer) && + !type.Eq(CBotTypArrayPointer) && + !type.Eq(CBotTypArrayBody)) ASM_TRAP(); + + m_token = new CBotToken(name); + m_next = NULL; + m_pMyThis = NULL; + m_pUserPtr = OBJECTCREATED;//NULL; + m_InitExpr = NULL; + m_LimExpr = NULL; + m_pVar = NULL; + m_type = type; + if ( type.Eq(CBotTypArrayPointer) ) m_type.SetType( CBotTypArrayBody ); + else if ( !type.Eq(CBotTypArrayBody) ) m_type.SetType( CBotTypClass ); + // officel type for this object + + m_pClass = NULL; + m_pParent = NULL; + m_binit = false; + m_bStatic = false; + m_mPrivate = 0; + m_bConstructor = false; + m_CptUse = 0; + m_ItemIdent = type.Eq(CBotTypIntrinsic) ? 0 : CBotVar::NextUniqNum(); + + // se place tout seul dans la liste + // TODO stands alone in the list (stands only in a list) + if (m_ExClass) m_ExClass->m_ExPrev = this; + m_ExNext = m_ExClass; + m_ExPrev = NULL; + m_ExClass = this; + + CBotClass* pClass = type.GivClass(); + CBotClass* pClass2 = pClass->GivParent(); + if ( pClass2 != NULL ) + { + // also creates an instance of the parent class + m_pParent = new CBotVarClass(name, CBotTypResult(type.GivType(),pClass2) ); //, nIdent); + } + + SetClass( pClass ); //, nIdent ); + +} + +CBotVarClass::~CBotVarClass( ) +{ + if ( m_CptUse != 0 ) + ASM_TRAP(); + + if ( m_pParent ) delete m_pParent; + m_pParent = NULL; + + // frees the indirect object if necessary +// if ( m_Indirect != NULL ) +// m_Indirect->DecrementUse(); + + // removes the class list + if ( m_ExPrev ) m_ExPrev->m_ExNext = m_ExNext; + else m_ExClass = m_ExNext; + + if ( m_ExNext ) m_ExNext->m_ExPrev = m_ExPrev; + m_ExPrev = NULL; + m_ExNext = NULL; + + delete m_pVar; +} + +void CBotVarClass::ConstructorSet() +{ + m_bConstructor = true; +} + + +CBotVar::~CBotVar( ) +{ + delete m_token; + delete m_next; +} + +void CBotVar::debug() +{ + const char* p = (const char*) m_token->GivString(); + CBotString s = (const char*) GivValString(); + const char* v = (const char*) s; + + if ( m_type.Eq(CBotTypClass) ) + { + CBotVar* pv = ((CBotVarClass*)this)->m_pVar; + while (pv != NULL) + { + pv->debug(); + pv = pv->GivNext(); + } + } +} + +void CBotVar::ConstructorSet() +{ + // nop +} + +void CBotVar::SetUserPtr(void* pUser) +{ + m_pUserPtr = pUser; + if (m_type.Eq(CBotTypPointer) && + ((CBotVarPointer*)this)->m_pVarClass != NULL ) + ((CBotVarPointer*)this)->m_pVarClass->SetUserPtr(pUser); +} + +void CBotVar::SetIdent(long n) +{ + if (m_type.Eq(CBotTypPointer) && + ((CBotVarPointer*)this)->m_pVarClass != NULL ) + ((CBotVarPointer*)this)->m_pVarClass->SetIdent(n); +} + +void CBotVar::SetUniqNum(long n) +{ + m_ident = n; + + if ( n == 0 ) ASM_TRAP(); +} + +long CBotVar::NextUniqNum() +{ + if (++m_identcpt < 10000) m_identcpt = 10000; + return m_identcpt; +} + +long CBotVar::GivUniqNum() +{ + return m_ident; +} + + +void* CBotVar::GivUserPtr() +{ + return m_pUserPtr; +} + +bool CBotVar::Save1State(FILE* pf) +{ + // this routine "virtual" must never be called, + // there must be a routine for each of the subclasses (CBotVarInt, CBotVarFloat, etc) + // ( see the type in m_type ) + ASM_TRAP(); + return false; +} + +void CBotVar::Maj(void* pUser, bool bContinu) +{ +/* if (!bContinu && m_pMyThis != NULL) + m_pMyThis->Maj(pUser, true);*/ +} + + +// creates a variable depending on its type + +CBotVar* CBotVar::Create(const CBotToken* name, int type ) +{ + CBotTypResult t(type); + return Create(name, t); +} + +CBotVar* CBotVar::Create(const CBotToken* name, CBotTypResult type) +{ + switch (type.GivType()) + { + case CBotTypShort: + case CBotTypInt: + return new CBotVarInt(name); + case CBotTypFloat: + return new CBotVarFloat(name); + case CBotTypBoolean: + return new CBotVarBoolean(name); + case CBotTypString: + return new CBotVarString(name); + case CBotTypPointer: + case CBotTypNullPointer: + return new CBotVarPointer(name, type); + case CBotTypIntrinsic: + return new CBotVarClass(name, type); + + case CBotTypClass: + // creates a new instance of a class + // and returns the POINTER on this instance + { + CBotVarClass* instance = new CBotVarClass(name, type); + CBotVarPointer* pointer = new CBotVarPointer(name, type); + pointer->SetPointer( instance ); + return pointer; + } + + case CBotTypArrayPointer: + return new CBotVarArray(name, type); + + case CBotTypArrayBody: + { + CBotVarClass* instance = new CBotVarClass(name, type); + CBotVarArray* array = new CBotVarArray(name, type); + array->SetPointer( instance ); + + CBotVar* pv = array; + while (type.Eq(CBotTypArrayBody)) + { + type = type.GivTypElem(); + pv = ((CBotVarArray*)pv)->GivItem(0, true); // creates at least the element [0] + } + + return array; + } + } + + ASM_TRAP(); + return NULL; +} + +CBotVar* CBotVar::Create( CBotVar* pVar ) +{ + CBotVar* p = Create(pVar->m_token->GivString(), pVar->GivTypResult(2)); + return p; +} + + +CBotVar* CBotVar::Create( const char* n, CBotTypResult type) +{ + CBotToken name(n); + + switch (type.GivType()) + { + case CBotTypShort: + case CBotTypInt: + return new CBotVarInt(&name); + case CBotTypFloat: + return new CBotVarFloat(&name); + case CBotTypBoolean: + return new CBotVarBoolean(&name); + case CBotTypString: + return new CBotVarString(&name); + case CBotTypPointer: + case CBotTypNullPointer: + { + CBotVarPointer* p = new CBotVarPointer(&name, type); +// p->SetClass(type.GivClass()); + return p; + } + case CBotTypIntrinsic: + { + CBotVarClass* p = new CBotVarClass(&name, type); +// p->SetClass(type.GivClass()); + return p; + } + + case CBotTypClass: + // creates a new instance of a class + // and returns the POINTER on this instance + { + CBotVarClass* instance = new CBotVarClass(&name, type); + CBotVarPointer* pointer = new CBotVarPointer(&name, type); + pointer->SetPointer( instance ); +// pointer->SetClass( type.GivClass() ); + return pointer; + } + + case CBotTypArrayPointer: + return new CBotVarArray(&name, type); + + case CBotTypArrayBody: + { + CBotVarClass* instance = new CBotVarClass(&name, type); + CBotVarArray* array = new CBotVarArray(&name, type); + array->SetPointer( instance ); + + CBotVar* pv = array; + while (type.Eq(CBotTypArrayBody)) + { + type = type.GivTypElem(); + pv = ((CBotVarArray*)pv)->GivItem(0, true); // creates at least the element [0] + } + + return array; + } + } + + ASM_TRAP(); + return NULL; +} + +CBotVar* CBotVar::Create( const char* name, int type, CBotClass* pClass) +{ + CBotToken token( name, "" ); + CBotVar* pVar = Create( &token, type ); + + if ( type == CBotTypPointer && pClass == NULL ) // pointer "null" ? + return pVar; + + if ( type == CBotTypClass || type == CBotTypPointer || + type == CBotTypIntrinsic ) + { + if (pClass == NULL) + { + delete pVar; + return NULL; + } + pVar->SetClass( pClass ); + } + return pVar; +} + +CBotVar* CBotVar::Create( const char* name, CBotClass* pClass) +{ + CBotToken token( name, "" ); + CBotVar* pVar = Create( &token, CBotTypResult( CBotTypClass, pClass ) ); +// pVar->SetClass( pClass ); + return pVar; +} + +CBotTypResult CBotVar::GivTypResult(int mode) +{ + CBotTypResult r = m_type; + + if ( mode == 1 && m_type.Eq(CBotTypClass) ) + r.SetType(CBotTypPointer); + if ( mode == 2 && m_type.Eq(CBotTypClass) ) + r.SetType(CBotTypIntrinsic); + + return r; +} + +int CBotVar::GivType(int mode) +{ + if ( mode == 1 && m_type.Eq(CBotTypClass) ) + return CBotTypPointer; + if ( mode == 2 && m_type.Eq(CBotTypClass) ) + return CBotTypIntrinsic; + return m_type.GivType(); +} + +void CBotVar::SetType(CBotTypResult& type) +{ + m_type = type; +} + + +int CBotVar::GivInit() +{ + if ( m_type.Eq(CBotTypClass) ) return IS_DEF; // always set! + + return m_binit; +} + +void CBotVar::SetInit(int bInit) +{ + m_binit = bInit; + if ( bInit == 2 ) m_binit = IS_DEF; // cas spécial + + if ( m_type.Eq(CBotTypPointer) && bInit == 2 ) + { + CBotVarClass* instance = GivPointer(); + if ( instance == NULL ) + { + instance = new CBotVarClass(NULL, m_type); +// instance->SetClass(((CBotVarPointer*)this)->m_pClass); + SetPointer(instance); + } + instance->SetInit(1); + } + + if ( m_type.Eq(CBotTypClass) || m_type.Eq(CBotTypIntrinsic) ) + { + CBotVar* p = ((CBotVarClass*)this)->m_pVar; + while( p != NULL ) + { + p->SetInit( bInit ); + p->m_pMyThis = (CBotVarClass*)this; + p = p->GivNext(); + } + } +} + +CBotString CBotVar::GivName() +{ + return m_token->GivString(); +} + +void CBotVar::SetName(const char* name) +{ + m_token->SetString(name); +} + +CBotToken* CBotVar::GivToken() +{ + return m_token; +} + +CBotVar* CBotVar::GivItem(const char* name) +{ + ASM_TRAP(); + return NULL; +} + +CBotVar* CBotVar::GivItemRef(int nIdent) +{ + ASM_TRAP(); + return NULL; +} + +CBotVar* CBotVar::GivItemList() +{ + ASM_TRAP(); + return NULL; +} + +CBotVar* CBotVar::GivItem(int row, bool bGrow) +{ + ASM_TRAP(); + return NULL; +} + +// check if a variable belongs to a given class +bool CBotVar::IsElemOfClass(const char* name) +{ + CBotClass* pc = NULL; + + if ( m_type.Eq(CBotTypPointer) ) + { + pc = ((CBotVarPointer*)this)->m_pClass; + } + if ( m_type.Eq(CBotTypClass) ) + { + pc = ((CBotVarClass*)this)->m_pClass; + } + + while ( pc != NULL ) + { + if ( pc->GivName() == name ) return true; + pc = pc->GivParent(); + } + + return false; +} + + +CBotVar* CBotVar::GivStaticVar() +{ + // makes the pointer to the variable if it is static + if ( m_bStatic == 0 || m_pMyThis == NULL ) return this; + + CBotClass* pClass = m_pMyThis->GivClass(); + return pClass->GivItem( m_token->GivString() ); +} + + +CBotVar* CBotVar::GivNext() +{ + return m_next; +} + +void CBotVar::AddNext(CBotVar* pVar) +{ + CBotVar* p = this; + while (p->m_next != NULL) p = p->m_next; + + p->m_next = pVar; +} + +void CBotVar::SetVal(CBotVar* var) +{ + switch (/*var->*/GivType()) + { + case CBotTypBoolean: + SetValInt(var->GivValInt()); + break; + case CBotTypInt: + SetValInt(var->GivValInt(), ((CBotVarInt*)var)->m_defnum); + break; + case CBotTypFloat: + SetValFloat(var->GivValFloat()); + break; + case CBotTypString: + SetValString(var->GivValString()); + break; + case CBotTypPointer: + case CBotTypNullPointer: + case CBotTypArrayPointer: + SetPointer(var->GivPointer()); + break; + case CBotTypClass: + { + delete ((CBotVarClass*)this)->m_pVar; + ((CBotVarClass*)this)->m_pVar = NULL; + Copy(var, false); + } + break; + default: + ASM_TRAP(); + } + + m_binit = var->m_binit; // copie l'état nan s'il y a +} + +void CBotVar::SetStatic(bool bStatic) +{ + m_bStatic = bStatic; +} + +void CBotVar::SetPrivate(int mPrivate) +{ + m_mPrivate = mPrivate; +} + +bool CBotVar::IsStatic() +{ + return m_bStatic; +} + +bool CBotVar::IsPrivate(int mode) +{ + return m_mPrivate >= mode; +} + +int CBotVar::GivPrivate() +{ + return m_mPrivate; +} + + +void CBotVar::SetPointer(CBotVar* pVarClass) +{ + ASM_TRAP(); +} + +CBotVarClass* CBotVar::GivPointer() +{ + ASM_TRAP(); + return NULL; +} + +// All these functions must be defined in the subclasses +// derived from class CBotVar + +int CBotVar::GivValInt() +{ + ASM_TRAP(); + return 0; +} + +float CBotVar::GivValFloat() +{ + ASM_TRAP(); + return 0; +} + +void CBotVar::SetValInt(int c, const char* s) +{ + ASM_TRAP(); +} + +void CBotVar::SetValFloat(float c) +{ + ASM_TRAP(); +} + +void CBotVar::Mul(CBotVar* left, CBotVar* right) +{ + ASM_TRAP(); +} + +void CBotVar::Power(CBotVar* left, CBotVar* right) +{ + ASM_TRAP(); +} + +int CBotVar::Div(CBotVar* left, CBotVar* right) +{ + ASM_TRAP(); + return 0; +} + +int CBotVar::Modulo(CBotVar* left, CBotVar* right) +{ + ASM_TRAP(); + return 0; +} + +void CBotVar::Add(CBotVar* left, CBotVar* right) +{ + ASM_TRAP(); +} + +void CBotVar::Sub(CBotVar* left, CBotVar* right) +{ + ASM_TRAP(); +} + +bool CBotVar::Lo(CBotVar* left, CBotVar* right) +{ + ASM_TRAP(); + return false; +} + +bool CBotVar::Hi(CBotVar* left, CBotVar* right) +{ + ASM_TRAP(); + return false; +} + +bool CBotVar::Ls(CBotVar* left, CBotVar* right) +{ + ASM_TRAP(); + return false; +} + +bool CBotVar::Hs(CBotVar* left, CBotVar* right) +{ + ASM_TRAP(); + return false; +} + +bool CBotVar::Eq(CBotVar* left, CBotVar* right) +{ + ASM_TRAP(); + return false; +} + +bool CBotVar::Ne(CBotVar* left, CBotVar* right) +{ + ASM_TRAP(); + return false; +} + +void CBotVar::And(CBotVar* left, CBotVar* right) +{ + ASM_TRAP(); +} + +void CBotVar::Or(CBotVar* left, CBotVar* right) +{ + ASM_TRAP(); +} + +void CBotVar::XOr(CBotVar* left, CBotVar* right) +{ + ASM_TRAP(); +} + +void CBotVar::ASR(CBotVar* left, CBotVar* right) +{ + ASM_TRAP(); +} + +void CBotVar::SR(CBotVar* left, CBotVar* right) +{ + ASM_TRAP(); +} + +void CBotVar::SL(CBotVar* left, CBotVar* right) +{ + ASM_TRAP(); +} + +void CBotVar::Neg() +{ + ASM_TRAP(); +} + +void CBotVar::Not() +{ + ASM_TRAP(); +} + +void CBotVar::Inc() +{ + ASM_TRAP(); +} +void CBotVar::Dec() +{ + ASM_TRAP(); +} + +void CBotVar::Copy(CBotVar* pSrc, bool bName) +{ + ASM_TRAP(); +} + +void CBotVar::SetValString(const char* p) +{ + ASM_TRAP(); +} + +CBotString CBotVar::GivValString() +{ + ASM_TRAP(); + return CBotString(); +} + +void CBotVar::SetClass(CBotClass* pClass) +{ + ASM_TRAP(); +} + +CBotClass* CBotVar::GivClass() +{ + ASM_TRAP(); + return NULL; +} + +/* +void CBotVar::SetIndirection(CBotVar* pVar) +{ + // nop, only CBotVarPointer::SetIndirection +} +*/ + +////////////////////////////////////////////////////////////////////////////////////// + +// copy a variable in to another +void CBotVarInt::Copy(CBotVar* pSrc, bool bName) +{ + CBotVarInt* p = (CBotVarInt*)pSrc; + + if ( bName) *m_token = *p->m_token; + m_type = p->m_type; + m_val = p->m_val; + m_binit = p->m_binit; + m_pMyThis = NULL; + m_pUserPtr = p->m_pUserPtr; + + // identificator is the same (by défaut) + if (m_ident == 0 ) m_ident = p->m_ident; + + m_defnum = p->m_defnum; +} + + + + +void CBotVarInt::SetValInt(int val, const char* defnum) +{ + m_val = val; + m_binit = true; + m_defnum = defnum; +} + + + +void CBotVarInt::SetValFloat(float val) +{ + m_val = (int)val; + m_binit = true; +} + +int CBotVarInt::GivValInt() +{ + return m_val; +} + +float CBotVarInt::GivValFloat() +{ + return (float)m_val; +} + +CBotString CBotVarInt::GivValString() +{ + if ( !m_defnum.IsEmpty() ) return m_defnum; + + CBotString res; + + if ( !m_binit ) + { + res.LoadString(TX_UNDEF); + return res; + } + if ( m_binit == IS_NAN ) + { + res.LoadString(TX_NAN); + return res; + } + + char buffer[300]; + sprintf(buffer, "%d", m_val); + res = buffer; + + return res; +} + + +void CBotVarInt::Mul(CBotVar* left, CBotVar* right) +{ + m_val = left->GivValInt() * right->GivValInt(); + m_binit = true; +} + +void CBotVarInt::Power(CBotVar* left, CBotVar* right) +{ + m_val = (int) pow( (double) left->GivValInt() , (double) right->GivValInt() ); + m_binit = true; +} + +int CBotVarInt::Div(CBotVar* left, CBotVar* right) +{ + int r = right->GivValInt(); + if ( r != 0 ) + { + m_val = left->GivValInt() / r; + m_binit = true; + } + return ( r == 0 ? TX_DIVZERO : 0 ); +} + +int CBotVarInt::Modulo(CBotVar* left, CBotVar* right) +{ + int r = right->GivValInt(); + if ( r != 0 ) + { + m_val = left->GivValInt() % r; + m_binit = true; + } + return ( r == 0 ? TX_DIVZERO : 0 ); +} + +void CBotVarInt::Add(CBotVar* left, CBotVar* right) +{ + m_val = left->GivValInt() + right->GivValInt(); + m_binit = true; +} + +void CBotVarInt::Sub(CBotVar* left, CBotVar* right) +{ + m_val = left->GivValInt() - right->GivValInt(); + m_binit = true; +} + +void CBotVarInt::XOr(CBotVar* left, CBotVar* right) +{ + m_val = left->GivValInt() ^ right->GivValInt(); + m_binit = true; +} + +void CBotVarInt::And(CBotVar* left, CBotVar* right) +{ + m_val = left->GivValInt() & right->GivValInt(); + m_binit = true; +} + +void CBotVarInt::Or(CBotVar* left, CBotVar* right) +{ + m_val = left->GivValInt() | right->GivValInt(); + m_binit = true; +} + +void CBotVarInt::SL(CBotVar* left, CBotVar* right) +{ + m_val = left->GivValInt() << right->GivValInt(); + m_binit = true; +} + +void CBotVarInt::ASR(CBotVar* left, CBotVar* right) +{ + m_val = left->GivValInt() >> right->GivValInt(); + m_binit = true; +} + +void CBotVarInt::SR(CBotVar* left, CBotVar* right) +{ + int source = left->GivValInt(); + int shift = right->GivValInt(); + if (shift>=1) source &= 0x7fffffff; + m_val = source >> shift; + m_binit = true; +} + +void CBotVarInt::Neg() +{ + m_val = -m_val; +} + +void CBotVarInt::Not() +{ + m_val = ~m_val; +} + +void CBotVarInt::Inc() +{ + m_val++; + m_defnum.Empty(); +} + +void CBotVarInt::Dec() +{ + m_val--; + m_defnum.Empty(); +} + +bool CBotVarInt::Lo(CBotVar* left, CBotVar* right) +{ + return left->GivValInt() < right->GivValInt(); +} + +bool CBotVarInt::Hi(CBotVar* left, CBotVar* right) +{ + return left->GivValInt() > right->GivValInt(); +} + +bool CBotVarInt::Ls(CBotVar* left, CBotVar* right) +{ + return left->GivValInt() <= right->GivValInt(); +} + +bool CBotVarInt::Hs(CBotVar* left, CBotVar* right) +{ + return left->GivValInt() >= right->GivValInt(); +} + +bool CBotVarInt::Eq(CBotVar* left, CBotVar* right) +{ + return left->GivValInt() == right->GivValInt(); +} + +bool CBotVarInt::Ne(CBotVar* left, CBotVar* right) +{ + return left->GivValInt() != right->GivValInt(); +} + + +////////////////////////////////////////////////////////////////////////////////////// + +// copy a variable into another +void CBotVarFloat::Copy(CBotVar* pSrc, bool bName) +{ + CBotVarFloat* p = (CBotVarFloat*)pSrc; + + if (bName) *m_token = *p->m_token; + m_type = p->m_type; + m_val = p->m_val; + m_binit = p->m_binit; +//- m_bStatic = p->m_bStatic; + m_next = NULL; + m_pMyThis = NULL;//p->m_pMyThis; + m_pUserPtr = p->m_pUserPtr; + + // keeps indentificator the same (by default) + if (m_ident == 0 ) m_ident = p->m_ident; +} + + + + +void CBotVarFloat::SetValInt(int val, const char* s) +{ + m_val = (float)val; + m_binit = true; +} + +void CBotVarFloat::SetValFloat(float val) +{ + m_val = val; + m_binit = true; +} + +int CBotVarFloat::GivValInt() +{ + return (int)m_val; +} + +float CBotVarFloat::GivValFloat() +{ + return m_val; +} + +CBotString CBotVarFloat::GivValString() +{ + CBotString res; + + if ( !m_binit ) + { + res.LoadString(TX_UNDEF); + return res; + } + if ( m_binit == IS_NAN ) + { + res.LoadString(TX_NAN); + return res; + } + + char buffer[300]; + sprintf(buffer, "%.2f", m_val); + res = buffer; + + return res; +} + + +void CBotVarFloat::Mul(CBotVar* left, CBotVar* right) +{ + m_val = left->GivValFloat() * right->GivValFloat(); + m_binit = true; +} + +void CBotVarFloat::Power(CBotVar* left, CBotVar* right) +{ + m_val = (float)pow( left->GivValFloat() , right->GivValFloat() ); + m_binit = true; +} + +int CBotVarFloat::Div(CBotVar* left, CBotVar* right) +{ + float r = right->GivValFloat(); + if ( r != 0 ) + { + m_val = left->GivValFloat() / r; + m_binit = true; + } + return ( r == 0 ? TX_DIVZERO : 0 ); +} + +int CBotVarFloat::Modulo(CBotVar* left, CBotVar* right) +{ + float r = right->GivValFloat(); + if ( r != 0 ) + { + m_val = (float)fmod( left->GivValFloat() , r ); + m_binit = true; + } + return ( r == 0 ? TX_DIVZERO : 0 ); +} + +void CBotVarFloat::Add(CBotVar* left, CBotVar* right) +{ + m_val = left->GivValFloat() + right->GivValFloat(); + m_binit = true; +} + +void CBotVarFloat::Sub(CBotVar* left, CBotVar* right) +{ + m_val = left->GivValFloat() - right->GivValFloat(); + m_binit = true; +} + +void CBotVarFloat::Neg() +{ + m_val = -m_val; +} + +void CBotVarFloat::Inc() +{ + m_val++; +} + +void CBotVarFloat::Dec() +{ + m_val--; +} + + +bool CBotVarFloat::Lo(CBotVar* left, CBotVar* right) +{ + return left->GivValFloat() < right->GivValFloat(); +} + +bool CBotVarFloat::Hi(CBotVar* left, CBotVar* right) +{ + return left->GivValFloat() > right->GivValFloat(); +} + +bool CBotVarFloat::Ls(CBotVar* left, CBotVar* right) +{ + return left->GivValFloat() <= right->GivValFloat(); +} + +bool CBotVarFloat::Hs(CBotVar* left, CBotVar* right) +{ + return left->GivValFloat() >= right->GivValFloat(); +} + +bool CBotVarFloat::Eq(CBotVar* left, CBotVar* right) +{ + return left->GivValFloat() == right->GivValFloat(); +} + +bool CBotVarFloat::Ne(CBotVar* left, CBotVar* right) +{ + return left->GivValFloat() != right->GivValFloat(); +} + + +////////////////////////////////////////////////////////////////////////////////////// + +// copy a variable into another +void CBotVarBoolean::Copy(CBotVar* pSrc, bool bName) +{ + CBotVarBoolean* p = (CBotVarBoolean*)pSrc; + + if (bName) *m_token = *p->m_token; + m_type = p->m_type; + m_val = p->m_val; + m_binit = p->m_binit; +//- m_bStatic = p->m_bStatic; + m_next = NULL; + m_pMyThis = NULL;//p->m_pMyThis; + m_pUserPtr = p->m_pUserPtr; + + // keeps indentificator the same (by default) + if (m_ident == 0 ) m_ident = p->m_ident; +} + + + + +void CBotVarBoolean::SetValInt(int val, const char* s) +{ + m_val = (bool)val; + m_binit = true; +} + +void CBotVarBoolean::SetValFloat(float val) +{ + m_val = (bool)val; + m_binit = true; +} + +int CBotVarBoolean::GivValInt() +{ + return m_val; +} + +float CBotVarBoolean::GivValFloat() +{ + return (float)m_val; +} + +CBotString CBotVarBoolean::GivValString() +{ + CBotString ret; + + CBotString res; + + if ( !m_binit ) + { + res.LoadString(TX_UNDEF); + return res; + } + if ( m_binit == IS_NAN ) + { + res.LoadString(TX_NAN); + return res; + } + + ret.LoadString( m_val > 0 ? ID_TRUE : ID_FALSE ); + return ret; +} + +void CBotVarBoolean::And(CBotVar* left, CBotVar* right) +{ + m_val = left->GivValInt() && right->GivValInt(); + m_binit = true; +} +void CBotVarBoolean::Or(CBotVar* left, CBotVar* right) +{ + m_val = left->GivValInt() || right->GivValInt(); + m_binit = true; +} + +void CBotVarBoolean::XOr(CBotVar* left, CBotVar* right) +{ + m_val = left->GivValInt() ^ right->GivValInt(); + m_binit = true; +} + +void CBotVarBoolean::Not() +{ + m_val = m_val ? false : true ; +} + +bool CBotVarBoolean::Eq(CBotVar* left, CBotVar* right) +{ + return left->GivValInt() == right->GivValInt(); +} + +bool CBotVarBoolean::Ne(CBotVar* left, CBotVar* right) +{ + return left->GivValInt() != right->GivValInt(); +} + +////////////////////////////////////////////////////////////////////////////////////// + +// copy a variable into another +void CBotVarString::Copy(CBotVar* pSrc, bool bName) +{ + CBotVarString* p = (CBotVarString*)pSrc; + + if (bName) *m_token = *p->m_token; + m_type = p->m_type; + m_val = p->m_val; + m_binit = p->m_binit; +//- m_bStatic = p->m_bStatic; + m_next = NULL; + m_pMyThis = NULL;//p->m_pMyThis; + m_pUserPtr = p->m_pUserPtr; + + // keeps indentificator the same (by default) + if (m_ident == 0 ) m_ident = p->m_ident; +} + + +void CBotVarString::SetValString(const char* p) +{ + m_val = p; + m_binit = true; +} + +CBotString CBotVarString::GivValString() +{ + if ( !m_binit ) + { + CBotString res; + res.LoadString(TX_UNDEF); + return res; + } + if ( m_binit == IS_NAN ) + { + CBotString res; + res.LoadString(TX_NAN); + return res; + } + + return m_val; +} + + +void CBotVarString::Add(CBotVar* left, CBotVar* right) +{ + m_val = left->GivValString() + right->GivValString(); + m_binit = true; +} + +bool CBotVarString::Eq(CBotVar* left, CBotVar* right) +{ + return (left->GivValString() == right->GivValString()); +} + +bool CBotVarString::Ne(CBotVar* left, CBotVar* right) +{ + return (left->GivValString() != right->GivValString()); +} + + +bool CBotVarString::Lo(CBotVar* left, CBotVar* right) +{ + return (left->GivValString() == right->GivValString()); +} + +bool CBotVarString::Hi(CBotVar* left, CBotVar* right) +{ + return (left->GivValString() == right->GivValString()); +} + +bool CBotVarString::Ls(CBotVar* left, CBotVar* right) +{ + return (left->GivValString() == right->GivValString()); +} + +bool CBotVarString::Hs(CBotVar* left, CBotVar* right) +{ + return (left->GivValString() == right->GivValString()); +} + + +//////////////////////////////////////////////////////////////// + +// copy a variable into another +void CBotVarClass::Copy(CBotVar* pSrc, bool bName) +{ + pSrc = pSrc->GivPointer(); // if source given by a pointer + + if ( pSrc->GivType() != CBotTypClass ) + ASM_TRAP(); + + CBotVarClass* p = (CBotVarClass*)pSrc; + + if (bName) *m_token = *p->m_token; + + m_type = p->m_type; + m_binit = p->m_binit; +//- m_bStatic = p->m_bStatic; + m_pClass = p->m_pClass; + if ( p->m_pParent ) + { + ASM_TRAP(); "que faire du pParent"; + } + +// m_next = NULL; + m_pUserPtr = p->m_pUserPtr; + m_pMyThis = NULL;//p->m_pMyThis; + m_ItemIdent = p->m_ItemIdent; + + // keeps indentificator the same (by default) + if (m_ident == 0 ) m_ident = p->m_ident; + + delete m_pVar; + m_pVar = NULL; + + CBotVar* pv = p->m_pVar; + while( pv != NULL ) + { + CBotVar* pn = CBotVar::Create(pv); + pn->Copy( pv ); + if ( m_pVar == NULL ) m_pVar = pn; + else m_pVar->AddNext(pn); + + pv = pv->GivNext(); + } +} + +void CBotVarClass::SetItemList(CBotVar* pVar) +{ + delete m_pVar; + m_pVar = pVar; // replaces the existing pointer +} + +void CBotVarClass::SetIdent(long n) +{ + m_ItemIdent = n; +} + +void CBotVarClass::SetClass(CBotClass* pClass)//, int &nIdent) +{ + m_type.m_pClass = pClass; + + if ( m_pClass == pClass ) return; + + m_pClass = pClass; + + // initializes the variables associated with this class + delete m_pVar; + m_pVar = NULL; + + if (pClass == NULL) return; + + CBotVar* pv = pClass->GivVar(); // first on a list + while ( pv != NULL ) + { + // seeks the maximum dimensions of the table + CBotInstr* p = pv->m_LimExpr; // the different formulas + if ( p != NULL ) + { + CBotStack* pile = CBotStack::FirstStack(); // an independent stack + int n = 0; + int max[100]; + + while (p != NULL) + { + while( pile->IsOk() && !p->Execute(pile) ) ; // calculate size without interruptions + CBotVar* v = pile->GivVar(); // result + max[n] = v->GivValInt(); // value + n++; + p = p->GivNext3(); + } + while (n<100) max[n++] = 0; + + pv->m_type.SetArray( max ); // stores the limitations + pile->Delete(); + } + + CBotVar* pn = CBotVar::Create( pv ); // a copy + pn->SetStatic(pv->IsStatic()); + pn->SetPrivate(pv->GivPrivate()); + + if ( pv->m_InitExpr != NULL ) // expression for initialization? + { +#if STACKMEM + CBotStack* pile = CBotStack::FirstStack(); // an independent stack + + while(pile->IsOk() && !pv->m_InitExpr->Execute(pile, pn)); // evaluates the expression without timer + + pile->Delete(); +#else + CBotStack* pile = new CBotStack(NULL); // an independent stack + while(!pv->m_InitExpr->Execute(pile)); // evaluates the expression without timer + pn->SetVal( pile->GivVar() ) ; + delete pile; +#endif + } + +// pn->SetUniqNum(CBotVar::NextUniqNum()); // enumerate elements + pn->SetUniqNum(pv->GivUniqNum()); //++nIdent + pn->m_pMyThis = this; + + if ( m_pVar == NULL) m_pVar = pn; + else m_pVar->AddNext( pn ); + pv = pv->GivNext(); + } +} + +CBotClass* CBotVarClass::GivClass() +{ + return m_pClass; +} + + +void CBotVarClass::Maj(void* pUser, bool bContinu) +{ +/* if (!bContinu && m_pMyThis != NULL) + m_pMyThis->Maj(pUser, true);*/ + + // an update routine exist? + + if ( m_pClass->m_rMaj == NULL ) return; + + // retrieves the user pointer according to the class + // or according to the parameter passed to CBotProgram::Run() + + if ( m_pUserPtr != NULL) pUser = m_pUserPtr; + if ( pUser == OBJECTDELETED || + pUser == OBJECTCREATED ) return; + m_pClass->m_rMaj( this, pUser ); +} + +CBotVar* CBotVarClass::GivItem(const char* name) +{ + CBotVar* p = m_pVar; + + while ( p != NULL ) + { + if ( p->GivName() == name ) return p; + p = p->GivNext(); + } + + if ( m_pParent != NULL ) return m_pParent->GivItem(name); + return NULL; +} + +CBotVar* CBotVarClass::GivItemRef(int nIdent) +{ + CBotVar* p = m_pVar; + + while ( p != NULL ) + { + if ( p->GivUniqNum() == nIdent ) return p; + p = p->GivNext(); + } + + if ( m_pParent != NULL ) return m_pParent->GivItemRef(nIdent); + return NULL; +} + +// for the management of an array +// bExtend can enlarge the table, but not beyond the threshold size of SetArray () + +CBotVar* CBotVarClass::GivItem(int n, bool bExtend) +{ + CBotVar* p = m_pVar; + + if ( n < 0 ) return NULL; + if ( n > MAXARRAYSIZE ) return NULL; + + if ( m_type.GivLimite() >= 0 && n >= m_type.GivLimite() ) return NULL; + + if ( p == NULL && bExtend ) + { + p = CBotVar::Create("", m_type.GivTypElem()); + m_pVar = p; + } + + if ( n == 0 ) return p; + + while ( n-- > 0 ) + { + if ( p->m_next == NULL ) + { + if ( bExtend ) p->m_next = CBotVar::Create("", m_type.GivTypElem()); + if ( p->m_next == NULL ) return NULL; + } + p = p->m_next; + } + + return p; +} + +CBotVar* CBotVarClass::GivItemList() +{ + return m_pVar; +} + + +CBotString CBotVarClass::GivValString() +{ +// if ( m_Indirect != NULL) return m_Indirect->GivValString(); + + CBotString res; + + if ( m_pClass != NULL ) // not used for an array + { + res = m_pClass->GivName() + CBotString("( "); + + CBotVarClass* my = this; + while ( my != NULL ) + { + CBotVar* pv = my->m_pVar; + while ( pv != NULL ) + { + res += pv->GivName() + CBotString("="); + + if ( pv->IsStatic() ) + { + CBotVar* pvv = my->m_pClass->GivItem(pv->GivName()); + res += pvv->GivValString(); + } + else + { + res += pv->GivValString(); + } + pv = pv->GivNext(); + if ( pv != NULL ) res += ", "; + } + my = my->m_pParent; + if ( my != NULL ) + { + res += ") extends "; + res += my->m_pClass->GivName(); + res += " ("; + } + } + } + else + { + res = "( "; + + CBotVar* pv = m_pVar; + while ( pv != NULL ) + { + res += pv->GivValString(); + if ( pv->GivNext() != NULL ) res += ", "; + pv = pv->GivNext(); + } + } + + res += " )"; + return res; +} + +void CBotVarClass::IncrementUse() +{ + m_CptUse++; +} + +void CBotVarClass::DecrementUse() +{ + m_CptUse--; + if ( m_CptUse == 0 ) + { + // if there is one, call the destructor + // but only if a constructor had been called. + if ( m_bConstructor ) + { + m_CptUse++; // does not return to the destructor + + // m_error is static in the stack + // saves the value for return + int err, start, end; + CBotStack* pile = NULL; + err = pile->GivError(start,end); // stack == NULL it does not bother! + + pile = CBotStack::FirstStack(); // clears the error + CBotVar* ppVars[1]; + ppVars[0] = NULL; + + CBotVar* pThis = CBotVar::Create("this", CBotTypNullPointer); + pThis->SetPointer(this); + CBotVar* pResult = NULL; + + CBotString nom = "~" + m_pClass->GivName(); + long ident = 0; + + while ( pile->IsOk() && !m_pClass->ExecuteMethode(ident, nom, pThis, ppVars, pResult, pile, NULL)) ; // waits for the end + + pile->ResetError(err, start,end); + + pile->Delete(); + delete pThis; + m_CptUse--; + } + + delete this; // self-destructs! + } +} + +CBotVarClass* CBotVarClass::GivPointer() +{ + return this; +} + + +// makes an instance according to its unique number + +CBotVarClass* CBotVarClass::Find(long id) +{ + CBotVarClass* p = m_ExClass; + + while ( p != NULL ) + { + if ( p->m_ItemIdent == id ) return p; + p = p->m_ExNext; + } + + return NULL; +} + +bool CBotVarClass::Eq(CBotVar* left, CBotVar* right) +{ + CBotVar* l = left->GivItemList(); + CBotVar* r = right->GivItemList(); + + while ( l != NULL && r != NULL ) + { + if ( l->Ne(l, r) ) return false; + l = l->GivNext(); + r = r->GivNext(); + } + + // should always arrived simultaneously at the end (same classes) + return l == r; +} + +bool CBotVarClass::Ne(CBotVar* left, CBotVar* right) +{ + CBotVar* l = left->GivItemList(); + CBotVar* r = right->GivItemList(); + + while ( l != NULL && r != NULL ) + { + if ( l->Ne(l, r) ) return true; + l = l->GivNext(); + r = r->GivNext(); + } + + // should always arrived simultaneously at the end (same classes) + return l != r; +} + +///////////////////////////////////////////////////////////////////////////// +// management of arrays + +CBotVarArray::CBotVarArray(const CBotToken* name, CBotTypResult& type ) +{ + if ( !type.Eq(CBotTypArrayPointer) && + !type.Eq(CBotTypArrayBody)) ASM_TRAP(); + + m_token = new CBotToken(name); + m_next = NULL; + m_pMyThis = NULL; + m_pUserPtr = NULL; + + m_type = type; + m_type.SetType(CBotTypArrayPointer); + m_binit = false; + + m_pInstance = NULL; // the list of the array elements +} + +CBotVarArray::~CBotVarArray() +{ + if ( m_pInstance != NULL ) m_pInstance->DecrementUse(); // the lowest reference +} + +// copy a variable into another +void CBotVarArray::Copy(CBotVar* pSrc, bool bName) +{ + if ( pSrc->GivType() != CBotTypArrayPointer ) + ASM_TRAP(); + + CBotVarArray* p = (CBotVarArray*)pSrc; + + if ( bName) *m_token = *p->m_token; + m_type = p->m_type; + m_pInstance = p->GivPointer(); + + if ( m_pInstance != NULL ) + m_pInstance->IncrementUse(); // a reference increase + + m_binit = p->m_binit; +//- m_bStatic = p->m_bStatic; + m_pMyThis = NULL;//p->m_pMyThis; + m_pUserPtr = p->m_pUserPtr; + + // keeps indentificator the same (by default) + if (m_ident == 0 ) m_ident = p->m_ident; +} + +void CBotVarArray::SetPointer(CBotVar* pVarClass) +{ + m_binit = true; // init, even on a null pointer + + if ( m_pInstance == pVarClass) return; // Special, not decrement and reincrement + // because the decrement can destroy the object + + if ( pVarClass != NULL ) + { + if ( pVarClass->GivType() == CBotTypArrayPointer ) + pVarClass = pVarClass->GivPointer(); // the real pointer to the object + + if ( !pVarClass->m_type.Eq(CBotTypClass) && + !pVarClass->m_type.Eq(CBotTypArrayBody)) + ASM_TRAP(); + + ((CBotVarClass*)pVarClass)->IncrementUse(); // incement the reference + } + + if ( m_pInstance != NULL ) m_pInstance->DecrementUse(); + m_pInstance = (CBotVarClass*)pVarClass; +} + + +CBotVarClass* CBotVarArray::GivPointer() +{ + if ( m_pInstance == NULL ) return NULL; + return m_pInstance->GivPointer(); +} + +CBotVar* CBotVarArray::GivItem(int n, bool bExtend) +{ + if ( m_pInstance == NULL ) + { + if ( !bExtend ) return NULL; + // creates an instance of the table + + CBotVarClass* instance = new CBotVarClass(NULL, m_type); + SetPointer( instance ); + } + return m_pInstance->GivItem(n, bExtend); +} + +CBotVar* CBotVarArray::GivItemList() +{ + if ( m_pInstance == NULL) return NULL; + return m_pInstance->GivItemList(); +} + +CBotString CBotVarArray::GivValString() +{ + if ( m_pInstance == NULL ) return ( CBotString( "Null pointer" ) ) ; + return m_pInstance->GivValString(); +} + +bool CBotVarArray::Save1State(FILE* pf) +{ + if ( !WriteType(pf, m_type) ) return false; + return SaveVar(pf, m_pInstance); // saves the instance that manages the table +} + + +///////////////////////////////////////////////////////////////////////////// +// gestion des pointeurs à une instance donnée +// TODO management of pointers to a given instance + +CBotVarPointer::CBotVarPointer(const CBotToken* name, CBotTypResult& type ) +{ + if ( !type.Eq(CBotTypPointer) && + !type.Eq(CBotTypNullPointer) && + !type.Eq(CBotTypClass) && // for convenience accepts Class and Intrinsic + !type.Eq(CBotTypIntrinsic) ) ASM_TRAP(); + + m_token = new CBotToken(name); + m_next = NULL; + m_pMyThis = NULL; + m_pUserPtr = NULL; + + m_type = type; + if ( !type.Eq(CBotTypNullPointer) ) + m_type.SetType(CBotTypPointer); // anyway, this is a pointer + m_binit = false; + m_pClass = NULL; + m_pVarClass = NULL; // will be defined by a SetPointer() + + SetClass(type.GivClass() ); +} + +CBotVarPointer::~CBotVarPointer() +{ + if ( m_pVarClass != NULL ) m_pVarClass->DecrementUse(); // decrement reference +} + + +void CBotVarPointer::Maj(void* pUser, bool bContinu) +{ +/* if ( !bContinu && m_pMyThis != NULL ) + m_pMyThis->Maj(pUser, false);*/ + + if ( m_pVarClass != NULL) m_pVarClass->Maj(pUser, false); +} + +CBotVar* CBotVarPointer::GivItem(const char* name) +{ + if ( m_pVarClass == NULL) // no existing instance? + return m_pClass->GivItem(name); // makes the pointer in the class itself + + return m_pVarClass->GivItem(name); +} + +CBotVar* CBotVarPointer::GivItemRef(int nIdent) +{ + if ( m_pVarClass == NULL) // no existing instance? + return m_pClass->GivItemRef(nIdent);// makes the pointer to the class itself + + return m_pVarClass->GivItemRef(nIdent); +} + +CBotVar* CBotVarPointer::GivItemList() +{ + if ( m_pVarClass == NULL) return NULL; + return m_pVarClass->GivItemList(); +} + +CBotString CBotVarPointer::GivValString() +{ + CBotString s = "Pointer to "; + if ( m_pVarClass == NULL ) s = "Null pointer" ; + else s += m_pVarClass->GivValString(); + return s; +} + + +void CBotVarPointer::ConstructorSet() +{ + if ( m_pVarClass != NULL) m_pVarClass->ConstructorSet(); +} + +// initializes the pointer to the instance of a class + +void CBotVarPointer::SetPointer(CBotVar* pVarClass) +{ + m_binit = true; // init, even on a null pointer + + if ( m_pVarClass == pVarClass) return; // special, not decrement and reincrement + // because the decrement can destroy the object + + if ( pVarClass != NULL ) + { + if ( pVarClass->GivType() == CBotTypPointer ) + pVarClass = pVarClass->GivPointer(); // the real pointer to the object + +// if ( pVarClass->GivType() != CBotTypClass ) + if ( !pVarClass->m_type.Eq(CBotTypClass) ) + ASM_TRAP(); + + ((CBotVarClass*)pVarClass)->IncrementUse(); // increment the reference + m_pClass = ((CBotVarClass*)pVarClass)->m_pClass; + m_pUserPtr = pVarClass->m_pUserPtr; // not really necessary + m_type = CBotTypResult(CBotTypPointer, m_pClass); // what kind of a pointer + } + + if ( m_pVarClass != NULL ) m_pVarClass->DecrementUse(); + m_pVarClass = (CBotVarClass*)pVarClass; + +} + +CBotVarClass* CBotVarPointer::GivPointer() +{ + if ( m_pVarClass == NULL ) return NULL; + return m_pVarClass->GivPointer(); +} + +void CBotVarPointer::SetIdent(long n) +{ + if ( m_pVarClass == NULL ) return; + m_pVarClass->SetIdent( n ); +} + +long CBotVarPointer::GivIdent() +{ + if ( m_pVarClass == NULL ) return 0; + return m_pVarClass->m_ItemIdent; +} + + +void CBotVarPointer::SetClass(CBotClass* pClass) +{ +// int nIdent = 0; + m_type.m_pClass = m_pClass = pClass; + if ( m_pVarClass != NULL ) m_pVarClass->SetClass(pClass); //, nIdent); +} + +CBotClass* CBotVarPointer::GivClass() +{ + if ( m_pVarClass != NULL ) return m_pVarClass->GivClass(); + + return m_pClass; +} + + +bool CBotVarPointer::Save1State(FILE* pf) +{ + if ( m_pClass ) + { + if (!WriteString(pf, m_pClass->GivName())) return false; // name of the class + } + else + { + if (!WriteString(pf, "")) return false; + } + + if (!WriteLong(pf, GivIdent())) return false; // the unique reference + + // also saves the proceedings copies + return SaveVar(pf, GivPointer()); +} + +// copy a variable into another +void CBotVarPointer::Copy(CBotVar* pSrc, bool bName) +{ + if ( pSrc->GivType() != CBotTypPointer && + pSrc->GivType() != CBotTypNullPointer) + ASM_TRAP(); + + CBotVarPointer* p = (CBotVarPointer*)pSrc; + + if ( bName) *m_token = *p->m_token; + m_type = p->m_type; +// m_pVarClass = p->m_pVarClass; + m_pVarClass = p->GivPointer(); + + if ( m_pVarClass != NULL ) + m_pVarClass->IncrementUse(); // incerement the reference + + m_pClass = p->m_pClass; + m_binit = p->m_binit; +//- m_bStatic = p->m_bStatic; + m_next = NULL; + m_pMyThis = NULL;//p->m_pMyThis; + m_pUserPtr = p->m_pUserPtr; + + // keeps indentificator the same (by default) + if (m_ident == 0 ) m_ident = p->m_ident; +} + +bool CBotVarPointer::Eq(CBotVar* left, CBotVar* right) +{ + CBotVarClass* l = left->GivPointer(); + CBotVarClass* r = right->GivPointer(); + + if ( l == r ) return true; + if ( l == NULL && r->GivUserPtr() == OBJECTDELETED ) return true; + if ( r == NULL && l->GivUserPtr() == OBJECTDELETED ) return true; + return false; +} + +bool CBotVarPointer::Ne(CBotVar* left, CBotVar* right) +{ + CBotVarClass* l = left->GivPointer(); + CBotVarClass* r = right->GivPointer(); + + if ( l == r ) return false; + if ( l == NULL && r->GivUserPtr() == OBJECTDELETED ) return false; + if ( r == NULL && l->GivUserPtr() == OBJECTDELETED ) return false; + return true; +} + + + +/////////////////////////////////////////////////////// +// management of results types + + +CBotTypResult::CBotTypResult(int type) +{ + m_type = type; + m_pNext = NULL; + m_pClass = NULL; + m_limite = -1; +} + +CBotTypResult::CBotTypResult(int type, const char* name) +{ + m_type = type; + m_pNext = NULL; + m_pClass = NULL; + m_limite = -1; + + if ( type == CBotTypPointer || + type == CBotTypClass || + type == CBotTypIntrinsic ) + { + m_pClass = CBotClass::Find(name); + if ( m_pClass && m_pClass->IsIntrinsic() ) m_type = CBotTypIntrinsic; + } +} + +CBotTypResult::CBotTypResult(int type, CBotClass* pClass) +{ + m_type = type; + m_pNext = NULL; + m_pClass = pClass; + m_limite = -1; + + if ( m_pClass && m_pClass->IsIntrinsic() ) m_type = CBotTypIntrinsic; +} + +CBotTypResult::CBotTypResult(int type, CBotTypResult elem) +{ + m_type = type; + m_pNext = NULL; + m_pClass = NULL; + m_limite = -1; + + if ( type == CBotTypArrayPointer || + type == CBotTypArrayBody ) + m_pNext = new CBotTypResult( elem ); +} + +CBotTypResult::CBotTypResult(const CBotTypResult& typ) +{ + m_type = typ.m_type; + m_pClass = typ.m_pClass; + m_pNext = NULL; + m_limite = typ.m_limite; + + if ( typ.m_pNext ) + m_pNext = new CBotTypResult( *typ.m_pNext ); +} + +CBotTypResult::CBotTypResult() +{ + m_type = 0; + m_limite = -1; + m_pNext = NULL; + m_pClass = NULL; +} + +CBotTypResult::~CBotTypResult() +{ + delete m_pNext; +} + +int CBotTypResult::GivType(int mode) const +{ +#ifdef _DEBUG + if ( m_type == CBotTypPointer || + m_type == CBotTypClass || + m_type == CBotTypIntrinsic ) + + if ( m_pClass == NULL ) ASM_TRAP(); + + + if ( m_type == CBotTypArrayPointer ) + if ( m_pNext == NULL ) ASM_TRAP(); +#endif + if ( mode == 3 && m_type == CBotTypNullPointer ) return CBotTypPointer; + return m_type; +} + +void CBotTypResult::SetType(int n) +{ + m_type = n; +} + +CBotClass* CBotTypResult::GivClass() const +{ + return m_pClass; +} + +CBotTypResult& CBotTypResult::GivTypElem() const +{ + return *m_pNext; +} + +int CBotTypResult::GivLimite() const +{ + return m_limite; +} + +void CBotTypResult::SetLimite(int n) +{ + m_limite = n; +} + +void CBotTypResult::SetArray( int* max ) +{ + m_limite = *max; + if (m_limite < 1) m_limite = -1; + + if ( m_pNext != NULL ) // last dimension? + { + m_pNext->SetArray( max+1 ); + } +} + + + +bool CBotTypResult::Compare(const CBotTypResult& typ) const +{ + if ( m_type != typ.m_type ) return false; + + if ( m_type == CBotTypArrayPointer ) return m_pNext->Compare(*typ.m_pNext); + + if ( m_type == CBotTypPointer || + m_type == CBotTypClass || + m_type == CBotTypIntrinsic ) + { + return m_pClass == typ.m_pClass; + } + + return true; +} + +bool CBotTypResult::Eq(int type) const +{ + return m_type == type; +} + +CBotTypResult& + CBotTypResult::operator=(const CBotTypResult& src) +{ + m_type = src.m_type; + m_limite = src.m_limite; + m_pClass = src.m_pClass; + m_pNext = NULL; + if ( src.m_pNext != NULL ) + { + m_pNext = new CBotTypResult(*src.m_pNext); + } + return *this; +} + + -- cgit v1.2.3-1-g7c22