From 9a9631493129f08e97726608d8034c07312d72f4 Mon Sep 17 00:00:00 2001
From: "Sven M. Hallberg" <pesco@khjk.org>
Date: Sat, 15 Jun 2013 19:06:10 +0200
Subject: [PATCH] refactor hashtable iterations to use H_FOREACH

---
 src/backends/lalr.c | 182 +++++++++++++++++---------------------------
 1 file changed, 69 insertions(+), 113 deletions(-)

diff --git a/src/backends/lalr.c b/src/backends/lalr.c
index fbdb5549..54f6dc8e 100644
--- a/src/backends/lalr.c
+++ b/src/backends/lalr.c
@@ -61,6 +61,27 @@ typedef struct HLREnhGrammar_ {
 } HLREnhGrammar;
 
 
+// XXX move to internal.h or something
+// XXX replace other hashtable iterations with this
+#define H_FOREACH_(HT) {                                                    \
+    const HHashTable *ht__ = HT;                                            \
+    for(size_t i__=0; i__ < ht__->capacity; i__++) {                        \
+      for(HHashTableEntry *hte__ = &ht__->contents[i__];                    \
+          hte__;                                                            \
+          hte__ = hte__->next) {                                            \
+        if(hte__->key == NULL) continue;
+
+#define H_FOREACH_KEY(HT, KEYVAR) H_FOREACH_(HT)                            \
+        const KEYVAR = hte__->key;
+
+#define H_FOREACH(HT, KEYVAR, VALVAR) H_FOREACH_KEY(HT, KEYVAR)             \
+        VALVAR = hte__->value;
+
+#define H_END_FOREACH                                                       \
+      }                                                                     \
+    }                                                                       \
+  }
+
 // compare symbols - terminals by value, others by pointer
 static bool eq_symbol(const void *p, const void *q)
 {
@@ -117,15 +138,9 @@ static HHashValue hash_lalr_itemset(const void *p)
 {
   HHashValue hash = 0;
 
-  const HHashTable *ht = p;
-  for(size_t i=0; i < ht->capacity; i++) {
-    for(HHashTableEntry *hte = &ht->contents[i]; hte; hte = hte->next) {
-      if(hte->key == NULL)
-        continue;
-
-      hash += hash_lalr_item(hte->key);
-    }
-  }
+  H_FOREACH_KEY((const HHashSet *)p, HLRItem *item)
+    hash += hash_lalr_item(item);
+  H_END_FOREACH
 
   return hash;
 }
@@ -179,27 +194,6 @@ void h_lrtable_free(HLRTable *table)
   h_free(table);
 }
 
-// XXX replace other hashtable iterations with this
-// XXX move to internal.h or something
-#define H_FOREACH_(HT) {                                                    \
-    const HHashTable *ht__ = HT;                                            \
-    for(size_t i__=0; i__ < ht__->capacity; i__++) {                        \
-      for(HHashTableEntry *hte__ = &ht__->contents[i__];                    \
-          hte__;                                                            \
-          hte__ = hte__->next) {                                            \
-        if(hte__->key == NULL) continue;
-
-#define H_FOREACH_KEY(HT, KEYVAR) H_FOREACH_(HT)                            \
-        const KEYVAR = hte__->key;
-
-#define H_FOREACH(HT, KEYVAR, VALVAR) H_FOREACH_KEY(HT, KEYVAR)             \
-        VALVAR = hte__->value;
-
-#define H_END_FOREACH                                                       \
-      }                                                                     \
-    }                                                                       \
-  }
-
 
 
 /* Constructing the characteristic automaton (handle recognizer) */
@@ -220,18 +214,11 @@ static HHashSet *closure(HCFGrammar *g, const HHashSet *items)
   HHashSet *ret = h_lrstate_new(arena);
   HSlist *work = h_slist_new(arena);
 
