mirror of
https://github.com/yasm/yasm
synced 2026-08-26 22:26:05 -04:00
* symrec.pxi: Implement iterators.
* symrec.h (yasm_symtab_first, yasm_symtab_next, yasm_symtab_iter_value): Supporting functions. * symrec.c (yasm_symtab_first, yasm_symtab_next, yasm_symtab_iter_value): Implement by passing through to... * hamt.h (HAMT_first, HAMT_next, HAMTEntry_get_data): New. * hamt.c (HAMT_first, HAMT_next, HAMTEntry_get_data): Implement. svn path=/trunk/yasm/; revision=1495
This commit is contained in:
parent
3c5cabcd47
commit
ba76728ded
5 changed files with 166 additions and 28 deletions
|
|
@ -37,11 +37,11 @@
|
|||
#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 */
|
||||
|
|
@ -160,6 +160,24 @@ HAMT_traverse(HAMT *hamt, void *d,
|
|||
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,
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@
|
|||
|
||||
/** 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.
|
||||
|
|
@ -91,4 +93,22 @@ int HAMT_traverse(HAMT *hamt, /*@null@*/ void *d,
|
|||
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
|
||||
|
|
|
|||
|
|
@ -175,6 +175,24 @@ yasm_symtab_traverse(yasm_symtab *symtab, void *d,
|
|||
return HAMT_traverse(symtab->sym_table, d, (int (*) (void *, void *))func);
|
||||
}
|
||||
|
||||
const yasm_symtab_iter *
|
||||
yasm_symtab_first(const yasm_symtab *symtab)
|
||||
{
|
||||
return (const yasm_symtab_iter *)HAMT_first(symtab->sym_table);
|
||||
}
|
||||
|
||||
/*@null@*/ const yasm_symtab_iter *
|
||||
yasm_symtab_next(const yasm_symtab_iter *prev)
|
||||
{
|
||||
return (const yasm_symtab_iter *)HAMT_next((const HAMTEntry *)prev);
|
||||
}
|
||||
|
||||
yasm_symrec *
|
||||
yasm_symtab_iter_value(const yasm_symtab_iter *cur)
|
||||
{
|
||||
return (yasm_symrec *)HAMTEntry_get_data((const HAMTEntry *)cur);
|
||||
}
|
||||
|
||||
yasm_symrec *
|
||||
yasm_symtab_use(yasm_symtab *symtab, const char *name, unsigned long line)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -154,6 +154,28 @@ int /*@alt void@*/ yasm_symtab_traverse
|
|||
(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
|
||||
|
|
|
|||
|
|
@ -43,9 +43,14 @@ cdef extern from "libyasm/symrec.h":
|
|||
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)
|
||||
|
|
@ -129,23 +134,64 @@ cdef object __make_symbol(yasm_symrec *symrec):
|
|||
Py_INCREF(symbol) # We're keeping a reference on the C side!
|
||||
return symbol
|
||||
|
||||
#
|
||||
# Helpers for dict-like functions in SymbolTable.
|
||||
#
|
||||
|
||||
cdef int __symtab_keys_helper(yasm_symrec *sym, void *d):
|
||||
(<object>d).append(yasm_symrec_get_name(sym))
|
||||
return 0
|
||||
|
||||
cdef int __symtab_values_helper(yasm_symrec *sym, void *d):
|
||||
(<object>d).append(__make_symbol(sym))
|
||||
return 0
|
||||
|
||||
cdef int __symtab_items_helper(yasm_symrec *sym, void *d):
|
||||
(<object>d).append((yasm_symrec_get_name(sym), __make_symbol(sym)))
|
||||
return 0
|
||||
|
||||
cdef class Bytecode
|
||||
cdef class SymbolTable
|
||||
|
||||
cdef class SymbolTableKeyIterator:
|
||||
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 = 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
|
||||
|
|
@ -195,18 +241,34 @@ cdef class SymbolTable:
|
|||
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):
|
||||
|
|
@ -221,13 +283,11 @@ cdef class SymbolTable:
|
|||
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)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue