def num_negate(op):
top = type(op)
neg = not op.num_negated if hasattr(op, "num_negated") else True
if top == ast.Add:
newOp = ast.Sub()
elif top == ast.Sub:
newOp = ast.Add()
elif top in [ast.Mult, ast.Div, ast.Mod, ast.Pow, ast.LShift,
ast.RShift, ast.BitOr, ast.BitXor, ast.BitAnd, ast.FloorDiv]:
return None # can't negate this
elif top in [ast.Num, ast.Name]:
# this is a normal value, so put a - in front of it
newOp = ast.UnaryOp(ast.USub(addedNeg=True), op)
else:
log("astTools\tnum_negate\tUnusual type: " + str(top), "bug")
transferMetaData(op, newOp)
newOp.num_negated = neg
return newOp
python类FloorDiv()的实例源码
def visit_AugAssign(self, node):
"""
AugAssign(expr target, operator op, expr value)
"""
# TODO: Make sure that all the logic in Assign also works in AugAssign
target = self.visit(node.target)
value = self.visit(node.value)
if isinstance(node.op, ast.Pow):
self.write("%s = %s ** %s" % (target, target, value))
#elif isinstance(node.op, ast.FloorDiv):
# #self.write("%s = Math.floor((%s)/(%s));" % (target, target, value))
# self.write("%s = (%s/%s)" % (target, target, value))
elif isinstance(node.op, ast.Div):
if re.search(r"Numo::", target) or re.search(r"Numo::", value):
self.write("%s = (%s)/(%s)" % (target, target, value))
else:
self.write("%s = (%s)/(%s).to_f" % (target, target, value))
else:
self.write("%s %s= %s" % (target, self.get_binary_op(node), value))
def _infer_arithmetic(left_type, right_type, op, lineno, solver):
"""Infer the type of an arithmetic operation, and add the corresponding axioms"""
result_type = solver.new_z3_const("arithmetic_result")
magic_method = ""
if isinstance(op, ast.Sub):
magic_method = "__sub__"
elif isinstance(op, ast.FloorDiv):
magic_method = "__floordiv__"
elif isinstance(op, ast.Mod):
magic_method = "__mod__"
elif isinstance(op, ast.LShift):
magic_method = "__lshift__"
elif isinstance(op, ast.RShift):
magic_method = "__rshift__"
solver.add(axioms.arithmetic(left_type, right_type, result_type, magic_method,
isinstance(op, ast.Mod), solver.z3_types),
fail_message="Arithmetic operation in line {}".format(lineno))
return result_type
def __init__(self):
super().__init__()
# add support for bitwise operators
if ast.LShift not in self.MATH_OPERATORS: # '<<'
self.MATH_OPERATORS[ast.LShift] = simpleeval.op.lshift
if ast.RShift not in self.MATH_OPERATORS: # '>>'
self.MATH_OPERATORS[ast.RShift] = simpleeval.op.rshift
if ast.BitOr not in self.MATH_OPERATORS: # '|'
self.MATH_OPERATORS[ast.BitOr] = simpleeval.op.or_
if ast.BitXor not in self.MATH_OPERATORS: # '^'
self.MATH_OPERATORS[ast.BitXor] = simpleeval.op.xor
if ast.BitAnd not in self.MATH_OPERATORS: # '&'
self.MATH_OPERATORS[ast.BitAnd] = simpleeval.op.and_
# add support for extra operators
#if ast.Not not in self.MATH_OPERATORS: # not ('not')
# self.MATH_OPERATORS[ast.Not] = simpleeval.op.not_
if ast.FloorDiv not in self.MATH_OPERATORS: # floordiv ('//')
self.MATH_OPERATORS[ast.FloorDiv] = simpleeval.op.floordiv
def doBinaryOp(op, l, r):
"""Perform the given AST binary operation on the values"""
top = type(op)
if top == ast.Add:
return l + r
elif top == ast.Sub:
return l - r
elif top == ast.Mult:
return l * r
elif top == ast.Div:
# Don't bother if this will be a really long float- it won't work properly!
# Also, in Python 3 this is floating division, so perform it accordingly.
val = 1.0 * l / r
if (val * 1e10 % 1.0) != 0:
raise Exception("Repeating Float")
return val
elif top == ast.Mod:
return l % r
elif top == ast.Pow:
return l ** r
elif top == ast.LShift:
return l << r
elif top == ast.RShift:
return l >> r
elif top == ast.BitOr:
return l | r
elif top == ast.BitXor:
return l ^ r
elif top == ast.BitAnd:
return l & r
elif top == ast.FloorDiv:
return l // r
def visit_AugAssign(self, node):
if node.op.__class__ != ast.FloorDiv:
return node
dummy_op = ast.BinOp(left=node.target, op=ast.Div(), right=node.value)
dummy_int = ast.Name(id="int", ctx=ast.Load())
dummy_call = ast.Call(func=dummy_int, args=[dummy_op], keywords=[], starargs=None, kwargs=None)
return ast.Assign(targets=[node.target], value=dummy_call)
def visit_BinOp(self, node):
if node.op.__class__ != ast.FloorDiv:
return node
dummy_op = ast.BinOp(left=node.left, op=ast.Div(), right=node.right)
dummy_int = ast.Name(id="int", ctx=ast.Load())
return ast.Call(func=dummy_int, args=[dummy_op], keywords=[], starargs=None, kwargs=None)
def visit_AugAssign(self, node):
assert node.op.__class__ not in [ast.Pow, ast.FloorDiv]
target = self.visit(node.target)
op = OPERATOR_MAP[node.op.__class__]
value = self.visit(node.value)
return cpp.AugAssign(target, op, value)
def visit_BinOp(self, node):
assert node.op.__class__ not in [ast.Pow, ast.FloorDiv]
left = self.visit(node.left)
op = OPERATOR_MAP[node.op.__class__]
right = self.visit(node.right)
return cpp.BinOp(left=left, op=op, right=right)
def mutate_Mult_to_FloorDiv(self, node):
if self.should_mutate(node):
return ast.FloorDiv()
raise MutationResign()
def mutate_Div_to_FloorDiv(self, node):
if self.should_mutate(node):
return ast.FloorDiv()
raise MutationResign()
def pythonast(self, args, tonative=False):
return ast.BinOp(args[0], ast.FloorDiv(), args[1])