def visit_Compare(self, node): """ For ==, !=, >, >=, <, <= : put the arguments in alphabetical order. Replace >= and <= by > and > is the other value is a number """ self.generic_visit(node) if len(node.ops) != 1: return node if isinstance(node.ops[0], (ast.NotEq, ast.Eq, ast.Gt, ast.GtE, ast.Lt, ast.LtE)): left = ast.dump(node.left, annotate_fields=False) right = ast.dump(node.comparators[0], annotate_fields=False) if left > right: node.left, node.comparators[0] = node.comparators[0], node.left if isinstance(node.ops[0], ast.Gt): node.ops[0] = ast.Lt() elif isinstance(node.ops[0], ast.GtE): node.ops[0] = ast.LtE() elif isinstance(node.ops[0], ast.Lt): node.ops[0] = ast.Gt() elif isinstance(node.ops[0], ast.LtE): node.ops[0] = ast.GtE() if (len(node.comparators) == 1 and isinstance(node.comparators[0], ast.Num)): if isinstance(node.ops[0], ast.LtE): # <= 6 ===> < 7 node.ops[0] = ast.Lt() node.comparators[0].n += 1 elif isinstance(node.ops[0], ast.GtE): # >= 6 ===> > 5 node.ops[0] = ast.Gt() node.comparators[0].n -= 1 return node
def visit_Compare(self, node): # cmpop = Eq | NotEq | Lt | LtE | Gt | GtE | Is | IsNot | In | NotIn print(" in MyTransformer.visit_Compare()") print(" node =", node) print(" op =", node.ops[0]) curr_op = node.ops[0] comp_negate = curr_op rand_num = random.randint(1, 10) if rand_num >= 7: print(" negating...") if isinstance(curr_op, ast.Eq): comp_negate = ast.NotEq() elif isinstance(curr_op, ast.NotEq): comp_negate = ast.Eq() elif isinstance(curr_op, ast.Lt): comp_negate = ast.GtE() elif isinstance(curr_op, ast.LtE): comp_negate = ast.Gt() elif isinstance(curr_op, ast.Gt): comp_negate = ast.LtE() elif isinstance(curr_op, ast.GtE): comp_negate = ast.Lt() elif isinstance(curr_op, ast.Is): comp_negate = ast.IsNot() elif isinstance(curr_op, ast.IsNot): comp_negate = ast.Is() elif isinstance(curr_op, ast.In): comp_negate = ast.NotIn() elif isinstance(curr_op, ast.NotIn): comp_negate = ast.In() else: comp_negate = ast.Eq() else: print(" mixing up...") if isinstance(curr_op, ast.Lt): comp_negate = ast.LtE() elif isinstance(curr_op, ast.LtE): comp_negate = ast.And() elif isinstance(curr_op, ast.Gt): comp_negate = ast.Or() elif isinstance(curr_op, ast.GtE): comp_negate = ast.Gt() elif isinstance(curr_op, ast.Is): comp_negate = ast.Gt() elif isinstance(curr_op, ast.IsNot): comp_negate = ast.Lt() elif isinstance(curr_op, ast.In): comp_negate = ast.In( ) #leave the same for for loops (for x in this) elif isinstance(curr_op, ast.NotIn): comp_negate = ast.Lt() else: comp_negate = ast.Eq() print(" new comparator =", comp_negate) # create negated node | Compare(expr left, cmpop* ops, expr* comparators) new_node = node new_node.ops = [comp_negate] ast.copy_location(new_node, node) ast.fix_missing_locations(new_node) return new_node
def visit_Compare(self, node): self.generic_visit(node) self.binop_count += 1 if (self.binop_count == self.count_of_node_to_mutate): new_node = copy.deepcopy(node) print('IN COMPARE') print('THIS IS THE PREVIOUS OP', node.ops) for (i, op) in enumerate(node.ops): if (isinstance(op, ast.Gt)): num = random.randint(0, 2) if num == 0: new_node.ops[i] = ast.GtE() if num == 1: new_node.ops[i] = ast.LtE() if num == 2: new_node.ops[i] = ast.Lt() if (isinstance(op, ast.GtE)): num = random.randint(0, 2) if num == 0: new_node.ops[i] = ast.Gt() if num == 1: new_node.ops[i] = ast.Lt() if num == 2: new_node.ops[i] = ast.LtE() if (isinstance(op, ast.Lt)): num = random.randint(0, 2) if num == 0: new_node.ops[i] = ast.LtE() if num == 1: new_node.ops[i] = ast.GtE() if num == 2: new_node.ops[i] = ast.Gt() if (isinstance(op, ast.LtE)): num = random.randint(0, 2) if num == 0: new_node.ops[i] = ast.Lt() if num == 1: new_node.ops[i] = ast.GtE() if num == 2: new_node.ops[i] = ast.Gt() if (isinstance(op, ast.Eq)): new_node.ops[i] = ast.NotEq() if (isinstance(op, ast.NotEq)): new_node.ops[i] = ast.Eq() if (isinstance(op, ast.Is)): new_node.ops[i] = ast.IsNot() if (isinstance(op, ast.IsNot)): new_node.ops[i] = ast.Is() print('THIS IS THE NEW OP', new_node.ops) print('I AM CREATING A NEW NODE HERE', self.binop_count) return new_node return node
def __gt__(self, other): if isinstance(other, Expr): comp = ast.Compare(left=self._expr, ops=[ast.Gt()], comparators=[other._expr]) return Expr(comp) elif other is not None: comp = ast.Compare(left=self._expr, ops=[ast.Gt()], comparators=[ast.Constant(value=other)]) return Expr(comp) else: return False
def __init__(self, base_node): BaseMutator.__init__(self, base_node) self.original_ops = base_node.ops index_count = 0 for op in base_node.ops: if type(op) in [ast.Gt, ast.GtE, ast.Lt, ast.LtE]: if type(op) is ast.Gt: ops_mutant_Gt = copy.deepcopy(base_node.ops) ops_mutant_Gt[index_count] = ast.GtE() self.mutations.append({"ops": ops_mutant_Gt}) if type(op) is ast.GtE: ops_mutant_GtE = copy.deepcopy(base_node.ops) ops_mutant_GtE[index_count] = ast.Gt() self.mutations.append({"ops": ops_mutant_GtE}) if type(op) is ast.Lt: ops_mutant_Lt = copy.deepcopy(base_node.ops) ops_mutant_Lt[index_count] = ast.LtE() self.mutations.append({"ops": ops_mutant_Lt}) if type(op) is ast.LtE: ops_mutant_LtE = copy.deepcopy(base_node.ops) ops_mutant_LtE[index_count] = ast.Lt() self.mutations.append({"ops": ops_mutant_LtE}) index_count += 1
def visit_Compare(self, node): global visit_count, visit_target visit_count += 1 if (visit_count == visit_target): ##print("Rewrite compare Line: ", node.lineno) if (isinstance(node.ops[0], ast.GtE)): new_node = ast.Compare(left=node.left, ops=[ast.Lt()], comparators=node.comparators) return new_node elif (isinstance(node.ops[0], ast.LtE)): new_node = ast.Compare(left=node.left, ops=[ast.Gt()], comparators=node.comparators) return new_node elif (isinstance(node.ops[0], ast.Gt)): new_node = ast.Compare(left=node.left, ops=[ast.LtE()], comparators=node.comparators) return new_node elif (isinstance(node.ops[0], ast.Lt)): new_node = ast.Compare(left=node.left, ops=[ast.GtE()], comparators=node.comparators) return new_node return node
def visit_Compare(self, node): global number_of_comparisons if (isinstance(node.ops[0], ast.GtE)): new_node = ast.Compare(left=node.left, ops=[ast.Lt()], comparators=node.comparators) number_of_comparisons += 1 elif (isinstance(node.ops[0], ast.LtE)): new_node = ast.Compare(left=node.left, ops=[ast.Gt()], comparators=node.comparators) number_of_comparisons += 1 elif (isinstance(node.ops[0], ast.Gt)): new_node = ast.Compare(left=node.left, ops=[ast.LtE()], comparators=node.comparators) number_of_comparisons += 1 elif (isinstance(node.ops[0], ast.Lt)): new_node = ast.Compare(left=node.left, ops=[ast.GtE()], comparators=node.comparators) number_of_comparisons += 1 return node
def to_node(self): if len(self.operator) == 0: return self.left.to_node() else: right_nodes = [] comp_operator = [] for i in range(len(self.right)): right_nodes.append(self.right[i].to_node()) if self.operator[i] in ['<', 'is lower than']: comp_operator.append(ast.Lt()) elif self.operator[i] in ['<=', 'is lower or equal to']: comp_operator.append(ast.LtE()) elif self.operator[i] in ['>', 'is greater than']: comp_operator.append(ast.Gt()) elif self.operator[i] in ['>=', 'is greater or equal to']: comp_operator.append(ast.GtE()) elif self.operator[i] in ['==', 'is equal to']: comp_operator.append(ast.Eq()) elif self.operator[i] in ['!=', 'is different from', 'is not equal to']: comp_operator.append(ast.NotEq()) elif self.operator[i] == 'in': comp_operator.append(ast.In()) elif self.operator[i] == 'not in': comp_operator.append(ast.NotIn()) elif self.operator[i] == 'is': comp_operator.append(ast.Is()) elif self.operator[i] == 'is not': comp_operator.append(ast.IsNot()) else: raise Exception("Unrecognized argument in Comparison") return ast.Compare(left=self.left.to_node(), ops=comp_operator, comparators=right_nodes)
def CmpOp_In(self, left, comparator): self.visit(ast_call( ast.FunctionDef( '', ast.arguments([ast_load('l'), ast_load('c')], None, None, []), [ ast.Return( ast.IfExp( ast_call( ast_load('Array.isArray'), ast_load('c'), ), ast.Compare( ast_call( ast_load('Array.prototype.indexOf.call'), ast_load('c'), ast_load('l'), ), [ast.Gt()], [ast.Num(-1)] ), ast_call( ast_load('JS'), ast.Str("l in c"), ) ) ) ], [] ), left, comparator ))
def preprocess_boolean(expr, inv): if type(expr) is ast.BoolOp: if type(expr.op) is ast.And or type(expr.op) is ast.Or: new_vs = [] pos_child = None for v in expr.values: nv, is_inv = preprocess_boolean(v, inv) new_vs.append(nv) pos_child = pos_child if is_inv else nv pos_child = pos_child or new_vs[0] if (type(expr.op) is ast.And and inv) or (type(expr.op) is ast.Or and not inv): return ast.BoolOp(ast.Or(), new_vs), False new_vs.remove(pos_child) new_vs2 = [] for v in new_vs: nv, _ = preprocess_boolean(v, True) new_vs2.append(nv) expr = ast.BoolOp(ast.And(), new_vs2) expr.pos_child = pos_child return expr, False else: raise Babeception( str(type(expr.op)) + ' is not supported in boolean!') elif type(expr) is ast.UnaryOp: if type(expr.op) is ast.Not: return preprocess_boolean(expr.operand, False) if inv else preprocess_boolean( expr.operand, True) else: raise Babeception( str(type(expr.op)) + ' is not supported in boolean!') elif type(expr) is ast.Compare: if type(expr.ops[0]) is ast.NotEq or type( expr.ops[0]) is ast.Lt or type(expr.ops[0]) is ast.Gt: return preprocess_child(expr, inv) elif type(expr.ops[0]) is ast.Eq: return preprocess_boolean( ast.UnaryOp( ast.Not(), ast.Compare(expr.left, [ast.NotEq()], expr.comparators)), inv) elif type(expr.ops[0]) is ast.LtE: return preprocess_boolean( ast.UnaryOp( ast.Not(), ast.Compare(expr.left, [ast.Gt()], expr.comparators)), inv) elif type(expr.ops[0]) is ast.GtE: return preprocess_boolean( ast.UnaryOp( ast.Not(), ast.Compare(expr.left, [ast.Lt()], expr.comparators)), inv) else: raise Babeception( str(type(expr.ops[0])) + ' is not supported in boolean!') elif type(expr) is ast.Call or type(expr) is ast.Name: return preprocess_child(expr, inv) else: raise Babeception(str(type(expr)) + ' is not supported in boolean!')
def visit_For(self, node): iterator = self.visit(node.iter.func) assert iterator == self.builtins['range'] # create nodes st_target = ast.Name(id=node.target.id, ctx=ast.Store()) ld_target = ast.Name(id=node.target.id, ctx=ast.Load()) init_node = ast.Assign(targets=[st_target], value=node.iter.args[0]) pos_cond_node = ast.Compare(ld_target, [ast.Lt()], [node.iter.args[1]]) neg_cond_node = ast.Compare(ld_target, [ast.Gt()], [node.iter.args[1]]) pos_step_node = ast.Compare(node.iter.args[2], [ast.Gt()], [ast.Num(0)]) build_cond = lambda: triton.language.where(self.visit(pos_step_node),\ self.visit(pos_cond_node),\ self.visit(neg_cond_node),\ builder=self.builder) #cond_node = neg_cond_node step_node = ast.AugAssign(target=st_target, op=ast.Add(), value=node.iter.args[2]) # code generation current_bb = self.builder.get_insert_block() loop_bb = _triton.ir.basic_block.create(self.module.builder.context, "loop", current_bb.parent) next_bb = _triton.ir.basic_block.create(self.module.builder.context, "postloop", current_bb.parent) def continue_fn(): self.visit(step_node) cond = build_cond() return self.builder.cond_br(cond.handle, loop_bb, next_bb) self.visit(init_node) cond = build_cond() self.builder.cond_br(cond.handle, loop_bb, next_bb) self.builder.set_insert_block(loop_bb) self.visit_compound_statement(node.body) # TODO: handle case where body breaks control flow continue_fn() stop_bb = self.builder.get_insert_block() self.module.seal_block(stop_bb) self.module.seal_block(loop_bb) self.module.seal_block(next_bb) self.builder.set_insert_block(next_bb) for stmt in node.orelse: ast.NodeVisitor.generic_visit(self, stmt)
def 比较(片段): 对照表 = { '>': ast.Gt(), '>=': ast.GtE(), '<': ast.Lt(), '<=': ast.LtE(), '==': ast.Eq(), '!=': ast.NotEq(), '===': ast.Is(), '!==': ast.IsNot() } return 语法树.比较(前项=片段[0], 操作符=对照表[片段[1].getstr()], 后项=片段[2], 片段=片段)
def visit_For(self, node): if node.orelse: raise Exception('for-else is not supported.') if isinstance(node.iter, _ast.Call) and isinstance(node.iter.func, _ast.Name) and \ node.iter.func.id == 'range': if len(node.iter.args) == 1: start = ast.Num(0) stop = node.iter.args[0] step = ast.Num(1) cmp_op = ast.Lt() elif len(node.iter.args) == 2: start = node.iter.args[0] stop = node.iter.args[1] step = ast.Num(1) cmp_op = ast.Lt() elif len(node.iter.args) == 3: start = node.iter.args[0] stop = node.iter.args[1] step = node.iter.args[2] if not isinstance(step, _ast.Num): raise Exception( 'range() only supports literal numeric step') if step.n >= 0: cmp_op = ast.Lt() else: cmp_op = ast.Gt() else: raise Exception('range() expects 1, 2 or 3 parameters') self.indent() self.output('for(') self.visit(node.target) self.output(' = ') self.visit(start) self.output('; ') self.visit(ast.Compare(node.target, [cmp_op], [stop])) self.output('; ') self.visit(node.target) self.output(' += ') self.visit(step) self.output(') ') else: self.indent() self.output('for(') self.visit(node.target) self.output(' in ') self.visit(node.iter) self.output(') ') self.block(node.body, context=BlockContext(self.stack[-1])) self.output('\n')
def nontrivial_range(loop_varname: str, args: list): """ When you have a `range()` like: for i in range(50, 133, x+1): you cannot be sure if the last argument (x+1) is > 0 or not. Hence, if you want to transform a `for _ in range(_)` expression into a `while`, you have to build a more complex while condition such as: while ( (x+1 < 0 and i > 133) or (x+1 >= 0 and i < 133)): this template returns this "complex" condition. """ return ast.Expr(value=ast.BoolOp( op=ast.Or(), values=[ ast.BoolOp( op=ast.And(), values=[ ast.Compare( left=args[2], ops=[ast.Lt()], comparators=[ast.Constant(value=0, kind=None)], ), ast.Compare( left=ast.Name(id=loop_varname, ctx=ast.Load()), ops=[ast.Gt()], comparators=[args[1]], ), ], ), ast.BoolOp( op=ast.And(), values=[ ast.Compare( left=args[2], ops=[ast.GtE()], comparators=[ast.Constant(value=0, kind=None)], ), ast.Compare( left=ast.Name(id=loop_varname, ctx=ast.Load()), ops=[ast.Lt()], comparators=[args[1]], ), ], ), ], ), )
def Random_Compare(self): random_int = random.randint(0, 5) if random_int == 0: return ast.Eq() elif random_int == 1: return ast.NotEq() elif random_int == 2: return ast.Gt() elif random_int == 3: return ast.Lt() elif random_int == 4: return ast.GtE() else: return ast.LtE()
def test_no_mod_in_place(): class my_clone(CloningNodeTransformer): def visit_Name(self, a: ast.Name): return ast.Name(id='there') c1 = ast.Name(id='hi') c2 = ast.Num(n=10) a = ast.Compare(ops=[ast.Gt()], left=c1, comparators=[c2]) new_a = my_clone().visit(a) assert a is not new_a assert ast.dump(new_a) != ast.dump(a) assert ast.dump(a).replace('hi', 'there') == ast.dump(new_a)
def undoReverse(a): tmp = None if type(a) == ast.Lt: tmp = ast.Gt() elif type(a) == ast.LtE: tmp = ast.GtE() elif type(a) == ast.Gt: tmp = ast.Lt() elif type(a) == ast.GtE: tmp = ast.LtE() else: return a transferMetaData(a, tmp) return tmp
def p_comp_op(p): '''comp_op : ">" | "<" | OP_EQ | OP_GE | OP_LE | OP_NE | OP_NNE | TAG_IN | TAG_NOT TAG_IN | TAG_IS | TAG_IS TAG_NOT''' if len(p) == 2: if p.get_item(1).type == 'OP_EQ': p[0] = ast.Eq() elif p.get_item(1).type == '>': p[0] = ast.Gt() elif p.get_item(1).type == '<': p[0] = ast.Lt() elif p.get_item(1).type == 'OP_GE': p[0] = ast.GtE() elif p.get_item(1).type == 'OP_LE': p[0] = ast.LtE() elif p.get_item(1).type == 'OP_NE': p[0] = ast.NotEq() elif p.get_item(1).type == 'OP_NNE': p[0] = ast.NotEq() elif p[1] == 'is': p[0] = ast.Is() elif p[1] == 'in': p[0] = ast.In() elif len(p) == 3: if p[1] == 'is': p[0] = ast.IsNot() elif p[1] == 'not': p[0] = ast.NotIn() return
class BinaryInfixOperand(object): n_terms = 2 assoc = 'LEFT' keyword_aliases = _kw( (['and', '&&'], ast.And()), (['or', '||'], ast.Or()), (['<', 'lt'], ast.Lt()), (['==', 'eq'], ast.Eq()), (['<=', 'le'], ast.LtE()), (['!=', 'ne'], ast.NotEq()), (['>=', 'ge'], ast.GtE()), (['>', 'gt'], ast.Gt()), ) def __init__(self, tokens): tokens = tokens[0] if len(tokens) % 2 == 1: self.op_token = tokens[1] self.comparators = tokens[::2] else: err = "Invalid number of infix expressions: {}" err = err.format(len(tokens)) raise ParseException(err) assert self.op_token in self.keyword_aliases # Check for too many literals and not enough keywords op = self.keyword_aliases[self.op_token] if isinstance(op, ast.boolop): if any(isinstance(c, Literal) for c in self.comparators): raise ValueError("Cannot use literals as truth") else: if all(isinstance(c, Literal) for c in self.comparators): raise ValueError("Cannot compare literals.") def ast(self): op = self.keyword_aliases[self.op_token] if isinstance(op, ast.boolop): # and and or use one type of AST node value = ast.BoolOp(op=op, values=[e.ast() for e in self.comparators]) else: # remaining operators use another value = ast.Compare( left=self.comparators[0].ast(), ops=[op], comparators=[e.ast() for e in self.comparators[1:]]) return value
def visit_range(self, args: list, var_name: str): if len(args) == 1: return [0, self.visit(args[0]), 1], ast.Lt() elif len(args) == 2: return [self.visit(args[0]), self.visit(args[1]), 1], ast.Lt() else: v_a, v_b, v_s = [self.visit(arg) for arg in args] step = args[-1] # AST, not string! if is_costant(step): try: comp = ast.Gt() if ast.literal_eval(step) < 0 else ast.Lt() return [v_a, v_b, v_s], comp except (ValueError, TypeError): pass return [v_a, v_b, v_s], templates.nontrivial_range(var_name, args)
class Infix(Symbol): rightAssoc = False _operator_map = { "in": ast.In(), ">": ast.Gt(), "<": ast.Lt(), "=": ast.Eq() } _logical_map = {"and": ast.And(), "or": ast.Or()} def led(self, left): self.first = left rbp = self.lbp - int(self.rightAssoc) self.second = self.parser.expression(rbp) return self def __repr__(self): return "<'%s'>(%s, %s)" % (self.value, self.first, self.second) def ast(self, context=None): lhs = self.first.ast(context) if self.second: rhs = self.second.ast(context) if self.value in self._logical_map: return ast.BoolOp(op=self._logical_map[self.value], values=[lhs, rhs]) else: path = list(context.stack) path.append(self.first.value) return ast.Call( func=ast.Name(id="filter_field", ctx=ast.Load()), args=[ ast.Name(id="obj", ctx=ast.Load()), ast.List(elts=[ast.Str(s=i) for i in path], ctx=ast.Load()), ast.Str(s=self.value), rhs, ], keywords=[], ) return ast.Name(id="not", ctx=ast.Load())
def mutate(cls, node): if node not in config.visited_nodes: if node.__class__ in [ ast.Eq, ast.NotEq, ast.Lt, ast.Gt, ast.LtE, ast.GtE ]: if node.__class__ in config.comparison_operators: config.comparison_operators.remove(node.__class__) while len(config.comparison_operators) > 0: original_node = deepcopy(node) parent = config.parent_dict[node] del config.parent_dict[node] node_type = config.comparison_operators.pop() if node_type is ast.Eq: node = ast.Eq() elif node_type is ast.NotEq: node = ast.NotEq() elif node_type is ast.Lt: node = ast.Lt() elif node_type is ast.Gt: node = ast.Gt() elif node_type is ast.LtE: node = ast.LtE() elif node_type is ast.GtE: node = ast.GtE() else: print "TypeError in AOR" config.parent_dict[node] = parent config.node_pairs[node] = original_node config.current_mutated_node = node config.mutated = True return node if len(config.arithmetic_operators) == 0: config.arithmetic_operators = [ ast.Eq, ast.NotEq, ast.Lt, ast.Gt, ast.LtE, ast.GtE ] config.visited_nodes.add(node) return node
def branch_dist_boolop(op, values, args): if len(values) == 1: return branch_dist(values[0], args) else: return ast.Call(func=ast.Lambda( args=ast.arguments( args=[ast.arg(arg=args.lambda_arg, annotation=None)], vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None, defaults=[]), body=ast.IfExp(test=ast.Compare( left=ast.Name(id=args.lambda_arg), ops=[ast.Gt() if isinstance(op, ast.And) else ast.LtE()], comparators=[ast.Num(n=0)]), body=ast.Name(id=args.lambda_arg), orelse=branch_dist_boolop(op, values[1:], args))), args=[branch_dist(values[0], args)], keywords=[])
def resolve_value(value, scope): if isinstance(value, EId): node = ast.Name(id=value.v, ctx=ast.Load()) elif isinstance(value, EInt): node = ast.Num(n=value.v) elif isinstance(value, EList): lst = [resolve_value(a, scope) for a in value.v] node = ast.List(elts=lst, ctx=ast.Load()) elif isinstance(value, EOp): lft, rgt = value.v lft = resolve_value(lft, scope) rgt = resolve_value(rgt, scope) operators = { '+': ast.Add(), '-': ast.Sub(), '*': ast.Mult(), '/': ast.Div(), '%': ast.Mod(), } node = ast.BinOp(left=lft, right=rgt, op=operators[value.t]) elif isinstance(value, ECompare): lft, rgt = value.v lft = resolve_value(lft, scope) rgt = resolve_value(rgt, scope) operators = { '<': ast.Lt(), '>': ast.Gt(), '<=': ast.LtE(), '>=': ast.GtE(), '==': ast.Eq(), } node = ast.Compare(left=lft, ops=[operators[value.t]], comparators=[rgt]) return ast.fix_missing_locations(node)
def visit_Compare(self, compare_node): if len(compare_node.comparators) > 1: return format_string = self.formatstring_for_comparison(compare_node) if format_string is None: return statements = [] format_params = [] new_comparators = [] for i, comparator in enumerate([compare_node.left] + compare_node.comparators): name = '@contexts_assertion_var' + str(i) statements.append(self.assign(name, comparator)) new_comparators.append(self.load(name)) format_params.append(self.repr(self.load(name))) name = '@contexts_formatparam' if isinstance(compare_node.ops[0], ast.Lt): ternary_expression = ast.IfExp( ast.Compare(new_comparators[0], [ast.Gt()], [new_comparators[1]]), ast.Str('it to be greater'), ast.Str('them to be equal') ) elif isinstance(compare_node.ops[0], ast.Gt): ternary_expression = ast.IfExp( ast.Compare(new_comparators[0], [ast.Lt()], [new_comparators[1]]), ast.Str('it to be less'), ast.Str('them to be equal') ) if isinstance(compare_node.ops[0], (ast.Lt, ast.Gt)): statements.append(self.assign(name, ternary_expression)) format_params.append(self.load(name)) compare_node.left, *compare_node.comparators = new_comparators msg = self.format(format_string, format_params) statements.append(ast.Assert(compare_node, msg)) return statements
def p_expr_compare(self, p): '''expr : expr EQUALITY expr | expr INEQUALITY expr | expr LESSTHAN expr | expr GREATERTHAN expr | expr LESSTHANOREQUAL expr | expr GREATERTHANOREQUAL expr ''' op = None if p[2] == '==': op = ast.Eq() elif p[2] == '!=': op = ast.NotEq() elif p[2] == '<': op = ast.Lt() elif p[2] == '>': op = ast.Gt() elif p[2] == '<=': op = ast.LtE() elif p[2] == '>=': op = ast.GtE() p[0] = ast.Compare(left=p[1], ops=[op], comparators=[p[3]])
def create_boolean_entity_node(self, boolean_entity): left_node = self.to_node(boolean_entity.left) if boolean_entity.operator is None: return left_node elif boolean_entity.operator in ['==', 'is equal to']: python_cmp_op = ast.Eq() elif boolean_entity.operator in [ '!=', 'is not equal to', 'is different from' ]: python_cmp_op = ast.NotEq() elif boolean_entity.operator in ['>', 'is greater than']: python_cmp_op = ast.Gt() elif boolean_entity.operator in ['>=', 'is greater or equal to']: python_cmp_op = ast.GtE() elif boolean_entity.operator in ['<', 'is lower than']: python_cmp_op = ast.Lt() elif boolean_entity.operator in ['<=', 'is lower or equal to']: python_cmp_op = ast.LtE() else: raise right_node = self.to_node(boolean_entity.right) return ast.Compare(left_node, (python_cmp_op, ), (right_node, ))
def visit_CmpOp(self, node: CmpOp, *args, **kwargs) -> C.cmpop: if node == CmpOp.Eq: return C.Eq() elif node == CmpOp.NotEq: return C.NotEq() elif node == CmpOp.Lt: return C.Lt() elif node == CmpOp.Lte: return C.Lte() elif node == CmpOp.Gt: return C.Gt() elif node == CmpOp.Gte: return C.Gte() elif node == CmpOp.Is: return C.Is() elif node == CmpOp.IsNot: return C.IsNot() elif node == CmpOp.In: return C.In() elif node == CmpOp.NotIn: return C.NotIn() else: raise Exception(f'unknown CmpOp {node!r}')
def neg(pred): ops = pred.ops[0] if type(ops) == ast.Eq: pred.ops[0] = ast.NotEq() return pred elif type(ops) == ast.NotEq: pred.ops[0] = ast.Eq() return pred elif type(ops) == ast.Lt: pred.ops[0] = ast.GtE() return pred elif type(ops) == ast.Gt: pred.ops[0] = ast.LtE() return pred elif type(ops) == ast.LtE: pred.ops[0] = ast.Gt() return pred elif type(ops) == ast.GtE: pred.ops[0] = ast.Lt() return pred else: print('%s Not Supported' % type(ops).__name__) exit(1)
def visit_For(self, node): # Turn for+range loop into a while loop: # i = start # while i < stop: # body # i = i + step assert isinstance(node.iter, ast.Call) and \ node.iter.func.id == 'range', \ 'for can only be used with range()' range_args = node.iter.args if len(range_args) == 1: start = ast.Num(n=0) stop = range_args[0] step = ast.Num(n=1) elif len(range_args) == 2: start, stop = range_args step = ast.Num(n=1) else: start, stop, step = range_args if (isinstance(step, ast.UnaryOp) and isinstance(step.op, ast.USub) and isinstance(step.operand, ast.Num)): # Handle negative step step = ast.Num(n=-step.operand.n) assert isinstance(step, ast.Num) and step.n != 0, \ 'range() step must be a nonzero integer constant' self.visit(ast.Assign(targets=[node.target], value=start)) test = ast.Compare( left=node.target, ops=[ast.Lt() if step.n > 0 else ast.Gt()], comparators=[stop], ) incr = ast.Assign( targets=[node.target], value=ast.BinOp(left=node.target, op=ast.Add(), right=step), ) self.visit(ast.While(test=test, body=node.body + [incr]))