コード例 #1
0
def analyze_tree(tree, category):

    if isinstance(tree, list):
        subtrees = [analyze_tree(subtree, category) for subtree in tree]
        return If(eparse('True'), subtrees, [])

    elif isinstance(tree, dict):
        if len(tree) != 1:
            raise ValueError('len(dict) != 1')
        rule, subtree = tree.items()[0]
        r = analyze_rule(rule)
        if isinstance(r, AST):
            test = r
            return If(test, [analyze_tree(subtree, category)], [])
        else:
            dueling_category_check(category, r)
            category = r
            return analyze_tree(subtree, category)

    else:
        rule = tree
        r = analyze_rule(rule)
        if isinstance(r, AST):
            test = r
            if category is None:
                raise ValueError('bottomed out without category')
            return If(test, [Return(Str(category))], [])
        else:
            dueling_category_check(category, r)
            category = r
            return Return(Str(category))
コード例 #2
0
ファイル: letparser.py プロジェクト: dhilst/lampy
    def body_helper(self, body):
        from ast import expr, Return

        # place return in the last expression of body
        if isinstance(body, expr):
            body = [Return(body)]
        elif isinstance(body, list) and not isinstance(body[-1], Return):
            body[-1] = Return(body[-1])

        return body
コード例 #3
0
ファイル: code.py プロジェクト: pierky/exabgp
 def _if_pattern(self, pattern):
     self.imported.add('re')
     # fix known ietf regex use
     pattern = pattern.replace('\\p{N}\\p{L}', '\\w')
     return [
         If(
             test=UnaryOp(
                 op=Not(),
                 operand=Call(
                     func=Attribute(
                         value=Name(id='re', ctx=Load()),
                         attr='match',
                         ctx=Load(),
                     ),
                     args=[
                         Constant(value=pattern, kind=None),
                         Name(id='value', ctx=Load()),
                         Attribute(
                             value=Name(id='re', ctx=Load()),
                             attr='UNICODE',
                             ctx=Load(),
                         ),
                     ],
                     keywords=[],
                 ),
             ),
             body=[
                 Return(value=Constant(value=False, kind=None), ),
             ],
             orelse=[],
         ),
     ]
コード例 #4
0
ファイル: py_converter.py プロジェクト: jiajuns/tvm
    def visit_let(self, letexp: Expr):
        # To properly account for scoping and ensure that the entire node produces an expression,
        # we translate the let binding as a function that we call with the value we intend to bind.
        # Yes, this is somewhat ugly.
        """
        let var = value in body
        =======================
        def let_thunk(var):
            return body
        let_thunk(value)
        """
        bind_body, bind_defs = self.visit(letexp.body)

        func_name = self.generate_function_name("_let_func")
        binding_func = self.create_def(func_name,
                                       [self.get_var_name(letexp.var)],
                                       bind_defs + [Return(bind_body)])

        # we call the binding func with the intended value for the bound variable

        # special case: if the value is a function literal, we must ensure it can be
        # recursive by naming it after the var
        if isinstance(letexp.value, Function):
            value_def, value_name = self.convert_func_node(
                letexp.value, letexp.var)
            return (
                self.create_call(func_name, [Name(value_name, Load())]),
                [value_def, binding_func],
            )

        value_body, value_defs = self.visit(letexp.value)
        value_defs.append(binding_func)
        binding_call = self.create_call(func_name, [value_body])
        return (binding_call, value_defs)
コード例 #5
0
ファイル: code.py プロジェクト: pierky/exabgp
 def _if_gt(value):
     if value >= 0:
         comparators = [Constant(value=value, kind=None)]
     else:
         comparators = [
             UnaryOp(
                 op=USub(),
                 operand=Constant(value=abs(value), kind=None),
             ),
         ]
     return [
         If(
             test=Compare(
                 left=Call(
                     func=Name(id='int', ctx=Load()),
                     args=[Name(id='value', ctx=Load())],
                     keywords=[],
                 ),
                 ops=[Gt()],
                 comparators=comparators,
             ),
             body=[
                 Return(value=Constant(value=False, kind=None), ),
             ],
             orelse=[],
         )
     ]
