Ejemplo n.º 1
0
    def visit_If(self, node):
        body_vars = set([get_id(v) for v in node.scopes[-1].body_vars])
        orelse_vars = set([get_id(v) for v in node.scopes[-1].orelse_vars])
        node.common_vars = body_vars.intersection(orelse_vars)

        # HACK to determine if main function name is visited
        if self.visit(node.test) == '__name__ == "__main__"':
            buf = ["proc main():"]
            buf.extend([self.visit(child) for child in node.body])
            buf.append("")
            return "\n".join(buf)
        body = "\n".join([
            self.indent(self.visit(child), level=node.level + 1)
            for child in node.body
        ])
        orelse = "\n".join([
            self.indent(self.visit(child), level=node.level + 1)
            for child in node.orelse
        ])
        test = self.visit(node.test)
        if node.orelse:
            orelse = f"else:\n{orelse}"
        else:
            orelse = ""
        return f"if {test}:\n{body}\n{orelse}"
Ejemplo n.º 2
0
    def visit_If(self, node):
        body_vars = set([get_id(v) for v in node.scopes[-1].body_vars])
        orelse_vars = set([get_id(v) for v in node.scopes[-1].orelse_vars])
        node.common_vars = body_vars.intersection(orelse_vars)

        # HACK to determine if main function name is visited
        if self.visit(node.test) == '__name__ == "__main__"':
            buf = ["function main()"]
            buf.extend([self.visit(child) for child in node.body])
            buf.append("")
            return "\n".join(buf) + "end\n"
        buf = []
        cond = self.visit(node.test)
        buf.append(f"if {cond}")
        buf.extend([self.visit(child) for child in node.body])

        orelse = [self.visit(child) for child in node.orelse]
        if orelse:
            buf.append("else\n")
            buf.extend(orelse)
            buf.append("end")
        else:
            buf.append("end")

        return "\n".join(buf)
Ejemplo n.º 3
0
    def visit_BinOp(self, node):
        self.generic_visit(node)

        if isinstance(node.left, ast.Name):
            lvar = node.scopes.find(get_id(node.left))
        else:
            lvar = node.left

        if isinstance(node.right, ast.Name):
            rvar = node.scopes.find(get_id(node.right))
        else:
            rvar = node.right

        left = lvar.annotation if lvar and hasattr(lvar, "annotation") else None
        right = rvar.annotation if rvar and hasattr(rvar, "annotation") else None

        if left is None and right is not None:
            node.annotation = right
            return node

        if right is None and left is not None:
            node.annotation = left
            return node

        if right is None and left is None:
            return node

        # Both operands are annotated. Now we have interesting cases
        left_id = get_id(left)
        right_id = get_id(right)

        if (
            left_id in self.FIXED_WIDTH_INTS_NAME
            and right_id in self.FIXED_WIDTH_INTS_NAME
        ):
            ret = self._handle_overflow(node.op, left_id, right_id)
            node.annotation = ast.Name(id=ret)
            return node
        if left_id == right_id:
            # Exceptions: division operator
            if isinstance(node.op, ast.Div):
                if left_id == "int":
                    node.annotation = ast.Name(id="float")
                    return node
            node.annotation = copy.copy(left)
            return node
        else:
            if left_id in self.FIXED_WIDTH_INTS_NAME:
                left_id = "int"
            if right_id in self.FIXED_WIDTH_INTS_NAME:
                right_id = "int"
            if (left_id, right_id) in {("int", "float"), ("float", "int")}:
                node.annotation = ast.Name(id="float")
                return node

            raise Exception(f"type error: {left_id} {type(node.op)} {right_id}")

        return node
