Exemple #1
0
    def visit_FunctionDef(self, node):
        body = "\n".join([self.visit(n) for n in node.body])
        # If rewriter inserted a block, we need to terminate it with a semicolon
        if len(node.body):
            last = node.body[-1]
            if getattr(last, "make_block", False):
                body += ";"

        if (self.use_catch_test_cases and is_void_function(node)
                and node.name.startswith("test")):
            return generate_catch_test_case(node, body)

        is_python_main = getattr(node, "python_main", False)
        typenames, args = self.visit(node.args)

        args_list = []
        if len(args) and hasattr(node, "self_type"):
            # implicit this
            del typenames[0]
            del args[0]

        typedecls = []
        index = 0
        for i in range(len(args)):
            typename = typenames[i]
            arg = args[i]
            if typename == "T":
                typename = "T{0}".format(index)
                typedecls.append(typename)
                index += 1
            if is_python_main and arg in ["argv"]:
                typename = "char **"
            args_list.append(f"{typename} {arg}")

        template = "inline "
        if len(typedecls) > 0:
            typedecls_str = ", ".join([f"typename {t}" for t in typedecls])
            template = f"template <{typedecls_str}>"

        if is_python_main:
            body = (
                "pycpp::sys::argv = std::vector<std::string>(argv, argv + argc);\n"
                + body)
            template = ""

        if not is_void_function(node):
            if node.returns:
                typename = self._typename_from_annotation(node, attr="returns")
                return_type = f"{typename}"
            else:
                return_type = "auto"
        else:
            return_type = "void"

        args = ", ".join(args_list)
        funcdef = f"{template}{return_type} {node.name}({args}) {{"

        return funcdef + "\n" + body + "}\n"
Exemple #2
0
    def visit_FunctionDef(self, node):
        body = "\n".join([self.visit(n) for n in node.body])

        if (self.use_catch_test_cases and is_void_function(node)
                and node.name.startswith("test")):
            return generate_catch_test_case(node, body)

        typenames, args = self.visit(node.args)

        args_list = []
        if len(args) and hasattr(node, "self_type"):
            # implicit this
            del typenames[0]
            del args[0]

        typedecls = []
        index = 0
        for i in range(len(args)):
            typename = typenames[i]
            arg = args[i]
            if typename == "T":
                typename = "T{0}".format(index)
                typedecls.append(typename)
                index += 1
            args_list.append(f"{typename} {arg}")

        template = "inline "
        if len(typedecls) > 0:
            typedecls_str = ", ".join([f"typename {t}" for t in typedecls])
            template = f"template <{typedecls_str}>"

        return_type = "auto"
        if node.name == "main":
            template = ""
            return_type = "int"

        if not is_void_function(node):
            if node.returns:
                typename = self._typename_from_annotation(node, attr="returns")
                return_type = f"{typename}"
            else:
                return_type = "auto"
        else:
            return_type = "void"

        args = ", ".join(args_list)
        funcdef = f"{template}{return_type} {node.name}({args}) {{"
        if getattr(node, "python_main", False):
            funcdef = "\n".join([
                "int main(int argc, char ** argv) {",
                "py14::sys::argv = "
                "std::vector<std::string>(argv, argv + argc);",
            ])
        return funcdef + "\n" + body + "}\n"
Exemple #3
0
    def visit_FunctionDef(self, node):
        body = "\n".join([self.visit(n) for n in node.body])
        typenames, args = self.visit(node.args)

        if len(typenames) and typenames[0] == None and hasattr(node, "self_type"):
            typenames[0] = node.self_type

        args_list = []
        typedecls = []
        index = 0
        for i in range(len(args)):
            typename = typenames[i]
            arg = args[i]
            if typename == "T":
                typename = "T{0} any".format(index)
                typedecls.append(typename)
                index += 1
            args_list.append(f"{arg} {typename}")

        return_type = ""
        if not is_void_function(node):
            if node.returns:
                typename = self._typename_from_annotation(node, attr="returns")
                return_type = f" {typename}"
            else:
                return_type = " RT"
                typedecls.append("RT")

        template = ""
        if len(typedecls) > 0:
            template = "[{0}]".format(", ".join(typedecls))

        args = ", ".join(args_list)
        funcdef = f"func {node.name}{template}({args}){return_type} {{"
        return f"{funcdef}\n{body}}}\n\n"