コード例 #6
0
ファイル: py_converter.py プロジェクト: jiajuns/tvm
    def visit_match(self, match: Expr):
        """For matches, we wrap the entire expression in a thunk
        because it is easiest to implement them using if statements.
        For each clause, we generate a function that checks if the
        pattern matches. If yes, we call a function that assigns
        the variables appropriately and invokes the clause body."""
        data, defs = self.visit(match.data)
        data_var = self.generate_var_name("_match_data")

        # must ensure the data clause is executed exactly once
        thunk_body = [Assign([Name(data_var, Store())], data)]
        for clause in match.clauses:
            check_expr = self.create_match_check(clause.lhs,
                                                 Name(data_var, Load()))
            body_def, body_name = self.create_match_clause_body(
                clause.lhs, clause.rhs)
            defs.append(body_def)

            # equiv: if check(data): return body(data)
            thunk_body.append(
                ast.If(check_expr, [
                    Return(
                        self.create_call(body_name, [Name(data_var, Load())]))
                ], []))

        # finally if nothing matches we have a failed assert (should never happen)
        thunk_body.append(
            ast.Assert(NameConstant(False), Str("Match was not exhaustive")))

        thunk_name = self.generate_function_name("_match_thunk")
        thunk_def = self.create_def(thunk_name, [], defs + thunk_body)
        return (self.create_call(thunk_name, []), [thunk_def])
コード例 #7
0
def getter(item):
    """Construct the getter function.

    partof: #SPC-asts.getter
    """
    func_name = f"{item.var}_getter"
    self_arg = arg(arg="self", annotation=None)
    func_args = arguments(
        args=[self_arg],
        kwonlyargs=[],
        vararg=None,
        kwarg=None,
        defaults=[],
        kw_defaults=[],
    )
    inst_var = Attribute(value=Name(id="self", ctx=ast.Load()),
                         attr=f"_{item.var}",
                         ctx=ast.Load())
    ret_stmt = Return(value=inst_var)
    func_node = FunctionDef(name=func_name,
                            args=func_args,
                            body=[ret_stmt],
                            decorator_list=[],
                            returns=None)
    mod_node = Module(body=[func_node])
    return ast_to_func(mod_node, func_name)
コード例 #8
0
def getLambdaMethod(methodname, body, args_node, file, id):  # methodname = _lambda_0
    global lambdaID
    fullbody = []
    fullbody.extend(getTracers(file, args_node, id))
    fullbody.append(getScopeTracer(file, methodname, id))
    fullbody.append(
        Return(
            value=Call(
                func=Name(id='eval', ctx=Load()),
                args=[
                    Constant(value=to_source(body), kind=None),
                    Call(
                        func=Name(id='locals', ctx=Load()),
                        args=[],
                        keywords=[]),
                    Name(id=methodname + '_locals', ctx=Load())],
                keywords=[]
            )
        )
    )
    return FunctionDef(
        name=methodname + '_return',
        args=args_node,
        body=fullbody,
        decorator_list=[],
        returns=None,
        type_comment=None)
コード例 #9
0
def make_function(name, args):
    my_args = arguments(
        args=[arg(arg="self", annotation=None)] + [
            # XXX for arrays the name is '' (empty string)
            # which would end up being nothing in the generated
            # source file.
            arg(arg=my_arg or "arg", annotation=None) for my_arg in args
        ],
        defaults=[],
        vararg=None,
        kwonlyargs=[],
        kw_defaults=[],
        kwarg=None,
    )
    my_body = [
        Return(value=Call(
            func=Attribute(
                value=Attribute(
                    value=Attribute(value=Name(id="self"), attr="_contract"),
                    attr="functions",
                ),
                attr=name,
            ),
            args=[Name(id=my_arg or "arg") for my_arg in args],
            keywords=[],
        ))
    ]

    return FunctionDef(name=name,
                       args=my_args,
                       body=my_body,
                       decorator_list=[])
コード例 #10
0
    def visit_FunctionDef(self, node: FunctionDef) -> FunctionDef:
        self.generic_visit(node)

        if len(node.body) and isinstance(node.body[-1], Expr):
            node.body[-1] = Return(value=node.body[-1].value)
            fix_missing_locations(node.body[-1])

        return node
