Esempio n. 1
0
def _unpack_if_variable(
        expr: ir.Expr, var_names: Set[str],
        literal_expr_by_unique_name: MutableMapping[str,
                                                    ir.AtomicTypeLiteral]):
    if isinstance(expr, ir.VariadicTypeExpansion):
        return ListExpansion(
            _unpack_if_variable(expr.expr, var_names,
                                literal_expr_by_unique_name))

    if isinstance(expr, ir.AtomicTypeLiteral) and expr.cpp_type in var_names:
        # We keep track of the expr so that we can re-pack this later.
        # If there are multiple they must be the same.
        if expr.cpp_type in literal_expr_by_unique_name:
            assert expr == literal_expr_by_unique_name[
                expr.cpp_type], '%s vs %s. Detailed:\n%s\n-- vs --\n%s' % (
                    expr_to_cpp_simple(expr),
                    expr_to_cpp_simple(
                        literal_expr_by_unique_name[expr.cpp_type]),
                    ir_to_string(expr),
                    ir_to_string(literal_expr_by_unique_name[expr.cpp_type]))
        else:
            literal_expr_by_unique_name[expr.cpp_type] = expr

        return expr.cpp_type
    else:
        return expr
Esempio n. 2
0
File: ir.py Progetto: google/tmppy
    def __post_init__(self) -> None:
        if self.body:
            for arg in self.args:
                assert arg.name

        assert (not self.body or not self.is_metafunction or any(
            isinstance(elem, Typedef) and elem.name in ('type', 'error',
                                                        'value')
            for elem in self.body) or any(
                isinstance(elem, ConstantDef) and elem.name == 'value'
                for elem in self.body)), ir_to_string(self)
Esempio n. 3
0
def _compile(module_name: str, object_files: List[str], filename: str,
             verbose):
    object_file_content = compile(
        module_name=module_name,
        file_name=filename,
        context_object_files=object_files,
        include_intermediate_irs_for_debugging=verbose)

    if verbose:
        main_module = object_file_content.modules_by_name[module_name]
        print('TMPPy IR2:')
        print(ir_to_string(main_module.ir2_module))
        print()
        print('TMPPy IR1:')
        print(ir_to_string(main_module.ir1_module))
        print()
        print('TMPPy IR0:')
        print(ir_to_string(main_module.ir0_header))
        print()

    return object_file_content
Esempio n. 4
0
def convert_to_cpp(python_source, filename='<unknown>', verbose=False):
    source_ast = ast.parse(python_source, filename=filename)
    compilation_context = ast2highir.CompilationContext(ast2highir.SymbolTable(),
                                                        ast2highir.SymbolTable(),
                                                        filename,
                                                        python_source.splitlines())

    def identifier_generator_fun():
        for i in itertools.count():
            yield 'TmppyInternal_%s' % i
    identifier_generator = iter(identifier_generator_fun())

    module_high_ir = ast2highir.module_ast_to_ir(source_ast, compilation_context)
    if verbose:
        print('TMPPy high IR:')
        print(utils.ir_to_string(module_high_ir))
        print()

    module_ir = highir2ir.module_to_ir(module_high_ir, identifier_generator)
    if verbose:
        print('TMPPy IR:')
        print(utils.ir_to_string(module_ir))
        print()

    header = ir2lowir.module_to_low_ir(module_ir, identifier_generator)
    if verbose:
        print('TMPPy low IR:')
        print(utils.ir_to_string(header))
        print()

    result = lowir2cpp.header_to_cpp(header, identifier_generator)
    result = utils.clang_format(result)

    if verbose:
        print('Conversion result:')
        print(result)
    return result
Esempio n. 5
0
def convert_to_cpp(python_source, filename='<unknown>', verbose=False):
    source_ast = ast.parse(python_source, filename=filename)

    def identifier_generator_fun():
        for i in itertools.count():
            yield 'TmppyInternal_%s' % i

    identifier_generator = iter(identifier_generator_fun())

    module_ir3 = ast_to_ir3.module_ast_to_ir3(source_ast, filename,
                                              python_source.splitlines())
    if verbose:
        print('TMPPy IR3:')
        print(utils.ir_to_string(module_ir3))
        print()

    module_ir3 = optimize_ir3.optimize_module(module_ir3)
    if verbose:
        print('TMPPy IR3 after optimization:')
        print(utils.ir_to_string(module_ir3))
        print()

    module_ir2 = ir3_to_ir2.module_to_ir2(module_ir3, identifier_generator)
    if verbose:
        print('TMPPy IR2:')
        print(utils.ir_to_string(module_ir2))
        print()

    module_ir1 = ir2_to_ir1.module_to_ir1(module_ir2)
    if verbose:
        print('TMPPy IR1:')
        print(utils.ir_to_string(module_ir1))
        print()

    header_ir0 = ir1_to_ir0.module_to_ir0(module_ir1, identifier_generator)
    if verbose:
        print('TMPPy IR0:')
        print(utils.ir_to_string(header_ir0))
        print()

    header_ir0 = optimize_ir0.optimize_header(header_ir0, identifier_generator)
    if verbose:
        print('TMPPy IR0 after optimization:')
        print(utils.ir_to_string(header_ir0))
        print()

    result = ir0_to_cpp.header_to_cpp(header_ir0, identifier_generator)
    result = utils.clang_format(result)

    if verbose:
        print('Conversion result:')
        print(result)
    return result
