# Python bindings for Yasm: Pyrex input file for expr.h # # Copyright (C) 2006 Michael Urman, Peter Johnson # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS'' # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. cdef extern from "libyasm/expr.h": cdef struct yasm_expr__item cdef yasm_expr *yasm_expr_create(yasm_expr_op op, yasm_expr__item *a, yasm_expr__item *b, unsigned long line) cdef yasm_expr__item *yasm_expr_sym(yasm_symrec *sym) cdef yasm_expr__item *yasm_expr_expr(yasm_expr *e) cdef yasm_expr__item *yasm_expr_int(yasm_intnum *intn) cdef yasm_expr__item *yasm_expr_float(yasm_floatnum *flt) cdef yasm_expr__item *yasm_expr_reg(unsigned long reg) cdef yasm_expr *yasm_expr_create_tree(yasm_expr *l, yasm_expr_op op, yasm_expr *r, unsigned long line) cdef yasm_expr *yasm_expr_create_branch(yasm_expr_op op, yasm_expr *r, unsigned long line) cdef yasm_expr *yasm_expr_create_ident(yasm_expr *r, unsigned long line) cdef yasm_expr *yasm_expr_copy(yasm_expr *e) cdef void yasm_expr_destroy(yasm_expr *e) cdef int yasm_expr_is_op(yasm_expr *e, yasm_expr_op op) ctypedef yasm_expr * (*yasm_expr_xform_func) (yasm_expr *e, void *d) cdef struct yasm__exprhead cdef yasm_expr *yasm_expr__level_tree(yasm_expr *e, int fold_const, int simplify_ident, int simplify_reg_mul, yasm_calc_bc_dist_func calc_bc_dist, yasm_expr_xform_func expr_xform_extra, void *expr_xform_extra_data, yasm__exprhead *eh, int *error) cdef yasm_expr *yasm_expr_simplify(yasm_expr *e, yasm_calc_bc_dist_func cbd) cdef yasm_expr *yasm_expr_extract_segoff(yasm_expr **ep) cdef yasm_expr *yasm_expr_extract_wrt(yasm_expr **ep) cdef yasm_intnum *yasm_expr_get_intnum(yasm_expr **ep, yasm_calc_bc_dist_func calc_bc_dist) cdef yasm_symrec *yasm_expr_get_symrec(yasm_expr **ep, int simplify) cdef unsigned long *yasm_expr_get_reg(yasm_expr **ep, int simplify) cdef void yasm_expr_print(yasm_expr *e, FILE *f) cdef extern from "libyasm/expr-int.h": cdef enum yasm_expr__type: YASM_EXPR_NONE YASM_EXPR_REG YASM_EXPR_INT YASM_EXPR_FLOAT YASM_EXPR_SYM YASM_EXPR_SYMEXP YASM_EXPR_EXPR cdef union yasm_expr__type_data: yasm_symrec *sym yasm_expr *expn yasm_intnum *intn yasm_floatnum *flt unsigned long reg cdef struct yasm_expr__item: yasm_expr__type type yasm_expr__type_data data cdef struct yasm_expr: yasm_expr_op op unsigned long line int numterms yasm_expr__item terms[2] cdef int yasm_expr__traverse_leaves_in_const(yasm_expr *e, void *d, int (*func) (yasm_expr__item *ei, void *d)) cdef int yasm_expr__traverse_leaves_in(yasm_expr *e, void *d, int (*func) (yasm_expr__item *ei, void *d)) cdef void yasm_expr__order_terms(yasm_expr *e) cdef yasm_expr *yasm_expr__copy_except(yasm_expr *e, int excpt) cdef int yasm_expr__contains(yasm_expr *e, yasm_expr__type t) import operator __op = { operator.__add__ : YASM_EXPR_ADD, operator.add : YASM_EXPR_ADD, operator.__and__ : YASM_EXPR_AND, operator.and_ : YASM_EXPR_AND, operator.__div__ : YASM_EXPR_SIGNDIV, operator.__floordiv__: YASM_EXPR_SIGNDIV, operator.div : YASM_EXPR_SIGNDIV, operator.floordiv: YASM_EXPR_SIGNDIV, operator.__ge__: YASM_EXPR_GE, operator.ge: YASM_EXPR_GE, operator.__gt__: YASM_EXPR_GT, operator.gt: YASM_EXPR_GT, operator.__inv__: YASM_EXPR_NOT, operator.__invert__: YASM_EXPR_NOT, operator.inv: YASM_EXPR_NOT, operator.invert: YASM_EXPR_NOT, operator.__le__: YASM_EXPR_LE, operator.le: YASM_EXPR_LE, operator.__lt__: YASM_EXPR_LT, operator.lt: YASM_EXPR_LT, operator.__mod__: YASM_EXPR_SIGNMOD, operator.mod: YASM_EXPR_SIGNMOD, operator.__mul__: YASM_EXPR_MUL, operator.mul: YASM_EXPR_MUL, operator.__neg__: YASM_EXPR_NEG, operator.neg: YASM_EXPR_NEG, operator.__not__: YASM_EXPR_LNOT, operator.not_: YASM_EXPR_LNOT, operator.__or__: YASM_EXPR_OR, operator.or_: YASM_EXPR_OR, operator.__sub__: YASM_EXPR_SUB, operator.sub: YASM_EXPR_SUB, operator.__xor__: YASM_EXPR_XOR, operator.xor: YASM_EXPR_XOR, } del operator cdef class Expression cdef object __make_expression(yasm_expr *expr): return Expression(PyCObject_FromVoidPtr(expr, NULL)) cdef class Expression: cdef yasm_expr *expr def __new__(self, op, *args, **kwargs): self.expr = NULL if isinstance(op, Expression): self.expr = yasm_expr_copy((op).expr) return if PyCObject_Check(op): # should check Desc self.expr = PyCObject_AsVoidPtr(op) return cdef size_t numargs cdef unsigned long line op = __op.get(op, op) numargs = len(args) line = kwargs.get('line', 0) if numargs == 0 or numargs > 2: raise NotImplementedError elif numargs == 2: self.expr = yasm_expr_create(op, self.__new_item(args[0]), self.__new_item(args[1]), line) else: self.expr = yasm_expr_create(op, self.__new_item(args[0]), NULL, line) cdef yasm_expr__item* __new_item(self, value) except NULL: cdef yasm_expr__item *retval if isinstance(value, Expression): return yasm_expr_expr(yasm_expr_copy((value).expr)) #elif isinstance(value, Symbol): # return yasm_expr_sym((value).sym) #elif isinstance(value, Register): # return yasm_expr_reg((value).reg) elif isinstance(value, FloatNum): return yasm_expr_float(yasm_floatnum_copy((value).flt)) elif isinstance(value, IntNum): return yasm_expr_int(yasm_intnum_copy((value).intn)) else: try: intnum = IntNum(value) except: raise ValueError("Invalid item value type '%s'" % type(value)) else: retval = yasm_expr_int((intnum).intn) (intnum).intn = NULL return retval def __dealloc__(self): if self.expr != NULL: yasm_expr_destroy(self.expr) def simplify(self): self.expr = yasm_expr_simplify(self.expr, NULL) # TODO: cbd def extract_segoff(self): cdef yasm_expr *retval retval = yasm_expr_extract_segoff(&self.expr) if retval == NULL: raise ValueError("not a SEG:OFF expression") return __make_expression(retval) def extract_wrt(self): cdef yasm_expr *retval retval = yasm_expr_extract_wrt(&self.expr) if retval == NULL: raise ValueError("not a WRT expression") return __make_expression(retval) def get_intnum(self): cdef yasm_intnum *retval retval = yasm_expr_get_intnum(&self.expr, NULL) # TODO: cbd if retval == NULL: raise ValueError("not an intnum expression") return __make_intnum(yasm_intnum_copy(retval))