예제 #1
0
 def visit_unsupported_body(self, node, name, body):
     if self._throw_on_unimplemented:
         raise AstNotImplementedError(f"{name} not implemented", node)
     else:
         return self.comment(
             f"{name} unimplemented on line {node.lineno}:{node.col_offset}"
         )
예제 #2
0
 def _slice_value(self, node: ast.Subscript):
     # 3.9 compatibility shim
     if sys.version_info < (3, 9, 0):
         if isinstance(node.slice, ast.Index):
             slice_value = node.slice.value
         else:
             slice_value = node.slice
     else:
         if isinstance(node.slice, ast.Slice):
             raise AstNotImplementedError("Advanced Slicing not supported", node)
         slice_value = node.slice
     return slice_value
예제 #3
0
 def visit(self, node):
     if node is None:
         raise AstEmptyNodeFound
     if type(node) in symbols:
         return c_symbol(node)
     else:
         try:
             return super().visit(node)
         except AstNotImplementedError:
             raise
         except Exception as e:
             raise AstNotImplementedError(e, node) from e
예제 #4
0
    def visit_Subscript(self, node):
        value = self.visit(node.value)
        if isinstance(node.slice, ast.Ellipsis):
            raise AstNotImplementedError("Ellipsis not supported", node)

        slice_value = self._slice_value(node)
        index = self.visit(slice_value)
        if hasattr(node, "is_annotation"):
            if value in self.CONTAINER_TYPES:
                value = self.CONTAINER_TYPES[value]
            return "{0}<{1}>".format(value, index)
        return f"{value}[{index}]"
예제 #5
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}}"
예제 #6
0
    def visit_Assign(self, node: ast.Assign) -> str:
        assign: List[str] = []
        use_temp: bool = len(node.targets) > 1 and isinstance(
            node.value, ast.Call)
        if use_temp:
            assign.append(f"mut tmp := {self.visit(node.value)}")
        for target in node.targets:
            kw: str = "mut " if is_mutable(node.scopes, get_id(target)) else ""
            if use_temp:
                value: str = "tmp"
            else:
                value: str = self.visit(node.value)

            if isinstance(target, (ast.Tuple, ast.List)):
                value = value[1:-1]
                subtargets: List[str] = []
                op: str = ":="
                for subtarget in target.elts:
                    subkw: str = ("mut " if is_mutable(
                        node.scopes, get_id(subtarget)) else "")
                    subtargets.append(f"{subkw}{self.visit(subtarget)}")
                    definition: Optional[
                        ast.AST] = node.scopes.parent_scopes.find(
                            get_id(subtarget)) or node.scopes.find(
                                get_id(subtarget))
                    if definition is not None and defined_before(
                            definition, subtarget):
                        op = "="
                    elif op == "=":
                        raise AstNotImplementedError(
                            "Mixing declarations and assignment in the same statement is unsupported.",
                            node,
                        )
                assign.append(f"{', '.join(subtargets)} {op} {value}")
            elif isinstance(target, (ast.Subscript, ast.Attribute)):
                target: str = self.visit(target)
                assign.append(f"{target} = {value}")
            elif isinstance(target, ast.Name) and defined_before(
                    node.scopes.parent_scopes.find(target.id)
                    or node.scopes.find(target.id),
                    node,
            ):
                target: str = self.visit(target)
                assign.append(f"{target} = {value}")
            else:
                target: str = self.visit(target)

                assign.append(f"{kw}{target} := {value}")
        return "\n".join(assign)
예제 #7
0
    def visit_Call(self, node) -> str:
        fname = self.visit(node.func)
        vargs = []

        if node.args:
            vargs += [self.visit(a) for a in node.args]
        if node.keywords:
            vargs += [self.visit(kw.value) for kw in node.keywords]

        ret = self._dispatch(node, fname, vargs)
        if ret is not None:
            return ret

        if any(i is None for i in vargs):
            raise AstNotImplementedError(f"Call {fname} ({vargs}) not supported", node)

        args = ", ".join(vargs)
        return f"{fname}({args})"