Esempio n. 6
0
    def __init__(self, args: Sequence[TemplateArgDecl],
                 patterns: 'Optional[Sequence[Expr]]',
                 body: Sequence[TemplateBodyElement], is_metafunction: bool):
        self.args = tuple(args)
        self.is_metafunction = is_metafunction
        if body:
            for arg in args:
                assert arg.name

        self.patterns = tuple(patterns) if patterns is not None else None
        self.body = tuple(body)
        assert (not body or not is_metafunction or any(
            isinstance(elem, Typedef) and elem.name in ('type', 'error',
                                                        'value')
            for elem in body) or any(
                isinstance(elem, ConstantDef) and elem.name == 'value'
                for elem in body)), 'body was:\n%s' % '\n'.join(
                    ir_to_string(elem) for elem in body)
Esempio n. 7
0
 def term_to_string(self, term: ir.Expr):
     return '"' + expr_to_cpp_simple(term) + '"\n' + ir_to_string(term)
    def _transform_template_body_elems(
            self, elems: Tuple[ir.TemplateBodyElement,
                               ...], result_element_names: FrozenSet[str],
            template_specialization_args: Tuple[ir.TemplateArgDecl,
                                                ...], is_metafunction: bool):
        name_by_expr: Dict[ir.Expr, str] = dict()
        replacements: Dict[str, str] = dict()
        type_by_name: Dict[str, ir.ExprType] = dict()

        # First we process all args, so that we'll remove assignments of the form:
        # x1 = arg1
        for arg in template_specialization_args:
            name_by_expr[ir.AtomicTypeLiteral.for_local(
                cpp_type=arg.name,
                expr_type=arg.expr_type,
                is_variadic=arg.is_variadic)] = arg.name
            type_by_name[arg.name] = arg.expr_type

        result_elems = []
        for elem in elems:
            assert isinstance(self.writer, ToplevelWriter)
            writer = TemplateBodyWriter(self.writer)
            transformation = NameReplacementTransformation(replacements)
            with transformation.set_writer(writer):
                transformation.transform_template_body_elem(elem)
            [elem] = writer.elems
            if isinstance(
                    elem,
                (ir.ConstantDef, ir.Typedef)) and elem.expr in name_by_expr:
                replacements[elem.name] = name_by_expr[elem.expr]
                type_by_name[elem.name] = elem.expr.expr_type
            else:
                result_elems.append(elem)
                if isinstance(elem, (ir.ConstantDef, ir.Typedef)):
                    name_by_expr[elem.expr] = elem.name

        additional_result_elems = []

        # This second pass will rename "result elements" back to the correct names if they were deduped.
        replacements2 = dict()
        arg_names = {arg.name for arg in template_specialization_args}
        for result_elem_name in result_element_names:
            if result_elem_name in replacements:
                replacement = replacements[result_elem_name]
                if replacement in replacements2:
                    # We've already added a replacement in `replacements2`, so we need to emit an extra "assignment" assigning
                    # a result element to another.
                    additional_result_elems.append(
                        _create_var_to_var_assignment(
                            lhs=result_elem_name,
                            rhs=replacements2[replacement],
                            expr_type=type_by_name[replacement]))
                elif replacement in result_element_names:
                    # We've eliminated the assignment to the result var against another result var, so we need to emit an
                    # extra "assignment" assigning a result element to another.

                    if replacement in type_by_name:
                        expr_type = type_by_name[replacement]
                    elif result_elem_name in type_by_name:
                        expr_type = type_by_name[result_elem_name]
                    else:
                        raise NotImplementedError(
                            'Unable to determine type. This should never happen.'
                        )

                    additional_result_elems.append(
                        _create_var_to_var_assignment(lhs=result_elem_name,
                                                      rhs=replacement,
                                                      expr_type=expr_type))
                elif replacement in arg_names:
                    # We've eliminated the assignment to the result var against the definition of an argument.
                    # So we need to add it back.
                    additional_result_elems.append(
                        _create_var_to_var_assignment(
                            lhs=result_elem_name,
                            rhs=replacement,
                            expr_type=type_by_name[replacement]))
                else:
                    replacements2[replacement] = result_elem_name

        result_elems = NameReplacementTransformation(
            replacements2).transform_template_body_elems(tuple(result_elems))
        result_elems = (*result_elems, *additional_result_elems)

        if is_metafunction and result_elems:
            assert (
                any(
                    isinstance(elem, ir.Typedef) and elem.name in
                    ('type', 'error', 'value') for elem in result_elems)
                or any(
                    isinstance(elem, ir.ConstantDef) and elem.name == 'value'
                    for elem in result_elems)
            ), 'type_by_name == %s\nreplacements2 == %s\nbody was:\n%s' % (
                type_by_name, replacements2, '\n'.join(
                    ir_to_string(elem) for elem in result_elems))
        return tuple(result_elems)