def reorder_operations(self, outer_bin_op: ast.BinOp, inner_bin_op: ast.BinOp) -> Tuple[Any, Any]: inner_first_value = self.literal_eval(inner_bin_op.left) inner_second_value = self.literal_eval(inner_bin_op.right) if (not (isinstance(outer_bin_op.op, BinaryOperation) and outer_bin_op.op.is_symmetric) or not (isinstance(outer_bin_op.op, BinaryOperation) and outer_bin_op.op.is_symmetric)): return inner_first_value, inner_second_value is_left_operand: bool = inner_bin_op is outer_bin_op.left other_value = self.literal_eval( outer_bin_op.right if is_left_operand else outer_bin_op.left) if inner_first_value is not Undefined or inner_second_value is not Undefined: if inner_first_value is Undefined: if other_value is Undefined: if is_left_operand: # (x + 1) + y -> (x + y) + 1 inner_bin_op.right, outer_bin_op.right = outer_bin_op.right, inner_bin_op.right else: # y + (x + 1) -> 1 + (x + y) inner_bin_op.right, outer_bin_op.left = outer_bin_op.left, inner_bin_op.right else: if is_left_operand: # (x + 2) + 1 -> (1 + 2) + x inner_bin_op.left, outer_bin_op.right = outer_bin_op.right, inner_bin_op.left else: # 1 + (x + 2) -> x + (1 + 2) inner_bin_op.left, outer_bin_op.left = outer_bin_op.left, inner_bin_op.left else: if other_value is Undefined: if is_left_operand: # (1 + x) + y -> (y + x) + 1 inner_bin_op.left, outer_bin_op.right = outer_bin_op.right, inner_bin_op.left else: # y + (1 + x) -> 1 + (y + x) inner_bin_op.left, outer_bin_op.left = outer_bin_op.left, inner_bin_op.left else: if is_left_operand: # (2 + x) + 1 -> (2 + 1) + x inner_bin_op.right, outer_bin_op.right = outer_bin_op.right, inner_bin_op.right else: # 1 + (2 + x) -> x + (2 + 1) inner_bin_op.right, outer_bin_op.left = outer_bin_op.left, inner_bin_op.right super().generic_visit(outer_bin_op) return self.literal_eval(outer_bin_op), self.literal_eval(outer_bin_op)
def visit_BinOp(self, node: ast.BinOp): """ Transforms a string concat to an f-string """ if is_string_concat(node): self.counter += 1 left, right = node.left, node.right left = self.visit(left) right = self.visit(right) if not check_sns_depth(left) or not check_sns_depth(right): node.left = left node.right = right return node parts = [] for p in [left, right]: if isinstance(p, ast.JoinedStr): parts += p.values else: parts.append(p) segments = [] for p in parts: if isinstance(p, ast.Constant): segments.append(ast_string_node(p.value)) else: segments.append(ast_formatted_value(p)) return ast.JoinedStr(segments) else: return self.generic_visit(node)
def visit_BinOp(self, node: ast.BinOp) -> Union[ast.BinOp, ast.Num]: """Evaluate binary operation and return ast.Num if operands are bound. Args: node: Binary operation to evaluate. Returns: Evaluated value. """ node.left = self.visit(node.left) node.right = self.visit(node.right) if isinstance(node.left, ast.Num) and isinstance(node.right, ast.Num): val = ast.Num(n=self._match_ops(node.op, self._binary_ops, node.left.n, node.right.n)) return ast.copy_location(val, node) return node
def visit_BinOp(self, node: ast.BinOp): node.left = self.visit(node.left) node.right = self.visit(node.right) if not isinstance(node.left, ast.Num) or not isinstance( node.right, ast.Num): return node result = node try: op_type = type(node.op) result = ast.Num( n=self.binop_dict[op_type](node.left.n, node.right.n)) except: print("Error: undefined type") return ast.copy_location(result, node)
def visit_BinOp(self, node: ast.BinOp) -> ast.BinOp: node = self.generic_visit(node) if self._is_numeric_mult(node): if isinstance(node.right, ast.Num): if node.right.n == 0: node = ast.copy_location(ast.Num(n = 0), node) elif node.right.n == 1: node = node.left elif node.right.n == 2: node.op = ast.copy_location(ast.Add(), node.op) node.right = copy(node.left) elif isinstance(node.left , ast.Num): if node.left.n == 0: node = ast.copy_location(ast.Num(n = 0), node) elif node.left.n == 1: node = node.right elif node.left.n == 2: node.op = ast.copy_location(ast.Add(), node.op) node.left = copy(node.right) return node
def visit_BinOp( self, ast_node_BinOp: ast.BinOp) -> Union[ast.BinOp, ast.Constant]: """ Evaluate binary operation and return ast.BinOp or ast.Constant if operands are bound. :param ast_node_BinOp: the AST node on which the binary operation is performed. :return: evaluated value. """ ast_node_BinOp.left = self.visit(ast_node_BinOp.left) ast_node_BinOp.right = self.visit(ast_node_BinOp.right) left, right = ast_node_BinOp.left, ast_node_BinOp.right if isinstance(left, ast.Constant) and isinstance(right, ast.Constant): new_ast_node_BinOp = ast.Constant(value=self._match_operator( ast_node_BinOp.op, self._ast_math_BinaryOperators, left.value, right.value)) return ast.copy_location(new_ast_node_BinOp, ast_node_BinOp) return ast_node_BinOp
def _make_print(self, ns: List[expr], prefix: str = None) -> Expr: # create the indent: ' ' * depth mul_by = Name(self._DEPTH_VAR, Load()) indent = BinOp(Constant(" "), Mult(), mul_by) # if prefix is given, indent is: ' ' * (depth - len(prefix)) + prefix if prefix is not None: assert len( prefix ) <= self._INDENT, f"too long {prefix} for given indent {self._INDENT}" indent.right = BinOp(mul_by, Sub(), Constant(len(prefix))) indent = BinOp(indent, Add(), Constant(prefix)) return Expr( Call( Name("print", Load()), args=cast(List[expr], [indent]) + ns, keywords=[ keyword("sep", Constant("")), keyword("file", Attribute(Name("sys", Load()), "stderr", Load())), ], ))