-  // iterate over items - initialize work list with them
-  const HHashTable *ht = items;
-  for(size_t i=0; i < ht->capacity; i++) {
-    for(HHashTableEntry *hte = &ht->contents[i]; hte; hte = hte->next) {
-      if(hte->key == NULL)
-        continue;
-  
-      const HLRItem *item = hte->key;
+  // initialize work list with items
+  H_FOREACH_KEY(items, HLRItem *item)
       h_hashset_put(ret, item);
       h_slist_push(work, (void *)item);
-    }
-  }
+  H_END_FOREACH
 
   while(!h_slist_empty(work)) {
     const HLRItem *item = h_slist_pop(work);
@@ -322,75 +309,52 @@ HLRDFA *h_lr0_dfa(HCFGrammar *g)
     HHashTable *neighbors = h_hashtable_new(arena, eq_symbol, hash_symbol);
 
     // iterate over closure and generate neighboring sets
-    const HHashTable *ht = closure(g, state);
-    for(size_t i=0; i < ht->capacity; i++) {
-      for(HHashTableEntry *hte = &ht->contents[i]; hte; hte = hte->next) {
-        if(hte->key == NULL)
-          continue;
-
-        const HLRItem *item = hte->key;
-        HCFChoice *sym = item->rhs[item->mark]; // symbol after mark
-
-        if(sym != NULL) { // mark was not at the end
-          // find or create prospective neighbor set
-          HLRState *neighbor = h_hashtable_get(neighbors, sym);
-          if(neighbor == NULL) {
-            neighbor = h_lrstate_new(arena);
-            h_hashtable_put(neighbors, sym, neighbor);
-          }
-
-          // ...and add the advanced item to it
-          h_hashset_put(neighbor, advance_mark(arena, item));
+    H_FOREACH_KEY(closure(g, state), HLRItem *item)
+      HCFChoice *sym = item->rhs[item->mark]; // symbol after mark
+
+      if(sym != NULL) { // mark was not at the end
+        // find or create prospective neighbor set
+        HLRState *neighbor = h_hashtable_get(neighbors, sym);
+        if(neighbor == NULL) {
+          neighbor = h_lrstate_new(arena);
+          h_hashtable_put(neighbors, sym, neighbor);
         }
+
+        // ...and add the advanced item to it
+        h_hashset_put(neighbor, advance_mark(arena, item));
       }
-    }
+    H_END_FOREACH
 
     // merge neighbor sets into the set of existing states
-    ht = neighbors;
-    for(size_t i=0; i < ht->capacity; i++) {
-      for(HHashTableEntry *hte = &ht->contents[i]; hte; hte = hte->next) {
-        if(hte->key == NULL)
-          continue;
-
-        const HCFChoice *symbol = hte->key;
-        HLRState *neighbor = hte->value;
-
-        // look up existing state, allocate new if not found
-        size_t neighbor_idx;
-        if(!h_hashset_present(states, neighbor)) {
-          neighbor_idx = states->used;
-          h_hashtable_put(states, neighbor, (void *)(uintptr_t)neighbor_idx);
-          h_slist_push(work, neighbor);
-          h_slist_push(work, (void *)(uintptr_t)neighbor_idx);
-        } else {
-          neighbor_idx = (uintptr_t)h_hashtable_get(states, neighbor);
-        }
-
-        // add transition "state --symbol--> neighbor"
-        HLRTransition *t = h_arena_malloc(arena, sizeof(HLRTransition));
-        t->from = state_idx;
-        t->to = neighbor_idx;
-        t->symbol = symbol;
-        h_slist_push(transitions, t);
+    H_FOREACH(neighbors, HCFChoice *symbol, HLRState *neighbor)
+      // look up existing state, allocate new if not found
+      size_t neighbor_idx;
+      if(!h_hashset_present(states, neighbor)) {
+        neighbor_idx = states->used;
+        h_hashtable_put(states, neighbor, (void *)(uintptr_t)neighbor_idx);
+        h_slist_push(work, neighbor);
+        h_slist_push(work, (void *)(uintptr_t)neighbor_idx);
+      } else {
+        neighbor_idx = (uintptr_t)h_hashtable_get(states, neighbor);
       }
-    }
+
+      // add transition "state --symbol--> neighbor"
+      HLRTransition *t = h_arena_malloc(arena, sizeof(HLRTransition));
+      t->from = state_idx;
+      t->to = neighbor_idx;
+      t->symbol = symbol;
+      h_slist_push(transitions, t);
+    H_END_FOREACH
   } // end while(work)
 
   // fill DFA struct
   HLRDFA *dfa = h_arena_malloc(arena, sizeof(HLRDFA));
   dfa->nstates = states->used;
   dfa->states = h_arena_malloc(arena, dfa->nstates*sizeof(HLRState *));
-  for(size_t i=0; i < states->capacity; i++) {
-    for(HHashTableEntry *hte = &states->contents[i]; hte; hte = hte->next) {
-      if(hte->key == NULL)
-        continue;
-
-      const HLRState *state = hte->key;
-      size_t idx = (uintptr_t)hte->value;
-
-      dfa->states[idx] = state;
-    }
-  }
+  H_FOREACH(states, HLRState *state, void *v)
+    size_t idx = (uintptr_t)v;
+    dfa->states[idx] = state;
+  H_END_FOREACH
   dfa->transitions = transitions;
 
   return dfa;
@@ -911,21 +875,13 @@ void h_pprint_lrstate(FILE *f, const HCFGrammar *g,
                       const HLRState *state, unsigned int indent)
 {
   bool first = true;
-  const HHashTable *ht = state;
-  for(size_t i=0; i < ht->capacity; i++) {
-    for(HHashTableEntry *hte = &ht->contents[i]; hte; hte = hte->next) {
-      if(hte->key == NULL)
-        continue;
-  
-      const HLRItem *item = hte->key;
-
-      if(!first)
-        for(unsigned int i=0; i<indent; i++) fputc(' ', f);
-      first = false;
-      h_pprint_lritem(f, g, item);
-      fputc('\n', f);
-    }
-  }
+  H_FOREACH_KEY(state, HLRItem *item)
+    if(!first)
+      for(unsigned int i=0; i<indent; i++) fputc(' ', f);
+    first = false;
+    h_pprint_lritem(f, g, item);
+    fputc('\n', f);
+  H_END_FOREACH
 }
 
 static void pprint_transition(FILE *f, const HCFGrammar *g, const HLRTransition *t)
-- 
GitLab