コード例 #11
0
 def add_implicit_bare_return(tree, **kw):
     if type(tree) in (FunctionDef, AsyncFunctionDef):
         if type(tree.body[-1]) is not Return:
             tree.body.append(
                 Return(
                     value=None,  # bare "return"
                     lineno=tree.lineno,
                     col_offset=tree.col_offset))
     return tree
コード例 #12
0
    def handle_when(self, when, *others):
        test, body = when.get_source_expressions()
        if others:
            if others[0].__class__.__name__ == "When":
                orelse = [self.handle_when(*others)]
            else:
                # Can we ever have other expressions after the default?
                orelse = [
                    Return(value=self.build_expression(others[0]), **self.file)
                ]
        else:
            orelse = []

        return If(
            test=self.build_expression(test),
            body=[Return(value=self.build_expression(body), **self.file)],
            orelse=orelse,
            **self.file,
        )
コード例 #13
0
def _make_call_meth(body, return_type, param_names):
    """
    Construct a `__call__` method from the provided `body`

    :param body: The body, probably from a FunctionDef.body
    :type body: ```List[AST]```

    :param return_type: The return type of the parent symbol (probably class). Used to fill in `__call__` return.
    :type return_type: ```Optional[str]```

    :param param_names: Container of AST `id`s to match for rename
    :type param_names: ```Optional[Iterator[str]]```

    :return: Internal function for `__call__`
    :rtype: ```FunctionDef```
    """
    body_len = len(body)
    return_ = (ast.fix_missing_locations(
        RewriteName(param_names).visit(
            Return(get_value(ast.parse(return_type[3:-3]).body[0]),
                   expr=None))) if return_type is not None
               and len(return_type) > 6 and return_type.startswith("```")
               and return_type.endswith("```") else None)
    if body_len:
        if isinstance(body[0], Expr):
            doc_str = get_value(body[0].value)
            if isinstance(doc_str, str) and body_len > 0:
                body = (body[1:] if body_len > 1 else ([
                    set_value(doc_str.replace(":cvar", ":param"))
                    if return_ is None else return_
                ] if body_len == 1 else body))
    #         elif not isinstance(body[0], Return) and return_ is not None:
    #             body.append(return_)
    # elif return_ is not None:
    #     body = [return_]

    return FunctionDef(args=arguments(
        args=[set_arg("self")],
        defaults=[],
        kw_defaults=[],
        kwarg=None,
        kwonlyargs=[],
        posonlyargs=[],
        vararg=None,
        arg=None,
    ),
                       body=body,
                       decorator_list=[],
                       name="__call__",
                       returns=None,
                       arguments_args=None,
                       identifier_name=None,
                       stmt=None,
                       lineno=None,
                       **maybe_type_comment)
コード例 #14
0
        def insert_returns(body):
            if isinstance(body[-1], Expr):
                body[-1] = Return(body[-1].value)
                fix_missing_locations(body[-1])

            if isinstance(body[-1], If):
                insert_returns(body[-1].body)
                insert_returns(body[-1].orelse)

            if isinstance(body[-1], With):
                insert_returns(body[-1].body)
コード例 #15
0
    def visit_Return(self, node):
        existing_node = self.generic_visit(node)
        value = existing_node.value
        if value is None:
            return existing_node

        return [Assign(targets=[Name(id=RESULT_NAME, ctx=Store())],
                       value=value),
                self._create_context_call('return_value',
                                          [Name(id=RESULT_NAME, ctx=Load()),
                                           Num(n=existing_node.lineno)]),
                Return(value=Name(id=RESULT_NAME, ctx=Load()))]
コード例 #16
0
 def visit_Return(self, node: ast.Return):
     with fast.location_of(node):
         node.value = fast.Call(
             func=self._emitter_ast(),
             args=[TraceEvent.after_return.to_ast(), self._get_copy_id_ast(node.value)],
             keywords=fast.kwargs(
                 ret=self._make_tuple_event_for(
                     self.visit(node.value),
                     TraceEvent.before_return,
                     orig_node_id=id(node.value),
                 ),
             ),
         )
     return node
