]> www.ginac.de Git - cln.git/blob - src/base/symbol/cl_symbol.cc
Assume types 'long long int' and 'long double' exist.
[cln.git] / src / base / symbol / cl_symbol.cc
1 // class cl_symbol.
2
3 // General includes.
4 #include "base/cl_sysdep.h"
5
6 // Specification.
7 #include "cln/symbol.h"
8
9
10 // Implementation.
11
12 #include "base/hash/cl_hashuniqweak.h"
13
14 namespace cln {
15
16 inline const cl_string hashkey (const cl_symbol& sym)
17 {
18         return (cl_string)sym;
19 }
20
21 // A symbol points to a string, so to convert cl_string -> cl_symbol, we just
22 // take the pointer and put it into a cl_symbol.
23 inline cl_symbol::cl_symbol (struct hashuniq * null, const cl_string& s)
24         : cl_rcpointer (as_cl_private_thing(s)) { unused null; }
25
26 typedef cl_htuniqentry<cl_string,cl_symbol> cl_htentry_from_string_to_symbol;
27
28 typedef cl_heap_weak_hashtable_uniq<cl_string,cl_symbol> cl_heap_hashtable_from_string_to_symbol;
29
30 typedef _cl_hashtable_iterator<cl_htentry_from_string_to_symbol> cl_hashtable_from_string_to_symbol_iterator;
31
32 static void cl_hashtable_from_string_to_symbol_destructor (cl_heap* pointer)
33 {
34         (*(cl_heap_hashtable_from_string_to_symbol*)pointer).~cl_heap_hashtable_from_string_to_symbol();
35 }
36
37
38 struct cl_ht_from_string_to_symbol : public cl_gcpointer {
39         // Constructors.
40         cl_ht_from_string_to_symbol ();
41         cl_ht_from_string_to_symbol (const cl_ht_from_string_to_symbol&);
42         // Assignment operators.
43         cl_ht_from_string_to_symbol& operator= (const cl_ht_from_string_to_symbol&);
44         // Iterator.
45         cl_hashtable_from_string_to_symbol_iterator iterator () const
46         { return ((cl_heap_hashtable_from_string_to_symbol*)pointer)->iterator(); }
47         // Lookup.
48         cl_symbol * get (const cl_string& s) const;
49         // Store.
50         void put (const cl_string& s) const;
51 };
52
53 // These are not inline, because they tend to duplicate a lot of template code.
54
55 cl_ht_from_string_to_symbol::cl_ht_from_string_to_symbol ()
56 {
57         static const cl_class cl_class_hashtable_from_string_to_symbol = {
58                 cl_hashtable_from_string_to_symbol_destructor,
59                 0
60         };
61         var cl_heap_hashtable_from_string_to_symbol* ht = new cl_heap_hashtable_from_string_to_symbol ();
62         ht->refcount = 1;
63         ht->type = &cl_class_hashtable_from_string_to_symbol;
64         pointer = ht;
65 }
66
67 cl_symbol * cl_ht_from_string_to_symbol::get (const cl_string& s) const
68 {
69         return ((cl_heap_hashtable_from_string_to_symbol*)pointer)->get(s);
70 }
71
72 void cl_ht_from_string_to_symbol::put (const cl_string& s) const
73 {
74         ((cl_heap_hashtable_from_string_to_symbol*)pointer)->put(s);
75 }
76
77 // The global symbol table.
78 class global_symbol_table
79 {
80         static int count;
81         static cl_ht_from_string_to_symbol* symbol_table;
82 public:
83         inline cl_symbol* get(const cl_string& s)
84         {
85                 return symbol_table->get(s);
86         }
87
88         inline void put(const cl_string& s)
89         {
90                 symbol_table->put(s);
91         }
92
93         global_symbol_table();
94         ~global_symbol_table();
95 };
96
97 int global_symbol_table::count = 0;
98 cl_ht_from_string_to_symbol* global_symbol_table::symbol_table;
99
100 global_symbol_table::global_symbol_table()
101 {
102         if (count++ == 0)
103                 symbol_table = new cl_ht_from_string_to_symbol();
104 }
105
106 global_symbol_table::~global_symbol_table()
107 {
108         if (--count == 0)
109                 delete symbol_table;
110 }
111
112 // Create or lookup a symbol from its name.
113 cl_symbol::cl_symbol (const cl_string& s)
114 {
115         static global_symbol_table symbol_table;
116         var cl_symbol * sym_in_table;
117         sym_in_table = symbol_table.get(s);
118         if (!sym_in_table) {
119                 symbol_table.put(s);
120                 sym_in_table = symbol_table.get(s);
121                 if (!sym_in_table)
122                         throw runtime_exception();
123         }
124         var cl_heap* p = sym_in_table->heappointer;
125         cl_inc_pointer_refcount(p);
126         pointer = p;
127 }
128
129 }  // namespace cln
130