|
|
|
# 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((<Expression>op).expr)
|
|
|
|
return
|
|
|
|
if PyCObject_Check(op): # should check Desc
|
|
|
|
self.expr = <yasm_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((<Expression>value).expr))
|
|
|
|
#elif isinstance(value, Symbol):
|
|
|
|
# return yasm_expr_sym((<Symbol>value).sym)
|
|
|
|
#elif isinstance(value, Register):
|
|
|
|
# return yasm_expr_reg((<Register>value).reg)
|
|
|
|
elif isinstance(value, FloatNum):
|
|
|
|
return yasm_expr_float(yasm_floatnum_copy((<FloatNum>value).flt))
|
|
|
|
elif isinstance(value, IntNum):
|
|
|
|
return yasm_expr_int(yasm_intnum_copy((<IntNum>value).intn))
|
|
|
|
else:
|
|
|
|
try:
|
|
|
|
intnum = IntNum(value)
|
|
|
|
except:
|
|
|
|
raise ValueError("Invalid item value type '%s'" % type(value))
|
|
|
|
else:
|
|
|
|
retval = yasm_expr_int((<IntNum>intnum).intn)
|
|
|
|
(<IntNum>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))
|
|
|
|
|