コード例 #17
0
    def __init__(self, function):
        expression = function(None)
        if getattr(expression, "copy", None):
            expression = expression.copy()
        func_code = getattr(function, "__code__", None) or function.func_code
        self.file = {
            "lineno": func_code.co_firstlineno,
            "filename": func_code.co_filename,
            "col_offset": 0,
            "ctx": Load(),
        }
        self.file_store = dict(self.file, ctx=Store())
        self.expression = expression
        body = self.build_expression(expression)
        if isinstance(body, list):
            pass
        elif not isinstance(body, stmt):
            body = [Return(value=body, **self.file)]
        else:
            body = [body]

        self.ast = Module(
            body=[
                FunctionDef(
                    name=func_code.co_name,
                    args=arguments(
                        args=[arg(arg="self", annotation=None)
                              ],  # function.func_code.co_varnames
                        defaults=[],
                        vararg=None,
                        kwarg=None,
                        kwonlyargs=[],
                        kw_defaults=[],
                        posonlyargs=[],
                    ),
                    kwarg=[],
                    kw_defaults=[],
                    vararg=[],
                    kwonlyargs=[],
                    body=body,
                    decorator_list=[],
                ),
            ],
            type_ignores=[],
            **self.file,
        )
        fix_missing_locations(self.ast)
        self.code = compile(self.ast,
                            mode="exec",
                            filename=self.file["filename"])
コード例 #18
0
ファイル: py_converter.py プロジェクト: jiajuns/tvm
    def convert_func_node(self, func: Function, name_var=None):
        """Converts the given Relay function into a Python function, with
        special for named functions (locally or globally)"""
        if name_var is None:
            func_name = self.generate_function_name("_anon_func")
        if isinstance(name_var, GlobalVar):
            func_name = str(name_var.name_hint)
        if isinstance(name_var, Var):
            func_name = self.get_var_name(name_var)

        var_names = [self.get_var_name(var) for var in func.params]
        body, defs = self.visit(func.body)
        ret = self.create_def(func_name, var_names, defs + [Return(body)])
        return (ret, func_name)
コード例 #19
0
ファイル: py_converter.py プロジェクト: whn09/incubator-tvm
 def visit_ref_write(self, write: Expr):
     """For writing refs, we wrap the update in a thunk
     (returning an empty tuple to match Relay's semantics)
     that we execute at the right time. This ensures such assignments
     can be properly nested, since assignments are statements
     in Python but expressions in Relay"""
     ref, ref_defs = self.visit(write.ref)
     val, val_defs = self.visit(write.value)
     thunk_name = self.generate_function_name('_ref_write_thunk')
     thunk = self.create_def(
         thunk_name, [], ref_defs + val_defs + [
             Assign([ast.Attribute(ref, 'value', Store())], val),
             Return(self.create_call('_container.tuple_object', []))
         ])
     return (self.create_call(thunk_name, []), [thunk])
コード例 #20
0
ファイル: debugger.py プロジェクト: legalian/xaxiom
		def visit_Return(self,node:ast.Return):
			if self.hot == None or (not self.hotHasReturnCheck and self.funcNames[self.hot] not in self.exitpatterns): return node
			# print("Assign: ",self.funcNames[self.hot])
			sin = [
				Assign(targets=[Name(id='_dbg_ret_var', ctx=Store())], value=node.value),
				Return(value=Name(id='_dbg_ret_var', ctx=Load()))
			]
			if self.hotHasReturnCheck:
				expattern = self.funcparams[self.hot]
				sin.insert(1,Expr(value=Call(func=Name(id='_dbgExit', ctx=Load()), args=[Name(id=pn+'_dbg_str_var_'+str(self.hot),ctx=Load()) for pn in expattern]+[Name(id='_dbg_ret_var', ctx=Load())], keywords=[])))
			if self.funcNames[self.hot] in self.exitpatterns:
				expattern = self.exitpatterns[self.funcNames[self.hot]]
				sin.insert(1,Expr(value=Call(func=Name(id='_dbgExit_'+self.funcNames[self.hot],ctx=Load()), args=[Name(id=pn+'_dbg_str_var_'+str(self.hot),ctx=Load()) for pn in expattern]+[Name(id='_dbg_ret_var', ctx=Load())], keywords=[])))
			for s in sin:
				ast.copy_location(s, node)
				ast.fix_missing_locations(s)
			return sin
