def _make_bitcast_symbol(symbol_table: SymbolTable,
                         context: CodegenContext) -> OverloadSet:
    del symbol_table  # only to keep API consistent
    del context
    to_type, from_type = PlaceholderTemplateType('T'), PlaceholderTemplateType(
        'U')
    bitcast_signature = BitcastFunctionSignature(
        placeholder_template_types=[to_type, from_type],
        return_type=to_type,
        arg_identifiers=['from'],
        arg_types=[from_type],
        arg_type_narrowings=[to_type])
    return OverloadSet('bitcast', [bitcast_signature])
Exemple #2
0
def test_narrow_type_templates():
    from sleepy.types import narrow_type, UnionType, PlaceholderTemplateType, StructType
    from sleepy.builtin_symbols import SLEEPY_INT, SLEEPY_BOOL
    context = make_test_context()
    Int, Bool = SLEEPY_INT, SLEEPY_BOOL
    T = PlaceholderTemplateType('T')
    List = StructType(identity=StructIdentity('List', context=context),
                      template_param_or_arg=[T],
                      member_identifiers=[],
                      member_types=[])
    # narrow(0:List[Int]|1:List[Bool], List[Int]) = 0:List[Int]
    assert_equal(
        narrow_type(
            UnionType.from_types(
                [List.replace_types({T: Int}),
                 List.replace_types({T: Bool})]), List.replace_types({T:
                                                                      Int})),
        UnionType.from_types([List.replace_types({T: Int})]))
    # narrow(List[Int|Bool], List[Int]) = List[Int|Bool]
    assert_equal(
        narrow_type(List.replace_types({T: UnionType.from_types([Int, Bool])}),
                    List.replace_types({T: Int})),
        List.replace_types({T: UnionType.from_types([Int, Bool])}))
    # narrow(List[Int|Bool]|List[Int], List[Int]) = List[Int|Bool]|List[Int]
    assert_equal(
        narrow_type(
            UnionType.from_types([
                List.replace_types({T: UnionType.from_types([Int, Bool])}),
                List.replace_types({T: Int})
            ]), List.replace_types({T: Int})),
        UnionType.from_types([
            List.replace_types({T: UnionType.from_types([Int, Bool])}),
            List.replace_types({T: Int})
        ]))
Exemple #3
0
def test_try_infer_templ_types_simple():
    from sleepy.types import try_infer_template_arguments, PlaceholderTemplateType
    from sleepy.builtin_symbols import SLEEPY_INT
    from sleepy.builtin_symbols import SLEEPY_DOUBLE
    T = PlaceholderTemplateType('T')
    U = PlaceholderTemplateType('U')
    assert_equal(
        try_infer_template_arguments(calling_types=[],
                                     signature_types=[],
                                     template_parameters=[]), [])
    assert_equal(
        try_infer_template_arguments(
            calling_types=[SLEEPY_INT, SLEEPY_DOUBLE],
            signature_types=[SLEEPY_INT, SLEEPY_DOUBLE],
            template_parameters=[]), [])
    assert_equal(
        try_infer_template_arguments(
            calling_types=[SLEEPY_INT, SLEEPY_DOUBLE],
            signature_types=[SLEEPY_INT, SLEEPY_DOUBLE],
            template_parameters=[T]), None)
    assert_equal(
        try_infer_template_arguments(calling_types=[SLEEPY_INT],
                                     signature_types=[T],
                                     template_parameters=[T]), [SLEEPY_INT])
    assert_equal(
        try_infer_template_arguments(calling_types=[SLEEPY_INT, SLEEPY_INT],
                                     signature_types=[T, T],
                                     template_parameters=[T]), [SLEEPY_INT])
    assert_equal(
        try_infer_template_arguments(calling_types=[SLEEPY_INT, SLEEPY_DOUBLE],
                                     signature_types=[T, SLEEPY_DOUBLE],
                                     template_parameters=[T]), [SLEEPY_INT])
    assert_equal(
        try_infer_template_arguments(calling_types=[SLEEPY_INT, SLEEPY_DOUBLE],
                                     signature_types=[SLEEPY_INT, T],
                                     template_parameters=[T]), [SLEEPY_DOUBLE])
    assert_equal(
        try_infer_template_arguments(calling_types=[SLEEPY_INT, SLEEPY_DOUBLE],
                                     signature_types=[T, U],
                                     template_parameters=[T, U]),
        [SLEEPY_INT, SLEEPY_DOUBLE])
    assert_equal(
        try_infer_template_arguments(calling_types=[SLEEPY_INT, SLEEPY_DOUBLE],
                                     signature_types=[T, U],
                                     template_parameters=[U, T]),
        [SLEEPY_DOUBLE, SLEEPY_INT])
