X-Git-Url: https://scm.cri.ensmp.fr/git/Faustine.git/blobdiff_plain/c7f552fd8888da2f0d8cfb228fe0f28d3df3a12c..b4b6f2ea75b9f0f3ca918f5b84016610bf7a4d4f:/interpretor/preprocessor/faust-0.9.47mr3/compiler/tlib/symbol.cpp diff --git a/interpretor/preprocessor/faust-0.9.47mr3/compiler/tlib/symbol.cpp b/interpretor/preprocessor/faust-0.9.47mr3/compiler/tlib/symbol.cpp new file mode 100644 index 0000000..1e2390c --- /dev/null +++ b/interpretor/preprocessor/faust-0.9.47mr3/compiler/tlib/symbol.cpp @@ -0,0 +1,177 @@ +/************************************************************************ + ************************************************************************ + FAUST compiler + Copyright (C) 2003-2004 GRAME, Centre National de Creation Musicale + --------------------------------------------------------------------- + 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 2 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, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + ************************************************************************ + ************************************************************************/ + +#include +#include +#include +#include "symbol.hh" +#include "compatibility.hh" +#include +#include +#include + +using namespace std; + +/** + * Hash table used to store the symbols + */ + +Symbol* Symbol::gSymbolTable[kHashTableSize]; + + +/** + * Search the hash table for the symbol of name \p str or returns a new one. + * \param str the name of the symbol + * \return a symbol of name str + */ + +Symbol* Symbol::get(const string& str) +{ + char buf[1024]; + int i; + int n = str.length(); + + if (n>1023) n = 1023; + for (i = 0; i < n; i++) { buf[i] = str[i]; } + buf[i] = 0; + + return Symbol::get(buf); +} + + + +/** + * Search the hash table for the symbol of name \p str or returns a new one. + * \param str the name of the symbol + * \return a symbol of name str + */ + +Symbol* Symbol::get(const char* str) +{ + unsigned int hsh = calcHashKey(str); + int bckt = hsh % kHashTableSize; + Symbol* item = gSymbolTable[bckt]; + + while ( item && !item->equiv(hsh,str) ) item = item->fNext; + Symbol* r = item ? item : gSymbolTable[bckt] = new Symbol(str, hsh, gSymbolTable[bckt]); + return r; +} + + +/** + * Static method that searches the symbol table for a string. + * \param str string to search + * \return true if the string is NOT in the table (it is a new string) + */ + +bool Symbol::isnew(const char* str) +{ + unsigned int hsh = calcHashKey(str); + int bckt = hsh % kHashTableSize; + Symbol* item = gSymbolTable[bckt]; + + while ( item && !item->equiv(hsh,str) ) item = item->fNext; + return item == 0; +} + + +/** + * Creates a new symbol with a name obtained by concatenating the \p str prefix with a number in order to make it unique + * \param str the prefix of the name + * \return a symbol of name \p prefix++n + */ + +Symbol* Symbol::prefix (const char* str) +{ + char name[256]; + + static map gPrefixCounters; + + for (int n = 0; n<10000; n++) { + snprintf(name, 256, "%s%d", str, gPrefixCounters[str]++); + if (isnew(name)) return get(name); + } + assert(false); + return get("UNIQUEOVERFLOW"); +} + + +/** + * Check if the name of the symbol is equal to string \p str + * This method is used by isnew() and make() when searching the hashtable + * for an existing symbol. + * + * \param hash the hash key of the string (used to speedup the comparison) + * \param str the string to compare + * \return \p true if the name of the symbol and \p str are the same + */ + +bool Symbol::equiv (unsigned int hash, const char *str) const +{ + return (fHash == hash) && (strcmp(fName,str) == 0); +} + + + +/** + * Compute the 32-bits hash key of string \p str + * \param str the string + * \return a 32-bits hash key + */ + +unsigned int Symbol::calcHashKey (const char* str) +{ + unsigned int h = 0; + + while (*str) h = (h << 1) ^ (h >> 20) ^ (*str++); + return h; +} + + + +/** + * Constructs a symbol ready to be placed in the hash table. + * It makes a private copy of its name. + * \param str the name of the symbol + * \param hsh the hash key of the symbol + * \param nxt a pointer to the next symbol in the hash table entry + */ + +Symbol::Symbol(const char* str, unsigned int hsh, Symbol* nxt) +{ + int len = strlen(str); + + fName = new char [len+1]; + memcpy(fName, str, len+1); + fHash = hsh; + fNext = nxt; + fData = 0; +} + +Symbol::~Symbol () +{ + delete [] fName; +} + +ostream& Symbol::print (ostream& fout) const ///< print a symbol on a stream +{ + return fout << fName; +}