コード例 #21
0
def test():
    """
    Test Function 
    """
    stmt = Program([
        Function("f", [], [
            For("i", 1, 10, 1, [
                Assign("x", IntValue(3)),
                Assign("x", IntValue(4)),
                IfThenElse(BoolValue(True), []),
                While(BoolValue(True), [Return(IntValue(3))]),
                Assign("x", IntValue(5))
            ])
        ]),
        Function("g", [], [Assign("x", IntValue(3))]),
        Assign("x", IntValue(1))
    ])
    nodes, edges = gen_cfg_main(stmt)
    gen_dot(nodes, edges)
コード例 #22
0
def _tco_transform_return(tree, *, known_ecs, transform_retexpr, **kw):
    if type(tree) is Return:
        non = q[None]
        non = copy_location(non, tree)
        value = tree.value or non  # return --> return None  (bare return has value=None in the AST)
        if not isec(value, known_ecs):
            return Return(value=transform_retexpr(value, known_ecs))
        else:
            # An ec call already escapes, so the return is redundant.
            #
            # If someone writes "return ec(...)" in a "with continuations" block,
            # this cleans up the code, since eliminating the "return" allows us
            # to omit a redundant "let".
            return Expr(value=value)  # return ec(...) --> ec(...)
    elif isec(tree, known_ecs):  # TCO the arg of an ec(...) call
        if len(tree.args) > 1:
            assert False, "expected exactly one argument for escape continuation"  # pragma: no cover
        tree.args[0] = transform_retexpr(tree.args[0], known_ecs)
    return tree
コード例 #23
0
    def create_match_clause_body(self, pattern: Pattern, body: Expr):
        """Given a match clause pattern and a clause body,
        generates a Python function that when called with an ADT
        that matches the pattern, returns the result of evaluating
        the clause body. This function returns a function definition
        and the name of the generated function."""

        def collect_var_assignments(pat, val):
            """This helper function ensures that the pattern is used to
            properly assign all subfields of the given AST for use
            in the clause body

            E.g., for PatternConstructor(A, PatternVar(v), PatternWildcard(),
            PatternConstructor(B, PatternVar(w)))
            we would want to have
            v = a.fields[0]
            w = a.fields[2].fields[0]
            """
            if isinstance(pat, relay.PatternWildcard):
                return []
            if isinstance(pat, relay.PatternVar):
                return [Assign([self.include_var(pat.var, assign=True)], val)]
            # constructor pattern: assign each field of the value
            # based on subpatterns
            assignments = []
            for i in range(len(pat.patterns)):
                # we want the assignments for val.fields[i]
                field = ast.Subscript(
                    ast.Attribute(val, "fields", Load()), ast.Index(Num(i)), Load()
                )
                assignments += collect_var_assignments(pat.patterns[i], field)
            return assignments

        func_name = self.generate_function_name("_match_clause_body")
        arg_name = self.generate_var_name("_match_clause_body")

        clause_body, defs = self.visit(body)
        assignments = collect_var_assignments(pattern, Name(arg_name, Load()))

        func_def = self.create_def(
            func_name, [arg_name], defs + assignments + [Return(clause_body)]
        )
        return (func_def, func_name)
コード例 #24
0
ファイル: code.py プロジェクト: pierky/exabgp
    def _union(self, node):
        values = []
        generated = []

        for union in node:
            for what, sub in union.items():
                if ':' in what:
                    if what in generated:
                        # only generate any imported function once
                        continue
                    generated.append(what)
                    name = what
                    yield self._type(what, name, sub)
                else:
                    # this is a build_in type (and my have been refined)
                    # therefore generate one function per type
                    name = self._unique(what)
                    yield self._function(name, self._type(what, what, sub))

                values += [
                    UnaryOp(
                        op=Not(),
                        operand=Call(
                            func=Name(id=self._python_name(name), ctx=Load()),
                            args=[Name(id='value', ctx=Load())],
                            keywords=[],
                        ),
                    ),
                ]

        yield [
            If(
                test=BoolOp(
                    op=And(),
                    values=values,
                ),
                body=[
                    Return(value=Constant(value=False, kind=None), ),
                ],
                orelse=[],
            ),
        ]
