summaryrefslogtreecommitdiff
path: root/graphics/asymptote/symbol.h
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /graphics/asymptote/symbol.h
Initial commit
Diffstat (limited to 'graphics/asymptote/symbol.h')
-rw-r--r--graphics/asymptote/symbol.h120
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