Ejemplo n.º 4
0
    def visit_Assign(self, node):
        target = node.targets[0]

        if isinstance(target, ast.Tuple):
            elts = [self.visit(e) for e in target.elts]
            value = self.visit(node.value)
            return "let ({0}) = {1};".format(", ".join(elts), value)

        if isinstance(node.scopes[-1], ast.If):
            outer_if = node.scopes[-1]
            target_id = self.visit(target)
            if target_id in outer_if.common_vars:
                value = self.visit(node.value)
                return "{0} = {1};".format(target_id, value)

        if isinstance(target, ast.Subscript) or isinstance(
                target, ast.Attribute):
            target = self.visit(target)
            value = self.visit(node.value)
            if value == None:
                value = "None"
            return "{0} = {1};".format(target, value)

        definition = node.scopes.find(target.id)
        if isinstance(target, ast.Name) and defined_before(definition, node):
            target = self.visit(target)
            value = self.visit(node.value)
            return "{0} = {1};".format(target, value)
        elif isinstance(node.value, ast.List):
            elements = [self.visit(e) for e in node.value.elts]
            mut = ""
            if is_mutable(node.scopes, get_id(target)):
                mut = "mut "
            return "let {0}{1} = vec![{2}];".format(mut, self.visit(target),
                                                    ", ".join(elements))
        else:
            mut = ""
            if is_mutable(node.scopes, get_id(target)):
                mut = "mut "

            typename = "_"
            if hasattr(target, "annotation"):
                typename = get_id(target.annotation)
                if typename in self._type_map:
                    typename = self._type_map[typename]

            target = self.visit(target)
            value = self.visit(node.value)

            if len(node.scopes) == 1:
                if isinstance(
                        node.scopes[0], ast.Module
                ):  # if assignment is module level it must be const
                    return f"const {target}: {typename} = {value};"

            return f"let {mut}{target}: {typename} = {value};"
Ejemplo n.º 5
0
    def visit_If(self, node):
        body_vars = set([get_id(v) for v in node.scopes[-1].body_vars])
        orelse_vars = set([get_id(v) for v in node.scopes[-1].orelse_vars])
        node.common_vars = body_vars.intersection(orelse_vars)

        # HACK to determine if main function name is visited
        if self.visit(node.test) == '__name__ == "__main__"':
            buf = ["fun main() {"]
            buf.extend([self.visit(child) for child in node.body])
            buf.append("")
            return "}\n".join(buf)
        return super().visit_If(node)
Ejemplo n.º 6
0
    def visit_Name(self, node):
        var = node.scopes.find(get_id(node))

        if not var:  # TODO why no scopes found for node id?
            return get_id(node)

        # TODO: code looks C++ specific. Move out
        if isinstance(var.assigned_from, ast.For):
            it = var.assigned_from.iter
            return "std::declval<typename decltype({0})::value_type>()".format(
                self.visit(it))
        elif isinstance(var.assigned_from, ast.FunctionDef):
            return get_id(var)
        else:
            return self.visit(var.assigned_from.value)
Ejemplo n.º 7
0
    def visit_AnnAssign(self, node: ast.AnnAssign) -> ast.AST:
        self.generic_visit(node)

        node.target.annotation = node.annotation
        if get_id(node.annotation) in self.FIXED_WIDTH_INTS_NAME:
            self.has_fixed_width_ints = True
        return node
Ejemplo n.º 8
0
    def visit_ClassDef(self, node):
        extractor = DeclarationExtractor(KotlinTranspiler())
        extractor.visit(node)
        declarations = extractor.get_declarations()

        fields = []
        index = 0
        for declaration, typename in declarations.items():
            if typename == None:
                typename = "ST{0}".format(index)
                index += 1
            mut = is_mutable(node.scopes, get_id(declaration))
            mut = "var" if mut else "val"
            fields.append(f"{mut} {declaration}: {typename}")

        for b in node.body:
            if isinstance(b, ast.FunctionDef):
                b.self_type = node.name

        if node.is_dataclass:
            fields = ", ".join(fields)
            body = [self.visit(b) for b in node.body]
            body = "\n".join(body)
            return f"data class {node.name}({fields}) {{\n{body}\n}}\n"
        else:
            fields = "\n".join(fields)
            body = [self.visit(b) for b in node.body]
            body = "\n".join(body)
            return f"class {node.name} {{\n{fields}\n\n {body}\n}}\n"