コード例 #25
0
 def transform_tailstmt(tree):
     # TODO: For/AsyncFor/While?
     if type(tree) is If:
         tree.body[-1] = transform_tailstmt(tree.body[-1])
         if tree.orelse:
             tree.orelse[-1] = transform_tailstmt(tree.orelse[-1])
     elif type(tree) in (With, AsyncWith):
         tree.body[-1] = transform_tailstmt(tree.body[-1])
     elif type(tree) is Try:
         # We don't care about finalbody; typically used for unwinding only.
         if tree.orelse:  # tail position is in else clause if present
             tree.orelse[-1] = transform_tailstmt(tree.orelse[-1])
         else:  # tail position is in the body of the "try"
             tree.body[-1] = transform_tailstmt(tree.body[-1])
         # additionally, tail position is in each "except" handler
         for handler in tree.handlers:
             handler.body[-1] = transform_tailstmt(handler.body[-1])
     elif type(tree) is Expr:
         tree = Return(value=tree.value)
     return tree
コード例 #26
0
ファイル: code.py プロジェクト: pierky/exabgp
 def _if_digit():
     return [
         If(
             test=UnaryOp(
                 op=Not(),
                 operand=Call(
                     func=Attribute(
                         value=Name(id='value', ctx=Load()),
                         attr='isdigit',
                         ctx=Load(),
                     ),
                     args=[],
                     keywords=[],
                 ),
             ),
             body=[
                 Return(value=Constant(value=False, kind=None), ),
             ],
             orelse=[],
         )
     ]
コード例 #27
0
def define_replace_method(methodname, args, body):
    """
    This generates an ast for a generic function that takes a list parameters
    and returns a generic body
    used to construct something like this

        def <methodname>(<arges>):
            return Module(body=<body>)

    The args parameters are like this :
        [ Name(id='<argname>', ctx=Param()), .... ]
    """

    return Module(  # top module
        body=[
            FunctionDef(  # new function
                name=methodname,
                args=arguments(args=args, vararg=None, kwarg=None,
                               defaults=[]),
                body=[Return(value=body)],
                decorator_list=[])  # module2
        ])  # module
コード例 #28
0
def getLocalsFunction(var_name):  # _lambda_0
    return FunctionDef(
        name=var_name,
        args=arguments(
            posonlyargs=[],
            args=[arg(arg='locls', annotation=None, type_comment=None)],
            vararg=None,
            kwonlyargs=[],
            kw_defaults=[],
            kwarg=None,
            defaults=[]),
        body=[
            Global(names=[var_name + '_locals']),
            Assign(
                targets=[Name(id=var_name + '_locals', ctx=Store())],
                value=Name(id='locls', ctx=Load()),
                type_comment=None),
            Return(value=Name(id=var_name + '_return', ctx=Load()))
        ],
        decorator_list=[],
        returns=None,
        type_comment=None)
コード例 #29
0
ファイル: code.py プロジェクト: pierky/exabgp
 def _if_length(self, minimum, maximum):
     return [
         If(
             test=Compare(
                 left=Constant(value=int(minimum), kind=None),
                 ops=[
                     Gt(),
                     Gt(),
                 ],
                 comparators=[
                     Call(
                         func=Name(id='len', ctx=Load()),
                         args=[Name(id='value', ctx=Load())],
                         keywords=[],
                     ),
                     Constant(value=int(maximum), kind=None),
                 ],
             ),
             body=[
                 Return(value=Constant(value=False, kind=None), ),
             ],
             orelse=[],
         ),
     ]
コード例 #30
0
ファイル: tracer.py プロジェクト: Jongy/pycodetracer
 def visit_Return(self, n: Return):
     """
     * Decrement the depth before exiting. We have to save the returned value into a temporary,
       and only then decrement; otherwise, if the return value itself is a Call, we lose the
       depth.
     """
     var = Assign([Name(self._RETURN_VAR, Store())], n.value)
     n.value = Name(self._RETURN_VAR, Load())
     return self._fix_location_all(
         [
             var,
             self._make_print(
                 [
                     self._parse_fstring(
                         colored(f"return {{{self._RETURN_VAR}}}",
                                 self.RETURN_COLOR))
                 ],
                 "< ",
             ),
             self._decrement_depth(),
             n,
         ],
         n,
     )