You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
130 lines
3.3 KiB
130 lines
3.3 KiB
// class cl_symbol.
|
|
|
|
// General includes.
|
|
#include "base/cl_sysdep.h"
|
|
|
|
// Specification.
|
|
#include "cln/symbol.h"
|
|
|
|
|
|
// Implementation.
|
|
|
|
#include "base/hash/cl_hashuniqweak.h"
|
|
|
|
namespace cln {
|
|
|
|
inline const cl_string hashkey (const cl_symbol& sym)
|
|
{
|
|
return (cl_string)sym;
|
|
}
|
|
|
|
// A symbol points to a string, so to convert cl_string -> cl_symbol, we just
|
|
// take the pointer and put it into a cl_symbol.
|
|
inline cl_symbol::cl_symbol (struct hashuniq * null, const cl_string& s)
|
|
: cl_rcpointer (as_cl_private_thing(s)) { unused null; }
|
|
|
|
typedef cl_htuniqentry<cl_string,cl_symbol> cl_htentry_from_string_to_symbol;
|
|
|
|
typedef cl_heap_weak_hashtable_uniq<cl_string,cl_symbol> cl_heap_hashtable_from_string_to_symbol;
|
|
|
|
typedef _cl_hashtable_iterator<cl_htentry_from_string_to_symbol> cl_hashtable_from_string_to_symbol_iterator;
|
|
|
|
static void cl_hashtable_from_string_to_symbol_destructor (cl_heap* pointer)
|
|
{
|
|
(*(cl_heap_hashtable_from_string_to_symbol*)pointer).~cl_heap_hashtable_from_string_to_symbol();
|
|
}
|
|
|
|
|
|
struct cl_ht_from_string_to_symbol : public cl_gcpointer {
|
|
// Constructors.
|
|
cl_ht_from_string_to_symbol ();
|
|
cl_ht_from_string_to_symbol (const cl_ht_from_string_to_symbol&);
|
|
// Assignment operators.
|
|
cl_ht_from_string_to_symbol& operator= (const cl_ht_from_string_to_symbol&);
|
|
// Iterator.
|
|
cl_hashtable_from_string_to_symbol_iterator iterator () const
|
|
{ return ((cl_heap_hashtable_from_string_to_symbol*)pointer)->iterator(); }
|
|
// Lookup.
|
|
cl_symbol * get (const cl_string& s) const;
|
|
// Store.
|
|
void put (const cl_string& s) const;
|
|
};
|
|
|
|
// These are not inline, because they tend to duplicate a lot of template code.
|
|
|
|
cl_ht_from_string_to_symbol::cl_ht_from_string_to_symbol ()
|
|
{
|
|
static const cl_class cl_class_hashtable_from_string_to_symbol = {
|
|
cl_hashtable_from_string_to_symbol_destructor,
|
|
0
|
|
};
|
|
var cl_heap_hashtable_from_string_to_symbol* ht = new cl_heap_hashtable_from_string_to_symbol ();
|
|
ht->refcount = 1;
|
|
ht->type = &cl_class_hashtable_from_string_to_symbol;
|
|
pointer = ht;
|
|
}
|
|
|
|
cl_symbol * cl_ht_from_string_to_symbol::get (const cl_string& s) const
|
|
{
|
|
return ((cl_heap_hashtable_from_string_to_symbol*)pointer)->get(s);
|
|
}
|
|
|
|
void cl_ht_from_string_to_symbol::put (const cl_string& s) const
|
|
{
|
|
((cl_heap_hashtable_from_string_to_symbol*)pointer)->put(s);
|
|
}
|
|
|
|
// The global symbol table.
|
|
class global_symbol_table
|
|
{
|
|
static int count;
|
|
static cl_ht_from_string_to_symbol* symbol_table;
|
|
public:
|
|
inline cl_symbol* get(const cl_string& s)
|
|
{
|
|
return symbol_table->get(s);
|
|
}
|
|
|
|
inline void put(const cl_string& s)
|
|
{
|
|
symbol_table->put(s);
|
|
}
|
|
|
|
global_symbol_table();
|
|
~global_symbol_table();
|
|
};
|
|
|
|
int global_symbol_table::count = 0;
|
|
cl_ht_from_string_to_symbol* global_symbol_table::symbol_table;
|
|
|
|
global_symbol_table::global_symbol_table()
|
|
{
|
|
if (count++ == 0)
|
|
symbol_table = new cl_ht_from_string_to_symbol();
|
|
}
|
|
|
|
global_symbol_table::~global_symbol_table()
|
|
{
|
|
if (--count == 0)
|
|
delete symbol_table;
|
|
}
|
|
|
|
// Create or lookup a symbol from its name.
|
|
cl_symbol::cl_symbol (const cl_string& s)
|
|
{
|
|
static global_symbol_table symbol_table;
|
|
var cl_symbol * sym_in_table;
|
|
sym_in_table = symbol_table.get(s);
|
|
if (!sym_in_table) {
|
|
symbol_table.put(s);
|
|
sym_in_table = symbol_table.get(s);
|
|
if (!sym_in_table)
|
|
throw runtime_exception();
|
|
}
|
|
var cl_heap* p = sym_in_table->heappointer;
|
|
cl_inc_pointer_refcount(p);
|
|
pointer = p;
|
|
}
|
|
|
|
} // namespace cln
|
|
|