def _make_ref_symbol(symbol_table: SymbolTable,
                     context: CodegenContext) -> TypeTemplateSymbol:
    del symbol_table  # only to keep API consistent
    del context
    pointee_type = PlaceholderTemplateType(identifier='T')
    ref_type = ReferenceType(pointee_type=pointee_type)
    return TypeTemplateSymbol(template_parameters=[pointee_type],
                              signature_type=ref_type)
Exemple #5
0
def test_try_infer_template_arguments_ptr():
    from sleepy.types import try_infer_template_arguments, PlaceholderTemplateType, PointerType
    from sleepy.builtin_symbols import SLEEPY_CHAR
    from sleepy.builtin_symbols import SLEEPY_INT
    T = PlaceholderTemplateType('T')
    assert_equal(
        try_infer_template_arguments(calling_types=[PointerType(SLEEPY_INT)],
                                     signature_types=[PointerType(T)],
                                     template_parameters=[T]), [SLEEPY_INT])
    assert_equal(
        try_infer_template_arguments(
            calling_types=[PointerType(SLEEPY_CHAR), SLEEPY_INT],
            signature_types=[PointerType(T), SLEEPY_INT],
            template_parameters=[T]), [SLEEPY_CHAR])
def _make_raw_ptr_symbol(symbol_table: SymbolTable,
                         context: CodegenContext) -> TypeTemplateSymbol:
    # add destructor
    destructor_signature = BuiltinOperationFunctionSignature(
        identifier='free',
        placeholder_template_types=[],
        return_type=SLEEPY_UNIT,
        arg_identifiers=['raw_ptr'],
        arg_types=[SLEEPY_RAW_PTR],
        arg_type_narrowings=[SLEEPY_NEVER],
        instruction=lambda builder, value: SLEEPY_UNIT.unit_constant())
    symbol_table.add_overload('free', destructor_signature)

    pointee_type = PlaceholderTemplateType(identifier='T')
    ptr_type = PointerType(pointee_type=pointee_type)

    # RawPtr[T](Ptr[T]) -> RawPtr
    from_specific_signature = BitcastFunctionSignature(
        placeholder_template_types=[pointee_type],
        return_type=SLEEPY_RAW_PTR,
        arg_identifiers=['ptr'],
        arg_types=[ptr_type],
        arg_type_narrowings=[ptr_type])
    symbol_table.add_overload('RawPtr', from_specific_signature)

    # RawPtr(Int) -> RawPtr
    from_int_signatures = {
        BuiltinOperationFunctionSignature(
            identifier='RawPtr',
            placeholder_template_types=[],
            return_type=SLEEPY_RAW_PTR,
            arg_identifiers=['int'],
            arg_types=[int_type],
            arg_type_narrowings=[int_type],
            instruction=lambda builder, integer: builder.inttoptr(
                integer, typ=SLEEPY_RAW_PTR.ir_type, name='int_to_ptr'))
        for int_type in INT_TYPES
    }

    symbol_table.add_overload('int_to_ptr', from_int_signatures)
    SLEEPY_RAW_PTR.constructor = OverloadSet(identifier='RawPtr',
                                             signatures=from_int_signatures
                                             | {from_specific_signature})

    raw_ptr_symbol = TypeTemplateSymbol.make_concrete_type_symbol(
        SLEEPY_RAW_PTR)
    return raw_ptr_symbol
