예제 #1
0
 def visit_Name(self, name):
     # Display the repr of the name if it's a local variable or
     # _should_repr_global_name() thinks it's acceptable.
     locs = ast_Call(self.builtin("locals"), [], [])
     inlocs = ast.Compare(ast.Str(name.id), [ast.In()], [locs])
     dorepr = self.helper("_should_repr_global_name", name)
     test = ast.BoolOp(ast.Or(), [inlocs, dorepr])
     expr = ast.IfExp(test, self.display(name), ast.Str(name.id))
     return name, self.explanation_param(expr)
예제 #2
0
파일: tryexcept.py 프로젝트: ztane/jaspyx
    def visit_TryExcept(self, node):
        if node.orelse:
            raise NotImplementedError('Try-except else handler not implemented')

        self.indent()
        self.output('try')
        self.block(node.body, context=BlockContext(self.stack[-1]))
        self.output(' catch($e) ')
        self.push(BlockContext(self.stack[-1]))

        if_start = None
        if_end = None

        for handler in node.handlers:
            if handler.type is not None:
                if handler.name is not None:
                    body = handler.body[:]
                    body.insert(0, ast.Assign(
                        [handler.name],
                        ast_call(ast_load('JS'), ast.Str('$e'))
                    ))
                else:
                    body = handler.body

                types = [handler.type] if isinstance(handler.type, _ast.Name) else handler.type
                conditions = [
                    ast_call(
                        ast_load('isinstance'),
                        ast_call(ast_load('JS'), ast.Str('$e')),
                        type_,
                    )
                    for type_ in types
                ]

                _if = ast.If(
                    ast.BoolOp(ast.Or(), conditions),
                    body,
                    []
                )
                if if_start is None:
                    if_start = if_end = _if
                else:
                    if_end.orelse, if_end = [_if], _if
            else:
                if handler is not node.handlers[-1]:
                    raise SyntaxError("default 'except:' must be last")
                if if_start is None:
                    self.block(handler.body)
                else:
                    if_end.orelse = handler.body

        if if_start is not None:
            self.visit(if_start)

        self.pop()
        self.output('\n')
예제 #3
0
 def setup(self):
     self.modulename = 'somename'
     self.node = ast.BoolOp(values=[
         ast.Name(id='a'),
         ast.Name(id='b'),
         ast.Name(id='c'),
     ],
                            lineno=6,
                            col_offset=4)
     self.label = '6.1'
 def __and__(self, other) -> Column:
     ''' Bitwise and becomes a logical and. '''
     self._test_for_extension('operator and')
     from .utils import _term_to_ast
     return Column(
         type(bool),
         ast.BoolOp(
             op=ast.And(),
             values=[_term_to_ast(self, None),
                     _term_to_ast(other, None)]))
예제 #5
0
 def compile_logical_or_and_and_operator(self, expression):
     ops = {"and": ast.And, "or": ast.Or}
     operator = expression.pop(0)
     values = []
     for child in expression:
         values.append(self.compile(child))
     return ast.BoolOp(op=ops[operator](),
                       lineno=operator.start_line,
                       col_offset=operator.start_column,
                       values=values)
예제 #6
0
def missingCheck(check: ast.Compare, el: ast.Subscript,
                 default: bool) -> ast.BoolOp:
    """Creates AST nodes corresponding to check whether the `el` is None, if it is returns `default`"""
    return ast.BoolOp(op=(ast.Or() if default else ast.And()),
                      values=[
                          ast.Compare(
                              left=el,
                              ops=[(ast.Is() if default else ast.IsNot())],
                              comparators=[noneCnst]), check
                      ])
예제 #7
0
    def visit_BoolOp(self, node):
        'Check if BoolOp is exaclty matching or contain pattern'

        if isinstance(self.patt_ast, ast.BoolOp):
            if len(node.values) == len(self.patt_ast.values):
                pat = PatternMatcher(node, self.nbits)
                matched = pat.visit(node, self.patt_ast)
                if matched:
                    new_node = EvalPattern(pat.wildcards).visit(self.rep_ast)
                    return new_node
                else:
                    return self.generic_visit(node)
            elif len(node.values) > len(self.patt_ast.values):
                # associativity n to m
                for combi in itertools.combinations(node.values,
                                                    len(self.patt_ast.values)):
                    rest = [elem for elem in node.values if elem not in combi]
                    testnode = ast.BoolOp(node.op, list(combi))
                    pat = PatternMatcher(testnode, self.nbits)
                    matched = pat.visit(testnode, self.patt_ast)
                    if matched:
                        new = EvalPattern(pat.wildcards).visit(self.rep_ast)
                        new = ast.BoolOp(node.op, [new] + rest)
                        new = asttools.Unleveling().visit(new)
                        return new
            return self.generic_visit(node)

        if isinstance(self.patt_ast, ast.BinOp):
            if type(node.op) != type(self.patt_ast.op):
                return self.generic_visit(node)
            op = node.op
            for combi in itertools.combinations(node.values, 2):
                rest = [elem for elem in node.values if elem not in combi]
                testnode = ast.BinOp(combi[0], op, combi[1])
                pat = PatternMatcher(testnode, self.nbits)
                matched = pat.visit(testnode, self.patt_ast)
                if matched:
                    new_node = EvalPattern(pat.wildcards).visit(self.rep_ast)
                    new_node = ast.BoolOp(op, [new_node] + rest)
                    new_node = asttools.Unleveling().visit(new_node)
                    return new_node
        return self.generic_visit(node)
