/***** * symbol.h * Andy Hammerlindl 2002/06/18 * * Creates symbols from strings so that multiple calls for a symbol of * the same string will return an identical object. *****/ #ifndef SYMBOL_H #define SYMBOL_H #include #include #include "common.h" using std::ostream; namespace sym { void initTable(); struct GCInit { #ifdef _AIX typedef char * GC_PTR; #endif GCInit() { #ifdef USEGC GC_set_free_space_divisor(2); mem::compact(0); GC_INIT(); #ifdef HAVE_PTHREAD GC_allow_register_threads(); #endif #endif // Put the symbol table into a state where symbols can be translated. initTable(); } }; typedef unsigned int uint; /* The symbol class, just a wrapper around the augmented hash value. This * wrapper is so that * cout << s << endl; * prints the symbol name instead of a meaningless integer. * * This is a lightweight class and should have no virtual functions for speed * reasons. */ struct symbol { // Is there any particular reason why this is in symbol? static GCInit initialize; uint hashplus; #if 0 symbol() {} symbol(uint h) : hashplus(h) {} #endif static symbol nullsym; static symbol initsym; static symbol castsym; static symbol ecastsym; bool special() const { return *this == initsym || *this == castsym || *this == ecastsym; } bool notSpecial() const { return !special(); } // Translate a string into a unique symbol, such that two strings are equal // if and only if their resulting symbols are equal. // len should be equal to strlen(s)+1 static symbol rawTrans(const char *s, size_t len); static symbol literalTrans(string s) { return rawTrans(s.c_str(), s.size() + 1); } static symbol opTrans(string s) { return literalTrans("operator "+s); } static symbol trans(string s) { // Figure out whether it's an operator or an identifier by looking at the // first character. char c=s[0]; return isalpha(c) || c == '_' ? literalTrans(s) : opTrans(s); } // Make a symbol that is guaranteed to be unique. It will not match any other // symbol in the namespace. static symbol gensym(string s); size_t hash() const { return (size_t)this->hashplus; } friend bool operator== (symbol s1, symbol s2) { return s1.hashplus == s2.hashplus; } friend bool operator!= (symbol s1, symbol s2) { return s1.hashplus != s2.hashplus; } friend bool operator< (symbol s1, symbol s2) { return s1.hashplus < s2.hashplus; } operator bool () const { return this->hashplus != 0; } operator string () const; #ifdef USEGC explicit operator std::string() const; #endif friend ostream& operator<< (ostream& out, const symbol sym); }; } // end namespace #endif // SYMBOL_H