diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /graphics/asymptote/symbol.h |
Initial commit
Diffstat (limited to 'graphics/asymptote/symbol.h')
-rw-r--r-- | graphics/asymptote/symbol.h | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/graphics/asymptote/symbol.h b/graphics/asymptote/symbol.h new file mode 100644 index 0000000000..bcfed4f630 --- /dev/null +++ b/graphics/asymptote/symbol.h @@ -0,0 +1,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); + mem::compact(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 |