예제 #8
0
 def test_astform(self):
     'Tests with different types of ast'
     t1 = ast.parse("1 + 2 + 3", mode="eval").body
     t1_ref = ast.BoolOp(ast.Add(), [ast.Num(1), ast.Num(2), ast.Num(3)])
     t2 = ast.parse("1 + 2 + 3", mode="eval")
     t3 = ast.parse("1 + 2 + 3").body[0]
     tests = [(t1, t1_ref), (t2, ast.Expression(t1_ref)),
              (t3, ast.Expr(t1_ref))]
     for test, ref in tests:
         ltest = Flattening().visit(test)
         self.assertTrue(Comparator().visit(ltest, ref))
예제 #9
0
 def make_Iterator(self, gen):
     if gen.ifs:
         ldFilter = ast.Lambda(
             ast.arguments([ast.Name(gen.target.id, ast.Param())],
                           None, None, []), ast.BoolOp(ast.And(), gen.ifs))
         ifilterName = ast.Attribute(
             value=ast.Name(id='itertools', ctx=ast.Load()),
             attr='ifilter', ctx=ast.Load())
         return ast.Call(ifilterName, [ldFilter, gen.iter], [], None, None)
     else:
         return gen.iter
 def __or__(self, other) -> Column:
     ''' Bitwise and becomes a logical and. '''
     self._test_for_extension('operator or')
     from .utils import _term_to_ast
     return Column(
         type(bool),
         ast.BoolOp(op=ast.Or(),
                    values=[
                        ast.Name('p', ctx=ast.Load()),
                        _term_to_ast(other, self)
                    ]))
예제 #11
0
 def stop_iteration(node):
     cmp_break = ast.Compare(left=mk_name(self.flag_id),
                             ops=[ast.Eq()],
                             comparators=[mk_str(self.BREAK)])
     cmp_return = ast.Compare(left=mk_name(self.flag_id),
                              ops=[ast.Eq()],
                              comparators=[mk_str(self.RETURN)])
     test = ast.BoolOp(op=ast.Or(), values=[cmp_break, cmp_return])
     break_stmt = ast.Break()
     ifstmt = ast.If(test=test, body=[break_stmt], orelse=[])
     node.body.append(ifstmt)
예제 #12
0
    def _dnf(self, node):
        if type(node) != ast.BoolOp:
            return node

        values = [self._dnf(child) for child in node.values]

        if type(node.op) == ast.Or:
            return ast.BoolOp(op=ast.Or(), values=values)

        for index, value in enumerate(values):
            if (type(value) == ast.BoolOp) and (type(value.op) == ast.Or):
                maxterm = values[index]
                values = values[:index] + values[index + 1:]
                values = [
                    ast.BoolOp(op=ast.And(), values=[v] + values)
                    for v in maxterm.values
                ]
                return self._dnf(ast.BoolOp(op=ast.Or(), values=values))

        return node
예제 #13
0
    def gen_attr_check(self, node, attr_name):
        """Check if 'attr_name' is allowed on the object in node.

        It generates (_getattr_(node, attr_name) and node).
        """

        call_getattr = ast.Call(func=ast.Name('_getattr_', ast.Load()),
                                args=[node, ast.Str(attr_name)],
                                keywords=[])

        return ast.BoolOp(op=ast.And(), values=[call_getattr, node])
예제 #14
0
    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
예제 #15
0
 def parse_bool_op(self, node, operator):
     values = []
     for child in node:
         rule = self.parse_rule_node(child)
         if rule:
             values.append(rule)
     num_values = len(values)
     if num_values > 1:
         return ast.BoolOp(operator, values)
     elif num_values == 1:
         return values[0]
     return None
