2022-04-04 14:15:02 -04:00
|
|
|
#include "hash.h"
|
|
|
|
#include "env.h"
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
static unsigned long hash(const char *str)
|
|
|
|
{
|
|
|
|
unsigned long hash = 5381;
|
|
|
|
int c;
|
|
|
|
|
|
|
|
while ((c = *str++)) {
|
|
|
|
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
|
|
|
|
}
|
|
|
|
|
|
|
|
return hash;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct ObjectTable buildTable(size_t capacity)
|
|
|
|
{
|
|
|
|
struct ObjectTable table = {
|
|
|
|
.count = 0,
|
|
|
|
.capacity = capacity,
|
2022-04-05 15:27:41 -04:00
|
|
|
.elements = capacity ? malloc(sizeof(struct EnvElement) * capacity) : NULL,
|
2022-04-04 14:15:02 -04:00
|
|
|
};
|
|
|
|
for (int i = 0; i < table.capacity; i++) {
|
|
|
|
table.elements[i].symbol = NULL;
|
|
|
|
}
|
|
|
|
return table;
|
|
|
|
}
|
|
|
|
|
|
|
|
///
|
|
|
|
/// \param table
|
|
|
|
/// \param name Should be a new allocation
|
|
|
|
/// \param object Should already be cloned
|
|
|
|
void addToTable(struct ObjectTable* table, char* name, Object object)
|
|
|
|
{
|
2022-04-05 15:27:41 -04:00
|
|
|
if (table->capacity < (table->count + 1) * 2) {
|
|
|
|
struct ObjectTable newTable = buildTable(table->capacity ? table->capacity * 2 : 4);
|
2022-04-04 14:15:02 -04:00
|
|
|
for (int i = 0; i < table->capacity; i++) {
|
|
|
|
if (table->elements[i].symbol) {
|
|
|
|
addToTable(&newTable, table->elements[i].symbol, table->elements[i].object);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
free(table->elements);
|
|
|
|
*table = newTable;
|
|
|
|
}
|
2022-04-05 15:27:41 -04:00
|
|
|
|
|
|
|
size_t h = hash(name) % table->capacity;
|
|
|
|
while(table->elements[h].symbol) {
|
|
|
|
h = (h + 1) % table->capacity;
|
|
|
|
}
|
|
|
|
table->elements[h].symbol = name;
|
|
|
|
table->elements[h].object = object;
|
|
|
|
table->count += 1;
|
2022-04-04 14:15:02 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
Object* getFromTable(struct ObjectTable* table, const char* name)
|
|
|
|
{
|
2022-04-05 15:27:41 -04:00
|
|
|
if (table->capacity == 0) {
|
|
|
|
return NULL;
|
|
|
|
}
|
2022-04-04 14:15:02 -04:00
|
|
|
size_t h = hash(name) % table->capacity;
|
|
|
|
while(table->elements[h].symbol) {
|
|
|
|
if (strcmp(name, table->elements[h].symbol) == 0) {
|
|
|
|
return &table->elements[h].object;
|
|
|
|
}
|
|
|
|
h = (h + 1) % table->capacity;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void deleteTable(struct ObjectTable* table)
|
|
|
|
{
|
|
|
|
for (int i = 0; i < table->capacity; i++) {
|
|
|
|
if (table->elements[i].symbol) {
|
|
|
|
free(table->elements[i].symbol);
|
|
|
|
cleanObject(&table->elements[i].object);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
free(table->elements);
|
|
|
|
}
|