1# Python bindings for Yasm: Pyrex input file for expr.h 2# 3# Copyright (C) 2006 Michael Urman, Peter Johnson 4# 5# Redistribution and use in source and binary forms, with or without 6# modification, are permitted provided that the following conditions 7# are met: 8# 1. Redistributions of source code must retain the above copyright 9# notice, this list of conditions and the following disclaimer. 10# 2. Redistributions in binary form must reproduce the above copyright 11# notice, this list of conditions and the following disclaimer in the 12# documentation and/or other materials provided with the distribution. 13# 14# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS'' 15# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE 18# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24# POSSIBILITY OF SUCH DAMAGE. 25 26cdef extern from *: 27 # Defined as a macro, so not automatically brought in by pyxelator 28 cdef yasm_expr *yasm_expr_simplify(yasm_expr *e, int calc_bc_dist) 29 30import operator 31__op = {} 32for ops, operation in [ 33 ((operator.__add__, operator.add, '+'), YASM_EXPR_ADD), 34 ((operator.__and__, operator.and_, '&'), YASM_EXPR_AND), 35 ((operator.__div__, operator.div, '/'), YASM_EXPR_SIGNDIV), 36 ((operator.__floordiv__, operator.floordiv, '//'), YASM_EXPR_SIGNDIV), 37 ((operator.__ge__, operator.ge, '>='), YASM_EXPR_GE), 38 ((operator.__gt__, operator.gt, '>'), YASM_EXPR_GT), 39 ((operator.__inv__, operator.inv, '~'), YASM_EXPR_NOT), 40 ((operator.__invert__, operator.invert), YASM_EXPR_NOT), 41 ((operator.__le__, operator.le, '<='), YASM_EXPR_LE), 42 ((operator.__lt__, operator.lt, '<'), YASM_EXPR_LT), 43 ((operator.__mod__, operator.mod, '%'), YASM_EXPR_SIGNMOD), 44 ((operator.__mul__, operator.mul, '*'), YASM_EXPR_MUL), 45 ((operator.__neg__, operator.neg), YASM_EXPR_NEG), 46 ((operator.__not__, operator.not_, 'not'), YASM_EXPR_LNOT), 47 ((operator.__or__, operator.or_, '|'), YASM_EXPR_OR), 48 ((operator.__sub__, operator.sub, '-'), YASM_EXPR_SUB), 49 ((operator.__xor__, operator.xor, '^'), YASM_EXPR_XOR), 50 ]: 51 for op in ops: 52 __op[op] = operation 53 54del operator, op, ops, operation 55 56cdef object __make_expression(yasm_expr *expr): 57 return Expression(__pass_voidp(expr, Expression)) 58 59cdef class Expression: 60 cdef yasm_expr *expr 61 62 def __cinit__(self, op, *args, **kwargs): 63 self.expr = NULL 64 65 if isinstance(op, Expression): 66 self.expr = yasm_expr_copy((<Expression>op).expr) 67 return 68 if PyCObject_Check(op): 69 self.expr = <yasm_expr *>__get_voidp(op, Expression) 70 return 71 72 cdef size_t numargs 73 cdef unsigned long line 74 75 op = __op.get(op, op) 76 numargs = len(args) 77 line = kwargs.get('line', 0) 78 79 if numargs == 0 or numargs > 2: 80 raise NotImplementedError 81 elif numargs == 2: 82 self.expr = yasm_expr_create(op, self.__new_item(args[0]), 83 self.__new_item(args[1]), line) 84 else: 85 self.expr = yasm_expr_create(op, self.__new_item(args[0]), NULL, 86 line) 87 88 cdef yasm_expr__item* __new_item(self, value) except NULL: 89 cdef yasm_expr__item *retval 90 if isinstance(value, Expression): 91 return yasm_expr_expr(yasm_expr_copy((<Expression>value).expr)) 92 #elif isinstance(value, Symbol): 93 # return yasm_expr_sym((<Symbol>value).sym) 94 #elif isinstance(value, Register): 95 # return yasm_expr_reg((<Register>value).reg) 96 elif isinstance(value, FloatNum): 97 return yasm_expr_float(yasm_floatnum_copy((<FloatNum>value).flt)) 98 elif isinstance(value, IntNum): 99 return yasm_expr_int(yasm_intnum_copy((<IntNum>value).intn)) 100 else: 101 try: 102 intnum = IntNum(value) 103 except: 104 raise ValueError("Invalid item value type '%s'" % type(value)) 105 else: 106 retval = yasm_expr_int((<IntNum>intnum).intn) 107 (<IntNum>intnum).intn = NULL 108 return retval 109 110 def __dealloc__(self): 111 if self.expr != NULL: yasm_expr_destroy(self.expr) 112 113 def simplify(self, calc_bc_dist=False): 114 self.expr = yasm_expr_simplify(self.expr, calc_bc_dist) 115 116 def extract_segoff(self): 117 cdef yasm_expr *retval 118 retval = yasm_expr_extract_segoff(&self.expr) 119 if retval == NULL: 120 raise ValueError("not a SEG:OFF expression") 121 return __make_expression(retval) 122 123 def extract_wrt(self): 124 cdef yasm_expr *retval 125 retval = yasm_expr_extract_wrt(&self.expr) 126 if retval == NULL: 127 raise ValueError("not a WRT expression") 128 return __make_expression(retval) 129 130 def get_intnum(self, calc_bc_dist=False): 131 cdef yasm_intnum *retval 132 retval = yasm_expr_get_intnum(&self.expr, calc_bc_dist) 133 if retval == NULL: 134 raise ValueError("not an intnum expression") 135 return __make_intnum(yasm_intnum_copy(retval)) 136 137