예제 #16
0
def __parseBoolOp(node, operator):
    values = []
    for child in _iter_children(node):
        rule = __parseRuleNode(child)
        if rule:
            values.append(rule)
    num_values = len(values)
    if num_values > 1:
        return ast.BoolOp(operator, values)
    elif num_values == 1:
        return values[0]
    return None
예제 #17
0
    def mutate(self, node, idx):
        """Replace AND with OR."""
        # replace all occurences of And()
        # A and B and C -> A or B or C
        node.op = ast.Or()

        # or replace an operator somewhere in the middle
        # of the expression
        if idx and len(node.values) > 2:
            left = node.values[:idx]
            if len(left) > 1:
                left = [ast.BoolOp(op=ast.And(), values=left)]

            right = node.values[idx:]
            if len(right) > 1:
                right = [ast.BoolOp(op=ast.And(), values=right)]

            node.values = []
            node.values.extend(left)
            node.values.extend(right)

        return node
예제 #18
0
파일: asttools.py 프로젝트: wellcomez/sspam
    def visit_BoolOp(self, node):
        'A custom BoolOp can be used in leveled AST'
        if type(node.op) not in (ast.Add, ast.Mult,
                                 ast.BitXor, ast.BitAnd, ast.BitOr):
            return self.generic_visit(node)
        # get constant parts of node:
        list_cste = [child for child in node.values
                     if isinstance(child, ast.Num)]
        if len(list_cste) < 2:
            return self.generic_visit(node)
        rest_values = [n for n in node.values if n not in list_cste]
        fake_node = Unleveling().visit(ast.BoolOp(node.op, list_cste))
        fake_node = ast.Expression(fake_node)
        ast.fix_missing_locations(fake_node)
        code = compile(fake_node, '<constant folding>', 'eval')
        obj_env = globals().copy()
        exec code in obj_env
        value = eval(code, obj_env)

        new_node = ast.Num(value)
        rest_values.append(new_node)
        return ast.BoolOp(node.op, rest_values)
    def visit_Where_of_Where(self, parent, filter):
        '''
        seq.Where(x: f(x)).Where(x: g(x))
        => Where(Where(seq, x: f(x)), y: g(y))
        is turned into
        seq.Where(x: f(x) and g(y))
        => Where(seq, x: f(x) and g(y))
        '''
        func_f = parent.filter
        func_g = filter

        arg = arg_name()
        return self.visit(Where(parent.source, lambda_build(arg, ast.BoolOp(ast.And(), [lambda_call(arg, func_f), lambda_call(arg, func_g)]))))
예제 #20
0
 def test_withUnaryOp(self):
     'Test with UnaryOp involved'
     tests = [("5 + (-(6 + 2)) + 3",
               ast.BoolOp(ast.Add(),
                          [ast.Num(5),
                           ast.UnaryOp(ast.USub(), ast.BinOp(ast.Num(6),
                                                             ast.Add(),
                                                             ast.Num(2))),
                           ast.Num(3)]))]
     for teststring, ref_ast in tests:
         test_ast = ast.parse(teststring, mode="eval").body
         test_ast = asttools.LevelOperators(ast.Add).visit(test_ast)
         self.assertTrue(asttools.Comparator().visit(test_ast, ref_ast))
예제 #21
0
    def visit_ListComp(self, node):
        """
        Rewrite list comprehensions to the equivalent for loops.

        AST syntax:

            ListComp(expr elt, comprehension* generators)
            comprehension = (expr target, expr iter, expr* ifs)

            'ifs' represent a chain of ANDs
        """
        assert len(node.generators) > 0

        # Create innermost body, i.e. list.append(expr)
        # TODO: size hint for PyList_New
        list_create = ast.List(elts=[], ctx=ast.Load())
        list_create.type = typesystem.object_  # typesystem.list_()
        list_create = nodes.CloneableNode(list_create)
        list_value = nodes.CloneNode(list_create)
        list_append = ast.Attribute(list_value, "append", ast.Load())
        append_call = ast.Call(func=list_append,
                               args=[node.elt],
                               keywords=[],
                               starargs=None,
                               kwargs=None)

        # Build up the loops from inwards to outwards
        body = append_call
        for comprehension in reversed(node.generators):
            # Hanlde the 'if' clause
            ifs = comprehension.ifs
            if len(ifs) > 1:
                make_boolop = lambda op1_op2: ast.BoolOp(op=ast.And(),
                                                         values=op1_op2)
                if_test = reduce(make_boolop, ifs)
            elif len(ifs) == 1:
                if_test, = ifs
            else:
                if_test = None

            if if_test is not None:
                body = ast.If(test=if_test, body=[body], orelse=[])

            # Wrap list.append() call or inner loops
            body = ast.For(target=comprehension.target,
                           iter=comprehension.iter,
                           body=[body],
                           orelse=[])

        expr = nodes.ExpressionNode(stmts=[list_create, body], expr=list_value)
        return self.visit(expr)