Ejemplo n.º 9
0
 def visit_arg(self, node):
     id = get_id(node)
     if id == "self":
         return (None, "self")
     typename = "T"
     if node.annotation:
         typename = self.visit(node.annotation)
     return (typename, id)
Ejemplo n.º 10
0
 def visit_Return(self, node):
     self.generic_visit(node)
     new_type_str = (
         get_id(node.value.annotation) if hasattr(node.value, "annotation") else None
     )
     if new_type_str is None:
         return node
     for scope in node.scopes:
         type_str = None
         if isinstance(scope, ast.FunctionDef):
             type_str = get_id(scope.returns)
             if type_str is not None:
                 if new_type_str != type_str:
                     type_str = f"Union[{type_str},{new_type_str}]"
                     scope.returns.id = type_str
             else:
                 scope.returns = ast.Name(id=new_type_str)
     return node
Ejemplo n.º 11
0
def is_self_arg(name, scopes):
    for scope in scopes:
        for entry in scope.body:
            if isinstance(entry, ast.FunctionDef):
                if len(entry.args.args):
                    first_arg = entry.args.args[0]
                    if get_id(first_arg) == name and hasattr(
                            entry, "self_type"):
                        return True
    return False
Ejemplo n.º 12
0
    def visit_If(self, node):
        body_vars = set([get_id(v) for v in node.scopes[-1].body_vars])
        orelse_vars = set([get_id(v) for v in node.scopes[-1].orelse_vars])
        node.common_vars = body_vars.intersection(orelse_vars)

        # TODO find out if this can be useful
        var_definitions = []
        # for cv in node.common_vars:
        #     definition = node.scopes.find(cv)
        #     var_type = decltype(definition)
        #     var_definitions.append("{0} {1};\n".format(var_type, cv))

        # HACK to determine if main function name is visited
        if self.visit(node.test) == '__name__ == "__main__"':
            buf = ["fn main() {"]
            buf.extend([self.visit(child) for child in node.body])
            buf.append("}")
            return "\n".join(buf)
        else:
            return "".join(var_definitions) + super(
                RustTranspiler, self).visit_If(node, use_parens=False)
Ejemplo n.º 13
0
    def visit_UnaryOp(self, node):
        self.generic_visit(node)

        if isinstance(node.operand, ast.Name):
            operand = node.scopes.find(get_id(node.operand))
        else:
            operand = node.operand

        if hasattr(operand, "annotation"):
            node.annotation = operand.annotation

        return node
Ejemplo n.º 14
0
    def visit_Assign(self, node: ast.Assign) -> ast.AST:
        self.generic_visit(node)

        target = node.targets[0]
        if hasattr(node.value, "annotation"):
            target.annotation = node.value.annotation
        else:
            var = node.scopes.find(get_id(node.value))

            if var and hasattr(var, "annotation"):
                target.annotation = copy.copy(var.annotation)

        return node
Ejemplo n.º 15
0
def is_list(node):
    """Check if a node was assigned as a list"""
    if isinstance(node, ast.List):
        return True
    elif isinstance(node, ast.Assign):
        return is_list(node.value)
    elif isinstance(node, ast.Name):
        var = node.scopes.find(get_id(node))
        return (hasattr(var, "assigned_from")
                and not isinstance(var.assigned_from, ast.FunctionDef)
                and not isinstance(var.assigned_from, ast.For)
                and is_list(var.assigned_from.value))
    else:
        return False