Exemple #4
0
    def visit_FunctionDef(self, node) -> str:
        body = "\n".join([self.indent(self.visit(n)) for n in node.body])
        typenames, args = self.visit(node.args)

        is_python_main = getattr(node, "python_main", False)

        args_list = []
        if len(args) and hasattr(node, "self_type"):
            typenames[0] = node.self_type

        for i in range(len(args)):
            typename = typenames[i]
            arg = args[i]

            args_list.append(f"{arg}: {typename}".format(arg, typename))

        return_type = ""
        if not is_void_function(node):
            if node.returns:
                typename = self._typename_from_annotation(node, attr="returns")
                return_type = f": {typename}"
            else:
                return_type = ""

        args = ", ".join(args_list)
        funcdef = f"proc {node.name}({args}){return_type} ="
        maybe_main = ""
        if is_python_main:
            maybe_main = "\nmain()"
        return f"{funcdef}\n{body}\n{maybe_main}"
Exemple #5
0
    def visit_FunctionDef(self, node):
        body = "\n".join([self.indent(self.visit(n)) for n in node.body])
        typenames, args = self.visit(node.args)

        args_list = []
        if len(args) and hasattr(node, "self_type"):
            typenames[0] = node.self_type

        for i in range(len(args)):
            typename = typenames[i]
            arg = args[i]

            args_list.append(f"(declare-const {arg} {typename})")

        return_type = ""
        if not is_void_function(node):
            if node.returns:
                typename = self._typename_from_annotation(node, attr="returns")
                return_type = f" {typename}"
            else:
                return_type = ""

        if len(node.body) == 1 and is_ellipsis(node.body[0]):
            return self._visit_DeclareFunc(node, return_type)

        args = "\n".join(args_list)
        funcdef = f"define-fun {node.name}() {return_type}"
        return f"{args}\n({funcdef}\n{body})\n"
Exemple #6
0
    def visit_FunctionDef(self, node, async_prefix=""):
        body = "\n".join([self.visit(n) for n in node.body])
        typenames, args = self.visit(node.args)

        args_list = []
        if args and args[0] == "self":
            del typenames[0]
            del args[0]
            args_list.append("&self")

        is_python_main = getattr(node, "python_main", False)
        if is_python_main:
            self._usings.add("anyhow::Result")

        typedecls = []
        index = 0
        for i in range(len(args)):
            typename = typenames[i]
            arg = args[i]

            if typename == "T":
                typename = "T{0}".format(index)
                typedecls.append(typename)
                index += 1
            args_list.append("{0}: {1}".format(arg, typename))

        return_type = "" if not is_python_main else "-> Result<()>"
        if node.returns:
            typename = self._typename_from_annotation(node, attr="returns")
            if getattr(node.returns, "rust_needs_reference", False):
                typename = f"&{typename}"
            if getattr(node, "rust_pyresult_type", False):
                if node.no_return:
                    typename = None
                else:
                    typename = self._generic_typename_from_type_node(
                        node.returns)
                typename = map_type(typename, extension=True, return_type=True)
            if typename != "_":
                return_type = f"-> {typename}"
        else:
            if not is_void_function(node):
                return_type = "-> RT"
                typedecls.append("RT")

        template = ""
        if len(typedecls) > 0:
            template = "<{0}>".format(", ".join(typedecls))

        extension = "#[pyfunction]\n" if self.extension else ""
        args_list = ", ".join(args_list)
        funcdef = f"{extension}pub {async_prefix}fn {node.name}{template}({args_list}) {return_type}"
        return_success = (
            "Ok(())" if is_python_main else ""
        )  # TODO: generalize this to functions that return Result<T, E>
        return f"{funcdef} {{\n{body}\n {return_success}}}\n"
Exemple #7
0
    def visit_FunctionDef(self, node):
        body = "\n".join([self.visit(n) for n in node.body])
        typenames, args = self.visit(node.args)

        args_list = []
        if len(args) and hasattr(node, "self_type"):
            # implicit this
            del typenames[0]
            del args[0]

        is_python_main = getattr(node, "python_main", False)

        typedecls = []
        index = 0
        for i in range(len(args)):
            typename = typenames[i]
            arg = args[i]
            if is_python_main and arg == "argc":
                continue

            if typename == "T":
                typename = "T{0}".format(index)
                typedecls.append(typename)
                index += 1
            args_list.append(f"{typename} {arg}")

        return_type = ""
        if not is_void_function(node):
            if node.returns:
                typename = self._typename_from_annotation(node, attr="returns")
                if typename != self._default_type:
                    return_type = f"{typename}"
            if not return_type:
                return_type = "RT"
                typedecls.append("RT")

        template = ""
        if len(typedecls) > 0:
            template = "<{0}>".format(", ".join(typedecls))

        args = ", ".join(args_list)
        funcdef = f"{return_type} {node.name}{template}({args}) {{"
        return funcdef + "\n" + body + "}\n\n"