예제 #22
0
    def single_compare(self, node):
        rhs = node.comparators[0]

        if is_obj(node.left.type):
            node = self.single_compare_objects(node)

        elif node.left.type.is_pointer and rhs.type.is_pointer:
            # Coerce pointers to integer values before comparing
            node.left = nodes.CoercionNode(node.left, Py_uintptr_t)
            node.comparators = [nodes.CoercionNode(rhs, Py_uintptr_t)]

        elif node.left.type.is_complex and rhs.type.is_complex:
            real1, imag1 = extract(node.left)
            real2, imag2 = extract(rhs)
            op = type(node.ops[0])
            if op == ast.Eq:
                lhs = compare(real1, ast.Eq(), real2)
                rhs = compare(imag1, ast.Eq(), imag2)
                result = ast.BoolOp(ast.And(), [lhs, rhs])
            elif op == ast.NotEq:
                lhs = compare(real1, ast.NotEq(), real2)
                rhs = compare(imag1, ast.NotEq(), imag2)
                result = ast.BoolOp(ast.Or(), [lhs, rhs])
            else:
                raise NotImplementedError("ordered comparisons are not "
                                          "implemented for complex numbers")
            node = nodes.typednode(result, bool_)

        elif node.left.type.is_string and rhs.type.is_string:
            node.left = nodes.CoercionNode(node.left, object_)
            node.comparators = [nodes.CoercionNode(rhs, object_)]
            return self.single_compare(node)

        elif node.left.type.is_complex and rhs.type.is_datetime:
            raise error.NumbaError(node,
                                   "datetime comparisons not yet implemented")

        return node
예제 #23
0
 def invert(self, node: Type[ast.AST]) -> Type[ast.AST]:
     if type(node) == ast.Compare:
         if len(node.ops) == 1:
             return ast.Compare(
                 left=node.left,
                 ops=[self.invertComparators[type(node.ops[0])]()],
                 comparators=node.comparators)
         else:
             tmpNode = ast.BoolOp(op=ast.And(),
                                  values=[
                                      ast.Compare(
                                          left=node.left,
                                          ops=[node.ops[0]],
                                          comparators=[node.comparators[0]])
                                  ])
             for i in range(0, len(node.ops) - 1):
                 tmpNode.values.append(
                     ast.Compare(left=node.comparators[i],
                                 ops=[node.ops[i + 1]],
                                 comparators=[node.comparators[i + 1]]))
             return self.invert(tmpNode)
     elif isinstance(node, ast.BinOp) and type(
             node.op) in self.invertComparators:
         return ast.BinOp(node.left,
                          self.invertComparators[type(node.op)](),
                          node.right)
     elif type(node) == ast.NameConstant and type(node.value) == bool:
         return ast.NameConstant(value=not node.value)
     elif type(node) == ast.BoolOp:
         return ast.BoolOp(values=[self.invert(x) for x in node.values],
                           op={
                               ast.And: ast.Or(),
                               ast.Or: ast.And()
                           }.get(type(node.op)))
     elif type(node) == ast.UnaryOp:
         return self.UnaryopInvert(node)
     else:
         return ast.UnaryOp(op=ast.Not(), operand=node)
예제 #24
0
 def test_differentops(self):
     'Test with other types of operators'
     tests = [
         ("(3 & 5 & 6)",
          ast.BoolOp(
              ast.BitAnd(),
              [ast.Num(3), ast.Num(5), ast.Num(6)])),
         ("(1 ^ 2 ^ 3) - 4",
          ast.BinOp(
              ast.BoolOp(ast.BitXor(),
                         [ast.Num(1), ast.Num(2),
                          ast.Num(3)]), ast.Add(),
              ast.BinOp(ast.Num(-1), ast.Mult(), ast.Num(4)))),
         ("((1 + 2 + 3) & (4 + 5))",
          ast.BinOp(
              ast.BoolOp(ast.Add(),
                         [ast.Num(1), ast.Num(2),
                          ast.Num(3)]), ast.BitAnd(),
              ast.BinOp(ast.Num(4), ast.Add(), ast.Num(5)))),
         ("(1 & 2 & 3) - (4 & 5)",
          ast.BinOp(
              ast.BoolOp(ast.BitAnd(),
                         [ast.Num(1), ast.Num(2),
                          ast.Num(3)]), ast.Add(),
              ast.BinOp(ast.Num(-1), ast.Mult(),
                        ast.BinOp(ast.Num(4), ast.BitAnd(), ast.Num(5))))),
         ("(1 & 2 & 3) << (4 & 5)",
          ast.BinOp(
              ast.BoolOp(ast.BitAnd(),
                         [ast.Num(1), ast.Num(2),
                          ast.Num(3)]), ast.LShift(),
              ast.BinOp(ast.Num(4), ast.BitAnd(), ast.Num(5))))
     ]
     for teststring, ref_ast in tests:
         test_ast = ast.parse(teststring, mode="eval").body
         test_ast = pre_processing.all_preprocessings(test_ast)
         test_ast = Flattening().visit(test_ast)
         self.assertTrue(Comparator().visit(test_ast, ref_ast))