Exemple #7
0
def test_struct_self_referencing():
    from sleepy.types import StructType, PlaceholderTemplateType, PartialIdentifiedStructType, ReferenceType
    from sleepy.builtin_symbols import SLEEPY_INT
    context = make_test_context()

    struct_identity = StructIdentity("List", context=context)
    T = PlaceholderTemplateType(identifier="T")
    ListTPartial = PartialIdentifiedStructType(identity=struct_identity,
                                               template_param_or_arg=[T])
    ListT = StructType(identity=struct_identity,
                       template_param_or_arg=[T],
                       member_identifiers=["val", "next"],
                       member_types=[T, ReferenceType(ListTPartial)],
                       partial_struct_type=ListTPartial)
    assert_equal(ListT.member_types, [T, ReferenceType(ListT)])

    Int = SLEEPY_INT
    ListInt = ListT.replace_types({T: Int})
    assert isinstance(ListInt, StructType)
    assert_equal(ListInt.member_types, [Int, ReferenceType(ListInt)])
Exemple #8
0
def test_try_infer_templ_types_struct():
    from sleepy.types import try_infer_template_arguments, PlaceholderTemplateType, StructType
    from sleepy.builtin_symbols import SLEEPY_CHAR, SLEEPY_INT
    context = make_test_context()
    T = PlaceholderTemplateType('T')
    U = PlaceholderTemplateType('U')
    WrapperT = StructType(StructIdentity('Wrapper', context=context),
                          template_param_or_arg=[T],
                          member_identifiers=['value'],
                          member_types=[T])
    WrapperU = WrapperT.replace_types({T: U})
    WrapperInt = WrapperT.replace_types({T: SLEEPY_INT})
    WrapperChar = WrapperT.replace_types({T: SLEEPY_CHAR})
    assert_equal(
        try_infer_template_arguments(calling_types=[WrapperInt],
                                     signature_types=[WrapperT],
                                     template_parameters=[T]), [SLEEPY_INT])
    assert_equal(
        try_infer_template_arguments(calling_types=[WrapperInt],
                                     signature_types=[T],
                                     template_parameters=[T]), [WrapperInt])
    assert_equal(
        try_infer_template_arguments(calling_types=[SLEEPY_INT],
                                     signature_types=[WrapperT],
                                     template_parameters=[T]), None)
    assert_equal(
        try_infer_template_arguments(calling_types=[WrapperInt, WrapperInt],
                                     signature_types=[WrapperT, WrapperT],
                                     template_parameters=[T]), [SLEEPY_INT])
    assert_equal(
        try_infer_template_arguments(calling_types=[WrapperInt, WrapperChar],
                                     signature_types=[WrapperT, WrapperU],
                                     template_parameters=[T, U]),
        [SLEEPY_INT, SLEEPY_CHAR])
    assert_equal(
        try_infer_template_arguments(calling_types=[WrapperInt, SLEEPY_INT],
                                     signature_types=[WrapperT, T],
                                     template_parameters=[T]), [SLEEPY_INT])
    assert_equal(
        try_infer_template_arguments(calling_types=[WrapperChar, SLEEPY_INT],
                                     signature_types=[WrapperT, T],
                                     template_parameters=[T]), None)
    assert_equal(
        try_infer_template_arguments(calling_types=[SLEEPY_INT, SLEEPY_INT],
                                     signature_types=[WrapperT, T],
                                     template_parameters=[T]), None)

    # with templates in calling_types
    assert_equal(
        try_infer_template_arguments(calling_types=[T, WrapperT],
                                     signature_types=[WrapperT, WrapperT],
                                     template_parameters=[T]), None)
    assert_equal(
        try_infer_template_arguments(calling_types=[WrapperT, T],
                                     signature_types=[WrapperT, WrapperT],
                                     template_parameters=[T]), None)
    assert_equal(
        try_infer_template_arguments(calling_types=[WrapperT, WrapperT],
                                     signature_types=[T, WrapperT],
                                     template_parameters=[T]), None)
    assert_equal(
        try_infer_template_arguments(calling_types=[WrapperT, WrapperT],
                                     signature_types=[WrapperT, T],
                                     template_parameters=[T]), None)
