Exemplo n.º 1
0
def py_transform(name, args, machine):
    """
    transform a generator function into a state machine

    def generator(args):
        yield x

    << into >>

    def generator(args):
        class iterator:
            def __init__(self): self.state = 0
            def __iter__(self): return iterator()
            def __next__(self):
                # iterator body
                if self.state==0:
                    return x

       return iterator()
    """
    # FunctionDef(identifier name, arguments args, stmt* body, expr* decorator_list, expr? returns)
    # ClassDef(identifier name, expr* bases, keyword* keywords, expr? starargs, expr? kwargs, stmt* body, expr *decorator_list)

    # 	arguments = (arg* args, identifier? vararg, expr? varargannotation, arg* kwonlyargs, identifier? kwarg,
    #                expr? kwargannotation, expr* defaults, expr* kw_defaults)

    #    arg = (identifier arg, expr? annotation)

    if isinstance(machine, ast.AST):
        return py_transform(name,args, MachineTranslator())
    else:
        body = ast.If()

        template=\
        """
        def generator():
            class iterator:
                def __init__(self): self.state = 0
                def __iter__(self): return iterator()
                def __next__(self): import body

           return iterator()
        """

        func = templated_ast(template, body=body, generator=name)
        func.args=args
        return func
Exemplo n.º 2
0
    def visit_While(self, node, scope):
        # While(expr test, stmt* body, stmt* orelse)
        if not node.orelse:
            template = """while (bool(%(test)s)) {
%(body)s
}"""
            return template % {
                "test": self.visit(node.test, PhantomScope(scope, False)),
                "body": JCompiler.indent(self.visit_stmt_list(node.body, PhantomScope(scope, True))),
            }
        else:
            # rewrite the expression
            code = """
            while True:
                if test:
                    import body
                else:
                    import orelse
                    break
            """
            transformed = templated_ast(code, test=node.test, body=node.body, orelse=node.orelse)
            return self.visit(transformed, scope)
Exemplo n.º 3
0
        def map_handler(handlers):
            # maps a catch block into the corresponding if

            # catch <Exception> <e>: <body>
            # into -->
            # if (isinstance(e$, <Exception>)): e=e$; <body>
            if not handlers:
                return ast.Pass

            first = handlers[0]
            code = ""
            code += "if isinstance(temp, exception): " if first.type else ""
            code += "var = temp; " if first.name else ""
            code += "import body; "
            code += "\nelse: import orelse; " if len(handlers) > 1 else ""

            return templated_ast(
                code,
                temp=ast.Name(id=catch_variable_name, ctx=ast.Load()),
                exception=first.type,
                var=ast.Name(id=first.name, ctx=ast.Store()),
                body=first.body,
                orelse=map_handler(handlers[1:]),
            )
Exemplo n.º 4
0
    def visit_For(self, node, scope):
        # For(expr target, expr iter, stmt* body, stmt* orelse)
        # the for statement is rewritten as follows
        code = """temp_store = iter(iterable)
while True:
    try:
        target=next(temp_load)
        import body
    except StopIteration:
        import orelse
        break
"""
        temp_iterable = JCompiler.inc_temp_var(getattr(scope, "temp_iterable", "$i"))
        for_scope = PhantomScope(scope, True, temp_iterable=temp_iterable)
        template = templated_ast(
            code,
            temp_store=ast.Name(id=temp_iterable, ctx=ast.Store()),
            temp_load=ast.Name(id=temp_iterable, ctx=ast.Load()),
            iterable=node.iter,
            target=node.target,
            body=node.body,
            orelse=node.orelse,
        )
        return self.generic_visit_list(template, for_scope)