stable
This commit is contained in:
@ -2,11 +2,11 @@
|
||||
|
||||
#define INIT_HASH_TABLE_SIZE (32)
|
||||
|
||||
void hashtable_init(hash_table_t* ht) {
|
||||
void init_hashtable(hash_table_t* ht) {
|
||||
vector_init(ht->entries);
|
||||
ht->count = 0;
|
||||
ht->tombstone_count = 0;
|
||||
Assert(ht->key_cmp != NULL && ht->hash_func != NULL);
|
||||
// Assert(ht->key_cmp != NULL && ht->hash_func != NULL);
|
||||
}
|
||||
|
||||
static int next_power_of_two(int n) {
|
||||
@ -127,3 +127,14 @@ void hashtable_destory(hash_table_t* ht) {
|
||||
ht->count = 0;
|
||||
ht->tombstone_count = 0;
|
||||
}
|
||||
|
||||
void hashtable_foreach(hash_table_t* ht, hash_table_iter_func iter_func, void* context) {
|
||||
for (rt_size_t i = 0; i < ht->entries.cap; i++) {
|
||||
hash_entry_t* entry = &vector_at(ht->entries, i);
|
||||
if (entry->state == ENTRY_ACTIVE) {
|
||||
if (!iter_func(entry->key, entry->value, context)) {
|
||||
break; // enable callback function terminal the iter
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
#ifndef __SMCC_HASHTABLE_H__
|
||||
#define __SMCC_HASHTABLE_H__
|
||||
|
||||
#include <lib/core.h>
|
||||
#include <lib/rt/rt_alloc.h>
|
||||
#include "vector.h"
|
||||
|
||||
@ -29,11 +30,14 @@ typedef struct hash_table {
|
||||
} hash_table_t;
|
||||
|
||||
// WARN you need set hash_func and key_cmp before use
|
||||
void hashtable_init(hash_table_t* ht) ;
|
||||
void init_hashtable(hash_table_t* ht) ;
|
||||
|
||||
void* hashtable_set(hash_table_t* ht, const void* key, void* value);
|
||||
void* hashtable_get(hash_table_t* ht, const void* key);
|
||||
void* hashtable_get(hash_table_t* ht, const void* key);
|
||||
void* hashtable_del(hash_table_t* ht, const void* key);
|
||||
void hashtable_destory(hash_table_t* ht);
|
||||
|
||||
typedef int (*hash_table_iter_func)(const void* key, void* value, void* context);
|
||||
void hashtable_foreach(hash_table_t* ht, hash_table_iter_func iter_func, void* context);
|
||||
|
||||
#endif // __SMCC_HASHTABLE_H__
|
||||
|
@ -15,7 +15,7 @@
|
||||
do { \
|
||||
(vec).size = 0, \
|
||||
(vec).cap = 0, \
|
||||
(vec).data = NULL; \
|
||||
(vec).data = 0; \
|
||||
} while(0)
|
||||
|
||||
#define vector_push(vec, value) \
|
||||
|
@ -5,7 +5,7 @@ void init_strpool(strpool_t* pool) {
|
||||
|
||||
pool->ht.hash_func = (u32_t(*)(const void*))rt_strhash;
|
||||
pool->ht.key_cmp = (int(*)(const void*, const void*))rt_strcmp;
|
||||
hashtable_init(&pool->ht);
|
||||
init_hashtable(&pool->ht);
|
||||
}
|
||||
|
||||
const char* strpool_intern(strpool_t* pool, const char* str) {
|
||||
|
@ -0,0 +1,62 @@
|
||||
#include "symtab.h"
|
||||
|
||||
static u32_t hash_func(const void* _key) {
|
||||
const symtab_key_t* key = (symtab_key_t*)_key;
|
||||
return rt_strhash(key->strp_name);
|
||||
}
|
||||
|
||||
static int key_cmp(const void* _key1, const void* _key2) {
|
||||
const symtab_key_t* key1 = (symtab_key_t*)_key1;
|
||||
const symtab_key_t* key2 = (symtab_key_t*)_key2;
|
||||
if (rt_strcmp(key1->strp_name, key2->strp_name) == 0) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void init_symtab(symtab_t* symtab) {
|
||||
symtab->cur_scope = NULL;
|
||||
symtab->gid = 1;
|
||||
init_hashtable(&symtab->global_table);
|
||||
symtab->global_table.hash_func = hash_func;
|
||||
symtab->global_table.key_cmp = key_cmp;
|
||||
init_hashtable(&symtab->local_table);
|
||||
symtab->local_table.hash_func = hash_func;
|
||||
symtab->local_table.key_cmp = key_cmp;
|
||||
}
|
||||
|
||||
void symtab_destroy(symtab_t* symtab) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
void symtab_enter_scope(symtab_t* symtab) {
|
||||
scope_t *scope = (scope_t*)salloc_alloc(sizeof(scope_t));
|
||||
scope->parent = symtab->cur_scope;
|
||||
scope->uid = symtab->gid++;
|
||||
init_hashtable(&scope->table);
|
||||
|
||||
scope->table.hash_func = hash_func;
|
||||
scope->table.key_cmp = key_cmp;
|
||||
symtab->cur_scope = scope;
|
||||
}
|
||||
|
||||
void symtab_leave_scope(symtab_t* symtab) {
|
||||
Assert(symtab->cur_scope != NULL);
|
||||
scope_t *parent = symtab->cur_scope->parent;
|
||||
hashtable_destory(&symtab->cur_scope->table);
|
||||
salloc_free(symtab->cur_scope);
|
||||
symtab->cur_scope = parent;
|
||||
}
|
||||
|
||||
void* symtab_get(symtab_t* symtab, symtab_key_t* key) {
|
||||
for (scope_t* scope = symtab->cur_scope; scope != NULL; scope = scope->parent) {
|
||||
void* val = hashtable_get(&scope->table, key);
|
||||
if (val != NULL) {
|
||||
return val;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
void* symtab_add(symtab_t* symtab, symtab_key_t* key, void* val) {
|
||||
return hashtable_set(&symtab->cur_scope->table, key, val);
|
||||
}
|
||||
|
@ -1,6 +1,39 @@
|
||||
#ifndef __SMCC_SYMTABL_H__
|
||||
#define __SMCC_SYMTABL_H__
|
||||
|
||||
#include <lib/core.h>
|
||||
#include <lib/utils/ds/hashtable.h>
|
||||
#include <lib/utils/strpool/strpool.h>
|
||||
|
||||
// FIXME 架构上可能有更好的方式解决
|
||||
|
||||
typedef struct symtab_key {
|
||||
const char* strp_name;
|
||||
int uid;
|
||||
} symtab_key_t;
|
||||
|
||||
typedef struct scope {
|
||||
int uid;
|
||||
struct scope* parent;
|
||||
hash_table_t table;
|
||||
} scope_t;
|
||||
|
||||
typedef struct symtab {
|
||||
hash_table_t global_table;
|
||||
hash_table_t local_table;
|
||||
scope_t* cur_scope;
|
||||
int gid; // global id for generating unique scope id
|
||||
} symtab_t;
|
||||
|
||||
void init_symtab(symtab_t* symtab);
|
||||
void symtab_destroy(symtab_t* symtab);
|
||||
|
||||
void symtab_enter_scope(symtab_t* symtab);
|
||||
void symtab_leave_scope(symtab_t* symtab);
|
||||
|
||||
void* symtab_get(symtab_t* symtab, symtab_key_t* key);
|
||||
|
||||
// WARNING key and val need you save, especially val
|
||||
void* symtab_add(symtab_t* symtab, symtab_key_t* key, void* val);
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user