Ejemplo n.º 16
0
    def visit_If(self, node):
        body_vars = set([get_id(v) for v in node.scopes[-1].body_vars])
        orelse_vars = set([get_id(v) for v in node.scopes[-1].orelse_vars])
        node.common_vars = body_vars.intersection(orelse_vars)

        var_definitions = []
        for cv in node.common_vars:
            definition = node.scopes.find(cv)
            var_type = decltype(definition)
            var_definitions.append("{0} {1};\n".format(var_type, cv))

        if self.visit(node.test) == '__name__ == std::string {"__main__"}':
            buf = [
                "int main(int argc, char ** argv) {",
                "py14::sys::argv = "
                "std::vector<std::string>(argv, argv + argc);",
            ]
            buf.extend([self.visit(child) for child in node.body])
            buf.append("}")
            return "\n".join(buf)
        else:
            return "".join(var_definitions) + super(CppTranspiler,
                                                    self).visit_If(node)
Ejemplo n.º 17
0
    def visit_If(self, node):
        body_vars = set([get_id(v) for v in node.scopes[-1].body_vars])
        orelse_vars = set([get_id(v) for v in node.scopes[-1].orelse_vars])
        node.common_vars = body_vars.intersection(orelse_vars)

        var_definitions = []
        for cv in node.common_vars:
            definition = node.scopes.find(cv)
            typename = "var"
            if hasattr(cv, "annotation"):
                typename = get_id(cv.annotation)

            var_definitions.append((typename, cv))
        decls = "\n".join(
            [f"{typename} {cv};" for typename, cv in var_definitions])

        # HACK to determine if main function name is visited
        if self.visit(node.test) == '__name__ == "__main__"':
            buf = ["void main() {"]
            buf.extend([self.visit(child) for child in node.body])
            buf.append("")
            return "\n".join(buf) + "}\n"
        return decls + "\n\n" + super().visit_If(node)
Ejemplo n.º 18
0
    def visit_Attribute(self, node):
        attr = node.attr
        value_id = get_id(node.value)
        if is_builtin_import(value_id):
            return "py14::" + value_id + "::" + attr
        elif value_id == "math":
            if node.attr == "asin":
                return "std::asin"
            elif node.attr == "atan":
                return "std::atan"
            elif node.attr == "acos":
                return "std::acos"

        if is_list(node.value):
            if node.attr == "append":
                attr = "push_back"
        return value_id + "." + attr
Ejemplo n.º 19
0
def generate_template_fun(node, body):
    params = []
    for idx, arg in enumerate(node.args.args):
        params.append(("T" + str(idx + 1), get_id(arg)))
    typenames = ["typename " + arg[0] for arg in params]

    template = "inline "
    if len(typenames) > 0:
        template = "template <{0}>\n".format(", ".join(typenames))
    params = ["{0} {1}".format(arg[0], arg[1]) for arg in params]

    return_type = "auto"
    if is_void_function(node):
        return_type = "void"

    funcdef = "{0}{1} {2}({3})".format(template, return_type, node.name,
                                       ", ".join(params))
    return funcdef + " {\n" + body + "\n}"
Ejemplo n.º 20
0
    def visit_Assign(self, node):
        target = node.targets[0]

        if isinstance(target, ast.Tuple):
            elts = [self.visit(e) for e in target.elts]
            value = self.visit(node.value)
            return f"{elts} = {value};"

        if isinstance(node.scopes[-1], ast.If):
            outer_if = node.scopes[-1]
            target_id = self.visit(target)
            if target_id in outer_if.common_vars:
                value = self.visit(node.value)
                return f"{target_id} = {value};"

        if isinstance(target, ast.Subscript) or isinstance(
                target, ast.Attribute):
            target = self.visit(target)
            value = self.visit(node.value)
            if value == None:
                value = "None"
            return f"{target} = {value};"

        definition = node.scopes.find(target.id)
        if isinstance(target, ast.Name) and defined_before(definition, node):
            target = self.visit(target)
            value = self.visit(node.value)
            return f"{target} = {value};"
        elif isinstance(node.value, ast.List):
            elements = [self.visit(e) for e in node.value.elts]
            elements = ", ".join(elements)
            target = self.visit(target)
            return f"var {target} = [{elements}];"
        else:
            typename = "var"
            if hasattr(target, "annotation"):
                typename = get_id(target.annotation)
                if typename in self._type_map:
                    typename = self._type_map[typename]

            target = self.visit(target)
            value = self.visit(node.value)

            return f"{typename} {target} = {value};"
