|
FAUST compiler
0.9.9.6b8
|
00001 /************************************************************************ 00002 ************************************************************************ 00003 FAUST compiler 00004 Copyright (C) 2003-2004 GRAME, Centre National de Creation Musicale 00005 --------------------------------------------------------------------- 00006 This program is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation; either version 2 of the License, or 00009 (at your option) any later version. 00010 00011 This program is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License 00017 along with this program; if not, write to the Free Software 00018 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00019 ************************************************************************ 00020 ************************************************************************/ 00021 00022 #include <stdlib.h> 00023 #include <stdio.h> 00024 #include <string.h> 00025 #include "symbol.hh" 00026 #include "compatibility.hh" 00027 #include <iostream> 00028 #include <cstring> 00029 #include <assert.h> 00030 00031 using namespace std; 00032 00037 Symbol* Symbol::gSymbolTable[kHashTableSize]; 00038 00039 00046 Symbol* Symbol::get(const string& str) 00047 { 00048 char buf[1024]; 00049 int i; 00050 int n = str.length(); 00051 00052 if (n>1023) n = 1023; 00053 for (i = 0; i < n; i++) { buf[i] = str[i]; } 00054 buf[i] = 0; 00055 00056 return Symbol::get(buf); 00057 } 00058 00059 00060 00067 Symbol* Symbol::get(const char* str) 00068 { 00069 unsigned int hsh = calcHashKey(str); 00070 int bckt = hsh % kHashTableSize; 00071 Symbol* item = gSymbolTable[bckt]; 00072 00073 while ( item && !item->equiv(hsh,str) ) item = item->fNext; 00074 Symbol* r = item ? item : gSymbolTable[bckt] = new Symbol(str, hsh, gSymbolTable[bckt]); 00075 return r; 00076 } 00077 00078 00085 bool Symbol::isnew(const char* str) 00086 { 00087 unsigned int hsh = calcHashKey(str); 00088 int bckt = hsh % kHashTableSize; 00089 Symbol* item = gSymbolTable[bckt]; 00090 00091 while ( item && !item->equiv(hsh,str) ) item = item->fNext; 00092 return item == 0; 00093 } 00094 00095 00102 Symbol* Symbol::prefix (const char* str) 00103 { 00104 char name[256]; 00105 00106 static map<const char*, unsigned int> gPrefixCounters; 00107 00108 for (int n = 0; n<10000; n++) { 00109 snprintf(name, 256, "%s%d", str, gPrefixCounters[str]++); 00110 if (isnew(name)) return get(name); 00111 } 00112 assert(false); 00113 return get("UNIQUEOVERFLOW"); 00114 } 00115 00116 00127 bool Symbol::equiv (unsigned int hash, const char *str) const 00128 { 00129 return (fHash == hash) && (strcmp(fName,str) == 0); 00130 } 00131 00132 00133 00140 unsigned int Symbol::calcHashKey (const char* str) 00141 { 00142 unsigned int h = 0; 00143 00144 while (*str) h = (h << 1) ^ (h >> 20) ^ (*str++); 00145 return h; 00146 } 00147 00148 00149 00158 Symbol::Symbol(const char* str, unsigned int hsh, Symbol* nxt) 00159 { 00160 int len = strlen(str); 00161 00162 fName = new char [len+1]; 00163 memcpy(fName, str, len+1); 00164 fHash = hsh; 00165 fNext = nxt; 00166 fData = 0; 00167 } 00168 00169 Symbol::~Symbol () 00170 { 00171 delete [] fName; 00172 } 00173 00174 ostream& Symbol::print (ostream& fout) const 00175 { 00176 return fout << fName; 00177 }
1.8.0