예제 #25
0
파일: ddl.py 프로젝트: zzl200012/railgun
def p_or_test(p):
    '''or_test : and_test
			| or_test TAG_OR and_test'''

    if len(p) == 2:
        p[0] = p[1]

    else:
        p[0] = ast.BoolOp(op=ast.Or(),
                          values=[p[1], p[3]],
                          lineno=p[1].lineno,
                          col_offset=p[1].col_offset)

    return
예제 #26
0
 def visit_While(self, node):
     if not self.is_body_covered(node.body):
         test = ast.BoolOp(op=ast.Or(),
                           values=[node.test,
                                   ast.Name(id='True')])
         body = [ast.copy_location(ast.Pass(), node.body[0])]
         if_ = ast.If(test=test, body=body, orelse=[])
         # This is a workaround on a pasta bug
         # TODO remove when is is fixed
         if_.__pasta__ = {'prefix': node.__pasta__['prefix']}
         return if_
     elif node.orelse and not self.is_body_covered(node.orelse):
         node.orelse = []
     return super(LoopRemover, self).generic_visit(node)
예제 #27
0
 def visit_Compare(self, node):
     self.generic_visit(node)
     if len(node.ops) == 1:
         return node
     else:
         list_compare = []
         left = node.left
         for op, comparator in zip(node.ops, node.comparators):
             compare = ast.Compare(left=left,
                                   ops=[op],
                                   comparators=[comparator])
             list_compare.append(compare)
             left = comparator
         return ast.BoolOp(op=ast.And(), values=list_compare)
예제 #28
0
파일: ddl.py 프로젝트: zzl200012/railgun
def p_and_test(p):
    '''and_test : not_test
			| and_test TAG_AND not_test'''

    if len(p) == 2:
        p[0] = p[1]

    else:
        p[0] = ast.BoolOp(op=ast.And(),
                          values=[p[1], p[3]],
                          lineno=p[1].lineno,
                          col_offset=p[1].col_offset)

    return
예제 #29
0
def merge_exitcases(exit1, exit2):
    """
    Merge the exitcases of two Links.
    Args:
        exit1: The exitcase of a Link object.
        exit2: Another exitcase to merge with exit1.
    Returns:
        The merged exitcases.
    """
    if exit1:
        if exit2:
            return ast.BoolOp(ast.And(), values=[exit1, exit2])
        return exit1
    return exit2
예제 #30
0
    def visit_ListComp(self, node):
        """Generate a curried lambda function

        [x + y for x, y in [[1, 4], [2, 5], [3, 6]]]

        becomes

        [[1, 4], [2, 5], [3, 6]]].map(([x, y]) => x + y)
        """
        try:
            generator, = node.generators
        except ValueError:
            raise NotImplementedError(
                'Only single loop comprehensions are allowed'
            )

        names = find_names(generator.target)
        argslist = [ast.arg(arg=name.id, annotation=None) for name in names]
        if len(names) <= 1:
            signature = ast.arguments(
                args=argslist,
                vararg=None,
                kwonlyargs=[],
                kw_defaults=[],
                kwarg=None,
                defaults=[],
            )
        else:
            signature = ast.List(elts=argslist, ctx=ast.Load())

        array = generator.iter
        lam_sig = functools.partial(ast.Lambda, args=signature)

        filters = generator.ifs
        if filters:
            filt = ast.BoolOp(op=ast.And(), values=filters)
            # array.filter
            method = ast.Attribute(value=array, attr='filter', ctx=ast.Load())
            # array.filter(func)
            array = ast.Call(
                func=method, args=[lam_sig(body=filt)], keywords=[]
            )

        method = ast.Attribute(value=array, attr='map', ctx=ast.Load())
        mapped = ast.Call(
            func=method, args=[lam_sig(body=node.elt)], keywords=[]
        )
        result = self.visit(mapped)
        return result