Exemple #8
0
    def visit_FunctionDef(self, node):
        body = "\n".join([self.visit(n) for n in node.body])
        typenames, args = self.visit(node.args)

        args_list = []
        typedecls = []
        index = 0

        is_python_main = getattr(node, "python_main", False)

        if len(typenames) and typenames[0] == None and hasattr(
                node, "self_type"):
            typenames[0] = node.self_type

        for i in range(len(args)):
            typename = typenames[i]
            arg = args[i]
            if typename == "T":
                typename = "T{0}".format(index)
                typedecls.append(typename)
                index += 1
            args_list.append("{0}::{1}".format(arg, typename))

        return_type = ""
        if not is_void_function(node):
            if node.returns:
                typename = self._typename_from_annotation(node, attr="returns")
                return_type = f"::{typename}"
            else:
                return_type = "::RT"
                typedecls.append("RT")

        template = ""
        if len(typedecls) > 0:
            template = "{{{0}}}".format(", ".join(typedecls))

        args = ", ".join(args_list)
        funcdef = f"function {node.name}{template}({args}){return_type}"
        maybe_main = ""
        if is_python_main:
            maybe_main = "\nmain()"
        return f"{funcdef}\n{body}\nend\n{maybe_main}"
Exemple #9
0
    def visit_FunctionDef(self, node, async_prefix=""):
        body = "\n".join([self.visit(n) for n in node.body])
        typenames, args = self.visit(node.args)

        args_list = []
        if args and args[0] == "self":
            del typenames[0]
            del args[0]
            args_list.append("&self")

        typedecls = []
        index = 0
        for i in range(len(args)):
            typename = typenames[i]
            arg = args[i]
            if typename == "T":
                typename = "T{0}".format(index)
                typedecls.append(typename)
                index += 1
            args_list.append("{0}: {1}".format(arg, typename))

        return_type = ""
        if not is_void_function(node):
            if node.returns:
                typename = self._typename_from_annotation(node, attr="returns")
                if getattr(node.returns, "rust_needs_reference", False):
                    typename = f"&{typename}"
                return_type = f"-> {typename}"
            else:
                return_type = "-> RT"
                typedecls.append("RT")

        template = ""
        if len(typedecls) > 0:
            template = "<{0}>".format(", ".join(typedecls))

        extension = "#[pyfunction]\n" if self.extension else ""
        args_list = ", ".join(args_list)
        funcdef = f"{extension}pub {async_prefix}fn {node.name}{template}({args_list}) {return_type}"
        return funcdef + " {\n" + body + "\n}\n"
Exemple #10
0
    def visit_FunctionDef(self, node) -> str:
        signature = ["fn"]
        if node.scopes[-1] is ast.ClassDef:
            raise AstNotImplementedError(
                "Class methods are not supported yet.", node)
        signature.append(node.name)

        generics: Set[str] = set()
        args: List[Tuple[str, str]] = []
        for arg in node.args.args:
            typename, id = self.visit(arg)
            if typename is None:  # receiver
                typename = "<struct name>"  # TODO: fetch struct name from node.scopes
            elif len(typename) == 1 and typename.isupper():
                generics.add(typename)
            args.append((typename, id))

        str_args: List[str] = []
        for typename, id in args:
            if typename == "":
                for c in string.ascii_uppercase:
                    if c not in generics:
                        generics.add(c)
                        typename = c
            if typename == "":
                raise AstNotImplementedError(
                    "Cannot use more than 26 generics in a function.", node)

            str_args.append(f"{id} {typename}")
        signature.append(f"({', '.join(str_args)})")

        if not is_void_function(node):
            signature.append(
                self._typename_from_annotation(node, attr="returns"))

        body = "\n".join([self.indent(self.visit(n)) for n in node.body])
        return f"{' '.join(signature)} {{\n{body}\n}}"
Exemple #11
0
def test_is_not_void_for_fun_with_return_value():
    source = parse("def foo(x):", "   return x")
    foo = source.body[0]
    assert not is_void_function(foo)
Exemple #12
0
def test_is_void_for_fun_with_no_return():
    source = parse("def foo(x):", "   bar(x)")
    foo = source.body[0]
    assert is_void_function(foo)