Skip to content

Commit

Permalink
Refactor map functions
Browse files Browse the repository at this point in the history
  • Loading branch information
andy-byers committed Aug 13, 2024
1 parent 2a0845c commit b8aa078
Show file tree
Hide file tree
Showing 8 changed files with 36 additions and 82 deletions.
2 changes: 1 addition & 1 deletion src/codegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -1246,7 +1246,7 @@ static void add_builtin_func(struct Generator *G, const char *name)
const int g = pawE_new_global(P, str);
GlobalVar *gv = pawE_get_global(P, g);
const Value key = {.o = CAST_OBJECT(str)};
const Value *pv = pawH_get_(P->builtin, key);
const Value *pv = pawH_get(P->builtin, key);
gv->value = *pv;
}

Expand Down
2 changes: 1 addition & 1 deletion src/compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ paw_Type pawP_type2code(struct Compiler *C, struct HirType *type)
String *pawP_scan_nstring(paw_Env *P, Map *st, const char *s, size_t n)
{
const Value *pv = pawC_pushns(P, s, n);
Value *value = pawH_action(P, st, *pv, MAP_ACTION_CREATE);
Value *value = pawH_create(P, st, *pv);
*value = *pv; // anchor in map
pawC_pop(P);
CHECK_GC(P);
Expand Down
19 changes: 9 additions & 10 deletions src/lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -392,9 +392,9 @@ static int string_clone(paw_Env *P)

static int map_get(paw_Env *P)
{
const Value key = CF_BASE(1 /*TODO*/ + 1);
Map *m = v_map(CF_BASE(0 /*TODO*/ + 1));
const Value *pv = pawH_get(P, m, key);
Map *m = v_map(CF_BASE(1));
const Value key = CF_BASE(2);
const Value *pv = pawH_get(m, key);
if (pv != NULL) {
// replace default value
P->top.p[-1] = *pv;
Expand All @@ -404,14 +404,14 @@ static int map_get(paw_Env *P)

static int map_erase(paw_Env *P)
{
Map *m = v_map(CF_BASE(0 /*TODO*/ + 1));
pawH_remove(P, m, CF_BASE(1 /*TODO*/ + 1));
Map *m = v_map(CF_BASE(1));
pawH_erase(m, CF_BASE(2));
return 0;
}

static int map_clone(paw_Env *P)
{
Map *m = v_map(CF_BASE(0 /*TODO*/ + 1));
Map *m = v_map(CF_BASE(1));
Value *pv = pawC_push0(P);
pawH_clone(P, pv, m);
return 1;
Expand Down Expand Up @@ -468,10 +468,9 @@ static paw_Bool load_cached(paw_Env *P, const char *name)
paw_push_string(P, name);
const Value key = P->top.p[-1];

Value *pvalue = pawH_get(P, P->libs, key);
if (!pvalue) {
return PAW_FALSE;
}
Value *pvalue = pawH_get(P->libs, key);
if (pvalue == NULL) return PAW_FALSE;

// replace library name
pawC_pushv(P, *pvalue);
paw_shift(P, 1);
Expand Down
5 changes: 3 additions & 2 deletions src/map.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ static void rehash_map(Map old_m, Map *m)
const size_t count = m->length;
m->length = 0;
for (size_t i = 0; m->length < count; ++i) {
paw_assert(i < old_m.capacity);
if (mm[i].state == MAP_ITEM_OCCUPIED) {
add_item(m, ks[i], vs[i]);
}
Expand Down Expand Up @@ -141,7 +142,7 @@ paw_Bool pawH_equals(paw_Env *P, Map *lhs, Map *rhs)
}
MapCursor mc = {lhs, 0};
while (mc.index < lhs->capacity) {
Value *v = pawH_action(P, rhs, *h_cursor_key(&mc), MAP_ACTION_NONE);
Value *v = pawH_get(rhs, *h_cursor_key(&mc));
if (v == NULL || !items_equal(*h_cursor_value(&mc), *v)) {
return PAW_FALSE;
}
Expand All @@ -156,7 +157,7 @@ void pawH_extend(paw_Env *P, Map *dst, Map *src)
while (mc.index < src->capacity) {
if (h_get_state(&mc) != MAP_ITEM_OCCUPIED) {
const Value key = *h_cursor_key(&mc);
Value *value = pawH_action(P, dst, key, MAP_ACTION_CREATE);
Value *value = pawH_create(P, dst, key);
*value = *h_cursor_value(&mc);
}
++mc.index;
Expand Down
76 changes: 15 additions & 61 deletions src/map.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,83 +86,37 @@ static inline size_t pawH_length(const Map *m)
return m->length;
}

static inline Value *pawH_get_(Map *m, Value key)
static inline Value *pawH_get(Map *m, Value key)
{
if (m->length == 0) {
return NULL;
}
MapCursor mc = h_cursor_lookup(m, key);
if (h_is_occupied(&mc)) {
return h_cursor_value(&mc);
}
return NULL;
}


typedef enum MapAction {
MAP_ACTION_NONE,
MAP_ACTION_CREATE,
MAP_ACTION_REMOVE,
} MapAction;

static inline Value *pawH_action(paw_Env *P, Map *m, Value key,
MapAction action)
{
if (action == MAP_ACTION_CREATE) {
return pawH_create(P, m, key);
} else if (m->length == 0) {
return NULL;
}
if (m->length == 0) return NULL;
MapCursor mc = h_cursor_lookup(m, key);
if (!h_is_occupied(&mc)) {
return NULL;
}
if (action == MAP_ACTION_REMOVE) {
h_set_state(&mc, MAP_ITEM_ERASED);
--m->length;

// Return the address of the slot to indicate success.
return h_cursor_key(&mc);
}
paw_assert(action == MAP_ACTION_NONE);
if (!h_is_occupied(&mc)) return NULL;
return h_cursor_value(&mc);
}

static inline paw_Bool pawH_contains(paw_Env *P, Map *m, Value key)
static inline void pawH_erase(Map *m, Value key)
{
return pawH_action(P, m, key, MAP_ACTION_NONE) != NULL;
if (m->length == 0) return;
MapCursor mc = h_cursor_lookup(m, key);
if (!h_is_occupied(&mc)) return;
h_set_state(&mc, MAP_ITEM_ERASED);
--m->length;
}

static inline void pawH_insert(paw_Env *P, Map *m, Value key, Value value)
{
Value *slot = pawH_action(P, m, key, MAP_ACTION_CREATE);
if (!slot) {
pawH_key_error(P, key, PAW_TSTRING); // TODO: key type
}
*slot = value;
*pawH_create(P, m, key) = value;
}

static inline void pawH_remove(paw_Env *P, Map *m, Value key)
{
if (!pawH_action(P, m, key, MAP_ACTION_REMOVE)) {
pawH_key_error(P, key, PAW_TSTRING); // TODO: key type
}
}

static inline Value *pawH_get(paw_Env *P, Map *m, Value key)
{
return pawH_action(P, m, key, MAP_ACTION_NONE);
}

static inline void pawH_set(paw_Env *P, Map *m, Value key, Value value)
static inline paw_Bool pawH_contains(paw_Env *P, Map *m, Value key)
{
*pawH_get(P, m, key) = value;
return pawH_get(m, key) != NULL;
}

static inline paw_Bool pawH_iter(const Map *m, paw_Int *itr)
static inline paw_Bool pawH_iter(const Map *m, paw_Int *pi)
{
for (++*itr; *itr < paw_cast_int(m->capacity); ++*itr) {
const MapMeta *mm = pawH_meta(m, *itr);
for (++*pi; *pi < paw_cast_int(m->capacity); ++*pi) {
const MapMeta *mm = pawH_meta(m, *pi);
if (mm->state == MAP_ITEM_OCCUPIED) {
return PAW_TRUE;
}
Expand Down
6 changes: 3 additions & 3 deletions src/resolve.c
Original file line number Diff line number Diff line change
Expand Up @@ -1608,15 +1608,15 @@ static struct HirType *resolve_composite_lit(struct Resolver *R, struct AstCompo
NAME_ERROR(R, hir_item->hdr.line, "duplicate field '%s' in initializer for struct '%s'",
item->name->text, pack.name->text);
}
Value *value = pawH_action(P, map, key, MAP_ACTION_CREATE);
Value *value = pawH_create(P, map, key);
v_set_int(value, i);
pawHir_expr_list_push(R->hir, order, hir_item);
}
for (int i = 0; i < pack.fields->count; ++i) {
struct HirDecl *decl = pack.fields->data[i];
struct HirFieldDecl *field = HirGetFieldDecl(decl);
v_set_object(&key, field->name);
Value *value = pawH_get(P, map, key);
Value *value = pawH_get(map, key);
if (value == NULL) {
NAME_ERROR(R, field->line, "missing initializer for field '%s' in struct '%s'",
field->name->text, pack.name->text);
Expand All @@ -1629,7 +1629,7 @@ static struct HirType *resolve_composite_lit(struct Resolver *R, struct AstCompo
struct HirType *item_t = expr_type(R, item);
item->sitem.index = i;
unify(R, item_t, field_t);
pawH_remove(P, map, key);
pawH_erase(map, key);
}
paw_Int iter = PAW_ITER_INIT;
while (pawH_iter(map, &iter)) {
Expand Down
2 changes: 1 addition & 1 deletion src/rt.c
Original file line number Diff line number Diff line change
Expand Up @@ -803,7 +803,7 @@ static void getitem_vector(paw_Env *P, Vector *vector, paw_Int index)

static int getitem_map(paw_Env *P, Map *map, Value key)
{
const Value *pv = pawH_get(P, map, key);
const Value *pv = pawH_get(map, key);
if (pv) {
*vm_top(2) = *pv;
vm_pop(1);
Expand Down
6 changes: 3 additions & 3 deletions test/test_impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,15 @@ static void map_free(paw_Env *P, Map *map)
static paw_Int map_get(paw_Env *P, Map *map, paw_Int k)
{
const Value key = {.i = k};
const Value *pvalue = pawH_get(P, map, key);
const Value *pvalue = pawH_get(map, key);
paw_assert(pvalue != NULL);
return pvalue->i;
}

static const paw_Int *map_try(paw_Env *P, Map *map, paw_Int k)
{
const Value key = {.i = k};
const Value *pvalue = pawH_get(P, map, key);
const Value *pvalue = pawH_get(map, key);
return pvalue ? &pvalue->i : NULL;
}

Expand All @@ -95,7 +95,7 @@ static void map_put(paw_Env *P, Map *map, paw_Int k, paw_Int v)
static void map_del(paw_Env *P, Map *map, paw_Int k)
{
const Value key = {.i = k};
pawH_remove(P, map, key);
pawH_erase(map, key);
}

static void dump_map(Map *m)
Expand Down

0 comments on commit b8aa078

Please sign in to comment.