]> granicus.if.org Git - yasm/commitdiff
* symrec.pxi: Revamp to more correctly generate Symbol objects, support
authorPeter Johnson <peter@tortall.net>
Sun, 16 Apr 2006 08:41:41 +0000 (08:41 -0000)
committerPeter Johnson <peter@tortall.net>
Sun, 16 Apr 2006 08:41:41 +0000 (08:41 -0000)
most dictionary functions (but not yet iterator protocol).
* yasm.pyx: Add Py_INCREF, Py_DECREF, malloc, free externals.
* coretype.pxi: Rename c_print to print_, add some missing yasm_expr_op
enum values.

svn path=/trunk/yasm/; revision=1491

tools/python-yasm/coretype.pxi
tools/python-yasm/symrec.pxi
tools/python-yasm/yasm.pyx

index e79324db52bb738ff02e7947c5543ddc16b1698a..0c5c50204a197635a87cd3b8ca6eb7d7f54f890e 100644 (file)
@@ -39,7 +39,7 @@ cdef extern from "libyasm/coretype.h":
 
     cdef struct yasm_assoc_data_callback:
         void (*destroy) (void *data)
-        void (*c_print "print") (void *data, FILE *f, int indent_level)
+        void (*print_ "print") (void *data, FILE *f, int indent_level)
 
     cdef struct yasm_bytecode
     cdef struct yasm_object
@@ -79,12 +79,16 @@ cdef extern from "libyasm/coretype.h":
         YASM_EXPR_OR
         YASM_EXPR_AND
         YASM_EXPR_XOR
+        YASM_EXPR_XNOR
         YASM_EXPR_NOR
         YASM_EXPR_SHL
         YASM_EXPR_SHR
         YASM_EXPR_LOR
         YASM_EXPR_LAND
         YASM_EXPR_LNOT
+        YASM_EXPR_LXOR
+        YASM_EXPR_LXNOR
+        YASM_EXPR_LNOR
         YASM_EXPR_LT
         YASM_EXPR_GT
         YASM_EXPR_EQ
index 4ba76f65852e16e256d884a6cb0e1dd873c9b718..94166865886d000a4363746313ac66e207fb24ea 100644 (file)
@@ -95,13 +95,61 @@ cdef class Symbol:
     def set_data(self, data): pass # TODO
         #yasm_symrec_set_data(self.sym, PyYasmAssocData, data)
 
+#
+# Use associated data mechanism to keep Symbol reference paired with symrec.
+#
+
+cdef class __assoc_data_callback:
+    cdef yasm_assoc_data_callback *cb
+    def __new__(self, destroy, print_):
+        self.cb = <yasm_assoc_data_callback *>malloc(sizeof(yasm_assoc_data_callback))
+        self.cb.destroy = <void (*) (void *)>PyCObject_AsVoidPtr(destroy)
+        self.cb.print_ = <void (*) (void *, FILE *, int)>PyCObject_AsVoidPtr(print_)
+    def __dealloc__(self):
+        free(self.cb)
+
+cdef void __python_symrec_cb_destroy(void *data):
+    Py_DECREF(<object>data)
+cdef void __python_symrec_cb_print(void *data, FILE *f, int indent_level):
+    pass
+__python_symrec_cb = __assoc_data_callback(
+        PyCObject_FromVoidPtr(&__python_symrec_cb_destroy, NULL),
+        PyCObject_FromVoidPtr(&__python_symrec_cb_print, NULL))
+
 cdef object __make_symbol(yasm_symrec *symrec):
-    return Symbol(PyCObject_FromVoidPtr(symrec, NULL))
+    cdef void *data
+    data = yasm_symrec_get_data(symrec,
+                                (<__assoc_data_callback>__python_symrec_cb).cb)
+    if data != NULL:
+        return <object>data
+    symbol = Symbol(PyCObject_FromVoidPtr(symrec, NULL))
+    yasm_symrec_add_data(symrec,
+                         (<__assoc_data_callback>__python_symrec_cb).cb,
+                         <void *>symbol)
+    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 yasm_symtab *symtab
+
     def __new__(self):
         self.symtab = yasm_symtab_create()
 
@@ -112,25 +160,69 @@ cdef class SymbolTable:
         return __make_symbol(yasm_symtab_use(self.symtab, name, line))
 
     def define_equ(self, name, expr, line):
+        if not isinstance(expr, Expression):
+            raise TypeError
         return __make_symbol(yasm_symtab_define_equ(self.symtab, name,
                 (<Expression>expr).expr, line))
 
     def define_label(self, name, precbc, in_table, line):
+        if not isinstance(precbc, Bytecode):
+            raise TypeError
         return __make_symbol(yasm_symtab_define_label(self.symtab, name,
                 (<Bytecode>precbc).bc, in_table, line))
 
     def define_special(self, name, vis):
-        return __make_symbol(yasm_symtab_define_special(self.symtab, name, vis))
+        return __make_symbol(yasm_symtab_define_special(self.symtab, name,
+                                                        vis))
 
     def declare(self, name, vis, line):
         return __make_symbol(yasm_symtab_declare(self.symtab, name, vis, line))
 
-    #def traverse(self, func, *args, **kw):
-    #    return yasm_symtab_traverse(self.symtab, (args, kw), func)
-
-    #def parser_finalize(self, undef_extern, objfmt):
-    #    yasm_symtab_parser_finalize(self.symtab, undef_extern,
-    #            (<ObjectFormat>objfmt).objfmt)
     #
+    # Methods to make SymbolTable behave like a dictionary of Symbols.
+    #
+
+    def __getitem__(self, key):
+        cdef yasm_symrec *symrec
+        symrec = yasm_symtab_get(self.symtab, key)
+        if symrec == NULL:
+            raise KeyError
+        return __make_symbol(symrec)
+
+    def keys(self):
+        l = []
+        yasm_symtab_traverse(self.symtab, <void *>l, __symtab_keys_helper)
+        return l
+
+    def values(self):
+        l = []
+        yasm_symtab_traverse(self.symtab, <void *>l, __symtab_values_helper)
+        return l
+
+    def items(self):
+        l = []
+        yasm_symtab_traverse(self.symtab, <void *>l, __symtab_items_helper)
+        return l
+
+    def has_key(self, key):
+        cdef yasm_symrec *symrec
+        symrec = yasm_symtab_get(self.symtab, key)
+        return symrec != NULL
+
+    def get(self, key, x):
+        cdef yasm_symrec *symrec
+        symrec = yasm_symtab_get(self.symtab, key)
+        if symrec == NULL:
+            return x
+        return __make_symbol(symrec)
+
+#    def iterkeys(self): pass
+#
+#    def itervalues(self): pass
+
+    # 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
 
index e6d91e3d1709e38fc6d2056e6a925e03099e0b7e..392befa0f9e4f8309a5a0d02b3edeb96f5e8cd71 100644 (file)
@@ -53,6 +53,13 @@ cdef extern from "Python.h":
     cdef int _PyLong_AsByteArray(object v, unsigned char *bytes, unsigned int n,
                                  int little_endian, int is_signed) except -1
 
+    cdef void Py_INCREF(object o)
+    cdef void Py_DECREF(object o)
+
+cdef extern from "stdlib.h":
+    cdef void *malloc(int n)
+    cdef void free(void *p)
+
 cdef extern from "libyasm/compat-queue.h":
     pass