Ejemplo n.º 21
0
    def visit_Assign(self, node):
        target = node.targets[0]

        if isinstance(target, ast.Tuple):
            elts = [self.visit(e) for e in target.elts]
            value = self.visit(node.value)
            return "{0} = {1}".format(", ".join(elts), value)

        if isinstance(node.scopes[-1], ast.If):
            outer_if = node.scopes[-1]
            target_id = self.visit(target)
            if target_id in outer_if.common_vars:
                value = self.visit(node.value)
                return "{0} = {1}".format(target_id, value)

        if isinstance(target, ast.Subscript) or isinstance(
                target, ast.Attribute):
            target = self.visit(target)
            value = self.visit(node.value)
            if value == None:
                value = "None"
            return "{0} = {1}".format(target, value)

        definition = node.scopes.find(target.id)
        if isinstance(target, ast.Name) and defined_before(definition, node):
            target = self.visit(target)
            value = self.visit(node.value)
            return "{0} = {1}".format(target, value)
        elif isinstance(node.value, ast.List):
            elements = [self.visit(e) for e in node.value.elts]
            mut = ""
            if is_mutable(node.scopes, get_id(target)):
                mut = "mutable "
            return "{1} = [{2}]".format(mut, self.visit(target),
                                        ", ".join(elements))
        else:
            target = self.visit(target)
            value = self.visit(node.value)
            return f"{target} = {value}"
Ejemplo n.º 22
0
    def visit_Assign(self, node):
        target = node.targets[0]

        if isinstance(target, ast.Tuple):
            elts = [self.visit(e) for e in target.elts]
            value = self.visit(node.value)
            return "std::tie({0}) = {1};".format(", ".join(elts), value)

        if isinstance(node.scopes[-1], ast.If):
            outer_if = node.scopes[-1]
            if target.id in outer_if.common_vars:
                value = self.visit(node.value)
                return "{0} = {1};".format(target.id, value)

        if isinstance(target, ast.Subscript):
            target = self.visit(target)
            value = self.visit(node.value)
            return "{0} = {1};".format(target, value)

        definition = node.scopes.find(target.id)
        if isinstance(target, ast.Name) and defined_before(definition, node):
            target = self.visit(target)
            value = self.visit(node.value)
            return "{0} = {1};".format(target, value)
        elif isinstance(node.value, ast.List):
            elements = [self.visit(e) for e in node.value.elts]
            return "{0} {1} {{{2}}};".format(decltype(node),
                                             self.visit(target),
                                             ", ".join(elements))
        else:
            typename = "auto"
            if hasattr(target, "annotation"):
                typename = get_id(target.annotation)
                if typename in self._type_map:
                    typename = self._type_map[typename]

            target = self.visit(target)
            value = self.visit(node.value)
            return f"{typename} {target} = {value};"
Ejemplo n.º 23
0
 def visit_AnnAssign(self, node):
     target = node.target
     self.increase_use_count(get_id(target))
     self.generic_visit(node)
     return node
Ejemplo n.º 24
0
 def visit_Call(self, node):
     if hasattr(node.func, "attr"):
         if node.func.attr == "append":
             self.increase_use_count(get_id(node.func.value))
     self.generic_visit(node)
     return node
Ejemplo n.º 25
0
 def find_definition(scope, var_attr="vars"):
     for var in getattr(scope, var_attr):
         if get_id(var) == lookup:
             return var