Exemple #9
0
def test_can_implicit_cast_to():
    from sleepy.types import can_implicit_cast_to, ReferenceType, UnionType, StructType, PlaceholderTemplateType
    from sleepy.builtin_symbols import SLEEPY_INT, SLEEPY_DOUBLE
    context = make_test_context()
    assert_equal(can_implicit_cast_to(SLEEPY_INT, SLEEPY_DOUBLE), False)
    assert_equal(can_implicit_cast_to(SLEEPY_INT, SLEEPY_INT), True)
    assert_equal(
        can_implicit_cast_to(UnionType.from_types([SLEEPY_INT]), SLEEPY_INT),
        True)
    assert_equal(
        can_implicit_cast_to(UnionType.from_types([SLEEPY_INT, SLEEPY_DOUBLE]),
                             SLEEPY_DOUBLE), False)
    assert_equal(
        can_implicit_cast_to(SLEEPY_DOUBLE,
                             UnionType.from_types([SLEEPY_INT,
                                                   SLEEPY_DOUBLE])), True)
    assert_equal(
        can_implicit_cast_to(ReferenceType(SLEEPY_INT),
                             ReferenceType(SLEEPY_DOUBLE)), False)
    assert_equal(
        can_implicit_cast_to(ReferenceType(SLEEPY_INT),
                             ReferenceType(SLEEPY_INT)), True)
    assert_equal(
        can_implicit_cast_to(
            ReferenceType(UnionType.from_types([SLEEPY_INT, SLEEPY_DOUBLE])),
            ReferenceType(SLEEPY_INT)), False)
    assert_equal(
        can_implicit_cast_to(
            ReferenceType(SLEEPY_INT),
            ReferenceType(UnionType.from_types([SLEEPY_INT, SLEEPY_DOUBLE]))),
        False)
    T = PlaceholderTemplateType('T')
    List = StructType(identity=StructIdentity('List', context=context),
                      template_param_or_arg=[T],
                      member_identifiers=[],
                      member_types=[])
    assert_equal(
        can_implicit_cast_to(
            ReferenceType(SLEEPY_INT),
            ReferenceType(UnionType.from_types([SLEEPY_INT, SLEEPY_DOUBLE]))),
        False)
    assert_equal(
        can_implicit_cast_to(
            ReferenceType(UnionType.from_types([SLEEPY_INT, SLEEPY_DOUBLE])),
            ReferenceType(SLEEPY_INT)), False)
    assert_equal(
        can_implicit_cast_to(
            ReferenceType(UnionType.from_types([SLEEPY_INT, SLEEPY_DOUBLE])),
            UnionType.from_types(
                [ReferenceType(SLEEPY_INT),
                 ReferenceType(SLEEPY_DOUBLE)])), False)
    assert_equal(
        can_implicit_cast_to(
            List.replace_types(
                {T: UnionType.from_types([SLEEPY_INT, SLEEPY_DOUBLE])}),
            List.replace_types({T: SLEEPY_INT})), False)
    assert_equal(
        can_implicit_cast_to(
            List.replace_types({T: SLEEPY_INT}),
            List.replace_types(
                {T: UnionType.from_types([SLEEPY_INT, SLEEPY_DOUBLE])})),
        False)
