#include "hamt.h"
#include "_stdint.h" /* for uintptr_t */
-typedef struct HAMTEntry {
+struct HAMTEntry {
STAILQ_ENTRY(HAMTEntry) next; /* next hash table entry */
/*@dependent@*/ const char *str; /* string being hashed */
/*@owned@*/ void *data; /* data pointer being stored */
-} HAMTEntry;
+};
typedef struct HAMTNode {
unsigned long BitMapKey; /* 32 bits, bitmap or hash key */
return 0;
}
+const HAMTEntry *
+HAMT_first(const HAMT *hamt)
+{
+ return STAILQ_FIRST(&hamt->entries);
+}
+
+const HAMTEntry *
+HAMT_next(const HAMTEntry *prev)
+{
+ return STAILQ_NEXT(prev, next);
+}
+
+void *
+HAMTEntry_get_data(const HAMTEntry *entry)
+{
+ return entry->data;
+}
+
/*@-temptrans -kepttrans -mustfree@*/
void *
HAMT_insert(HAMT *hamt, const char *str, void *data, int *replace,
/** Hash array mapped trie data structure (opaque type). */
typedef struct HAMT HAMT;
+/** Hash array mapped trie entry (opaque type). */
+typedef struct HAMTEntry HAMTEntry;
/** Create new, empty, HAMT. error_func() is called when an internal error is
* encountered--it should NOT return to the calling function.
int (*func) (/*@dependent@*/ /*@null@*/ void *node,
/*@null@*/ void *d));
+/** Get the first entry in a HAMT.
+ * \param hamt Hash array mapped trie
+ * \return First entry in HAMT, or NULL if HAMT is empty.
+ */
+const HAMTEntry *HAMT_first(const HAMT *hamt);
+
+/** Get the next entry in a HAMT.
+ * \param prev Previous entry in HAMT
+ * \return Next entry in HAMT, or NULL if no more entries.
+ */
+/*@null@*/ const HAMTEntry *HAMT_next(const HAMTEntry *prev);
+
+/** Get the corresponding data for a HAMT entry.
+ * \param entry HAMT entry (as returned by HAMT_first() and HAMT_next())
+ * \return Corresponding data item.
+ */
+void *HAMTEntry_get_data(const HAMTEntry *entry);
+
#endif
(yasm_symtab *symtab, /*@null@*/ void *d,
yasm_symtab_traverse_callback func);
+/** Symbol table iterator (opaque type). */
+typedef struct yasm_symtab_iter yasm_symtab_iter;
+
+/** Get an iterator pointing to the first symbol in the symbol table.
+ * \param symtab symbol table
+ * \return Iterator for the symbol table.
+ */
+const yasm_symtab_iter *yasm_symtab_first(const yasm_symtab *symtab);
+
+/** Move a symbol table iterator to the next symbol in the symbol table.
+ * \param prev Previous iterator value
+ * \return Next iterator value, or NULL if no more symbols in the table.
+ */
+/*@null@*/ const yasm_symtab_iter *yasm_symtab_next
+ (const yasm_symtab_iter *prev);
+
+/** Get the symbol corresponding to the current symbol table iterator value.
+ * \param cur iterator value
+ * \return Corresponding symbol.
+ */
+yasm_symrec *yasm_symtab_iter_value(const yasm_symtab_iter *cur);
+
/** Finalize symbol table after parsing stage. Checks for symbols that are
* used but never defined or declared #YASM_SYM_EXTERN or #YASM_SYM_COMMON.
* \param symtab symbol table
unsigned long line)
ctypedef int (*yasm_symtab_traverse_callback)(yasm_symrec *sym, void *d)
-
cdef int yasm_symtab_traverse(yasm_symtab *symtab, void *d,
yasm_symtab_traverse_callback func)
+
+ ctypedef struct yasm_symtab_iter
+ cdef yasm_symtab_iter *yasm_symtab_first(yasm_symtab *symtab)
+ cdef yasm_symtab_iter *yasm_symtab_next(yasm_symtab_iter *prev)
+ cdef yasm_symrec *yasm_symtab_iter_value(yasm_symtab_iter *cur)
+
cdef void yasm_symtab_parser_finalize(yasm_symtab *symtab,
int undef_extern, yasm_objfmt *objfmt)
cdef void yasm_symtab_print(yasm_symtab *symtab, FILE *f, int indent_level)
Py_INCREF(symbol) # We're keeping a reference on the C side!
return symbol
-#
-# Helpers for dict-like functions in SymbolTable.
-#
+cdef class Bytecode
+cdef class SymbolTable
-cdef int __symtab_keys_helper(yasm_symrec *sym, void *d):
- (<object>d).append(yasm_symrec_get_name(sym))
- return 0
+cdef class SymbolTableKeyIterator:
+ cdef yasm_symtab_iter *iter
-cdef int __symtab_values_helper(yasm_symrec *sym, void *d):
- (<object>d).append(__make_symbol(sym))
- return 0
+ def __new__(self, symtab):
+ if not isinstance(symtab, SymbolTable):
+ raise TypeError
+ self.iter = yasm_symtab_first((<SymbolTable>symtab).symtab)
-cdef int __symtab_items_helper(yasm_symrec *sym, void *d):
- (<object>d).append((yasm_symrec_get_name(sym), __make_symbol(sym)))
- return 0
+ def __iter__(self):
+ return self
-cdef class Bytecode
+ def __next__(self):
+ if self.iter == NULL:
+ raise StopIteration
+ rv = yasm_symrec_get_name(yasm_symtab_iter_value(self.iter))
+ self.iter = yasm_symtab_next(self.iter)
+ return rv
+
+cdef class SymbolTableValueIterator:
+ cdef yasm_symtab_iter *iter
+
+ def __new__(self, symtab):
+ if not isinstance(symtab, SymbolTable):
+ raise TypeError
+ self.iter = yasm_symtab_first((<SymbolTable>symtab).symtab)
+
+ def __iter__(self):
+ return self
+
+ def __next__(self):
+ if self.iter == NULL:
+ raise StopIteration
+ rv = __make_symbol(yasm_symtab_iter_value(self.iter))
+ self.iter = yasm_symtab_next(self.iter)
+ return rv
+
+cdef class SymbolTableItemIterator:
+ cdef yasm_symtab_iter *iter
+
+ def __new__(self, symtab):
+ if not isinstance(symtab, SymbolTable):
+ raise TypeError
+ self.iter = yasm_symtab_first((<SymbolTable>symtab).symtab)
+
+ def __iter__(self):
+ return self
+
+ def __next__(self):
+ cdef yasm_symrec *sym
+ if self.iter == NULL:
+ raise StopIteration
+ sym = yasm_symtab_iter_value(self.iter)
+ rv = (yasm_symrec_get_name(sym), __make_symbol(sym))
+ self.iter = yasm_symtab_next(self.iter)
+ return rv
cdef class SymbolTable:
cdef yasm_symtab *symtab
return symrec != NULL
def keys(self):
+ cdef yasm_symtab_iter *iter
l = []
- yasm_symtab_traverse(self.symtab, <void *>l, __symtab_keys_helper)
+ iter = yasm_symtab_first(self.symtab)
+ while iter != NULL:
+ l.append(yasm_symrec_get_name(yasm_symtab_iter_value(iter)))
+ iter = yasm_symtab_next(iter)
return l
def values(self):
+ cdef yasm_symtab_iter *iter
l = []
- yasm_symtab_traverse(self.symtab, <void *>l, __symtab_values_helper)
+ iter = yasm_symtab_first(self.symtab)
+ while iter != NULL:
+ l.append(__make_symbol(yasm_symtab_iter_value(iter)))
+ l.append(yasm_symrec_get_name(yasm_symtab_iter_value(iter)))
+ iter = yasm_symtab_next(iter)
return l
def items(self):
+ cdef yasm_symtab_iter *iter
+ cdef yasm_symrec *sym
l = []
- yasm_symtab_traverse(self.symtab, <void *>l, __symtab_items_helper)
+ iter = yasm_symtab_first(self.symtab)
+ while iter != NULL:
+ sym = yasm_symtab_iter_value(iter)
+ l.append((yasm_symrec_get_name(sym), __make_symbol(sym)))
+ l.append(yasm_symrec_get_name(yasm_symtab_iter_value(iter)))
+ iter = yasm_symtab_next(iter)
return l
def has_key(self, key):
return x
return __make_symbol(symrec)
-# def iterkeys(self): pass
-#
-# def itervalues(self): pass
+ def iterkeys(self): return SymbolTableKeyIterator(self)
+ def itervalues(self): return SymbolTableValueIterator(self)
+ def iteritems(self): return SymbolTableItemIterator(self)
# This doesn't follow Python's guideline to make this iterkeys() for
# mappings, but makes more sense in this context, e.g. for sym in symtab.
- #def __iter__(self): return self.itervalues()
-
-# def iteritems(self): pass
+ def __iter__(self): return SymbolTableValueIterator(self)