예제 #8
0
    def visit_GeneratorExp(self, node: ast.GeneratorExp) -> ast.Call:
        new_node = None
        for comp in node.generators:
            if isinstance(comp.target, ast.Name):
                self.redirects[comp.target.id] = "it"
            elif isinstance(comp.target, ast.Tuple):
                for idx, elem in enumerate(comp.target.elts):
                    assert isinstance(elem, ast.Name)
                    self.redirects[elem.id] = f"it[{idx}]"
            else:
                raise AstNotImplementedError(
                    f"Unknown target type {type(node.target).__qualname__}",
                    node)

            subnode = comp.iter

            for cmp in comp.ifs:
                chain = create_ast_node("placeholder.filter(placeholder)",
                                        at_node=node)
                chain.func.value = subnode
                chain.args[0] = cmp
                subnode = chain

            chain = create_ast_node("placeholder.map(placeholder)",
                                    at_node=node)
            chain.func.value = subnode
            chain.args[0] = node.elt
            subnode = chain

            if new_node is None:
                new_node = subnode
            else:
                new_node.args[0] = subnode

        self.visit(new_node)
        self.redirects.clear()
        return new_node
예제 #9
0
 def visit_AnnAssign(self, node):
     target, type_str, val = super().visit_AnnAssign(node)
     if val == None:
         return f"(declare-const {target} {type_str})"
     else:
         raise AstNotImplementedError(f"{val} can't be assigned", node)
예제 #10
0
 def visit_Starred(self, node: ast.Starred) -> str:
     raise AstNotImplementedError(
         "Starred expressions are not supported yet.", node)
예제 #11
0
 def visit_Global(self, node: ast.Global) -> str:
     raise AstNotImplementedError("Globals are not supported yet.", node)
예제 #12
0
 def visit_Try(self, node: ast.Try, finallybody: bool = None) -> str:
     raise AstNotImplementedError("Exceptions are not supported yet.", node)
예제 #13
0
 def visit_ClassDef(self, node: ast.ClassDef) -> str:
     raise AstNotImplementedError("Classes are not supported yet.", node)
예제 #14
0
 def visit_StrEnum(self, node: ast.ClassDef) -> str:
     raise AstNotImplementedError("String enums are not supported in V.",
                                  node)
예제 #15
0
 def visit_Lambda(self, node: ast.Lambda) -> str:
     raise AstNotImplementedError("Lambdas are not supported yet.", node)
예제 #16
0
 def visit_Await(self, node: ast.Await) -> str:
     raise AstNotImplementedError("asyncio is not supported.", node)
예제 #17
0
 def visit_With(self, node: ast.With) -> str:
     raise AstNotImplementedError(
         "`with` statements are not supported yet.", node)
예제 #18
0
 def visit_Raise(self, node: ast.Raise) -> str:
     raise AstNotImplementedError("Exceptions are not supported yet.", node)
예제 #19
0
 def visit_Delete(self, node: ast.Delete) -> str:
     raise AstNotImplementedError(
         "`delete` statements are not supported yet.", node)
예제 #20
0
 def visit_ExceptHandler(self, node) -> str:
     raise AstNotImplementedError("Exceptions are not supported yet.", node)
예제 #21
0
 def visit_Yield(self, node: ast.Yield) -> str:
     raise AstNotImplementedError("Generators are not supported yet.", node)
예제 #22
0
 def visit_Call(self, node):
     params = [self.visit(arg) for arg in node.args]
     if any(t is None for t in params):
         raise AstNotImplementedError(f"Call({params}) not implemented", node)
     params = ",".join(params)
     return "{0}({1})".format(self.visit(node.func), params)
예제 #23
0
 def visit_DictComp(self, node: ast.DictComp) -> str:
     raise AstNotImplementedError(
         "Dict comprehensions are not supported yet.", node)
예제 #24
0
 def visit_IntFlag(self, node: ast.ClassDef) -> str:
     raise AstNotImplementedError("Enums are not supported yet.", node)
예제 #25
0
 def visit_GeneratorExp(self, node: ast.GeneratorExp) -> str:
     raise AstNotImplementedError(
         "Comprehensions should have been handled in the rewriter.", node)
예제 #26
0
 def visit_AsyncFunctionDef(self, node: ast.FunctionDef) -> str:
     raise AstNotImplementedError("asyncio is not supported.", node)
예제 #27
0
 def visit_Set(self, node: ast.Set) -> str:
     raise AstNotImplementedError("Sets are not implemented in V yet.",
                                  node)