def _make_ptr_symbol(symbol_table: SymbolTable,
                     context: CodegenContext) -> TypeTemplateSymbol:
    pointee_type = PlaceholderTemplateType(identifier='T')
    ptr_type = PointerType(pointee_type=pointee_type)

    assert 'load' not in symbol_table
    load_signature = BuiltinOperationFunctionSignature(
        identifier='load',
        placeholder_template_types=[pointee_type],
        return_type=ReferenceType(pointee_type),
        arg_identifiers=['ptr'],
        arg_types=[ptr_type],
        arg_type_narrowings=[ptr_type],
        instruction=lambda builder, ptr: ptr)
    symbol_table.add_overload('load', load_signature)

    assert 'store' not in symbol_table
    store_signature = BuiltinOperationFunctionSignature(
        identifier='store',
        placeholder_template_types=[pointee_type],
        return_type=SLEEPY_UNIT,
        arg_identifiers=['ptr', 'value'],
        arg_types=[ptr_type, pointee_type],
        arg_type_narrowings=[ptr_type, pointee_type],
        instruction=lambda builder, ptr, value: builder.store(value=value,
                                                              ptr=ptr))
    symbol_table.add_overload('store', store_signature)

    # cast from RawPtr -> Ptr[T] and Ref[T] -> Ptr[T]
    constructor_signature = BitcastFunctionSignature(
        placeholder_template_types=[pointee_type],
        return_type=ptr_type,
        arg_identifiers=['raw_ptr'],
        arg_types=[SLEEPY_RAW_PTR],
        arg_type_narrowings=[ptr_type])
    ref_cast_signature = BuiltinOperationFunctionSignature(
        identifier='Ptr',
        placeholder_template_types=[pointee_type],
        return_type=ptr_type,
        arg_identifiers=['reference'],
        arg_types=[ReferenceType(pointee_type)],
        arg_type_narrowings=[ReferenceType(pointee_type)],
        instruction=lambda builder, ptr: ptr)
    ptr_type.constructor = OverloadSet(
        'Ptr', [constructor_signature, ref_cast_signature])

    ptr_op_decls = [
        (BuiltinBinaryOps.Addition,
         [(lambda builder, lhs, rhs: builder.gep(lhs, (rhs, )), [ptr_type, i
                                                                 ], ptr_type)
          for i in INT_TYPES] +
         [(lambda builder, lhs, rhs: builder.gep(rhs, (lhs, )), [i, ptr_type
                                                                 ], ptr_type)
          for i in INT_TYPES]),
        (BuiltinBinaryOps.Subtraction, [(lambda builder, lhs, rhs: builder.gep(
            lhs,
            (builder.mul(ir.Constant(i.ir_type, -1), rhs), )), [ptr_type,
                                                                i], ptr_type)
                                        for i in INT_TYPES])
    ]
    ptr_op_decls += [(op, [
        (lambda builder, lhs, rhs, op=op: builder.icmp_unsigned(
            op.value, lhs, rhs), [ptr_type, ptr_type], SLEEPY_BOOL)
    ]) for op in Simple_Comparison_Ops]
    for operator, overloads in ptr_op_decls:
        for instruction, arg_types, return_type in overloads:
            signature = _make_func_signature(
                identifier=operator.value,
                instruction=instruction,
                op_placeholder_templ_types=[pointee_type],
                op_arg_types=arg_types,
                op_return_type=return_type)
            symbol_table.add_overload(operator.value, signature)

    free_signature = BuiltinOperationFunctionSignature(
        identifier='free',
        placeholder_template_types=[pointee_type],
        return_type=SLEEPY_UNIT,
        arg_identifiers=['ptr'],
        arg_types=[ptr_type],
        arg_type_narrowings=[SLEEPY_NEVER],
        instruction=lambda builder, value: SLEEPY_UNIT.unit_constant())
    symbol_table.add_overload('free', free_signature)
    return TypeTemplateSymbol(template_parameters=[pointee_type],
                              signature_type=ptr_type)