1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
|
/*****
* 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 <iostream>
#include <cassert>
#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);
GC_dont_expand=0;
GC_INIT();
#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;
friend ostream& operator<< (ostream& out, const symbol sym);
};
} // end namespace
#endif // SYMBOL_H
|