typed alloc
This commit is contained in:
+91
-4
@@ -1413,6 +1413,83 @@ main func() i32 {
|
||||
testing.expect_value(t, state.exit_code, 0)
|
||||
}
|
||||
|
||||
@(test)
|
||||
integer_bound_builtins_compile_and_run :: proc(t: ^testing.T) {
|
||||
directory := "/tmp/brolang-test-integer-bounds"
|
||||
main_path := "/tmp/brolang-test-integer-bounds/main.bro"
|
||||
output := "/tmp/brolang-test-integer-bounds-output"
|
||||
text := `MAX_U64 u64 :: max_value(u64)
|
||||
|
||||
maximum func($T type) T {
|
||||
return max_value(T)
|
||||
}
|
||||
|
||||
main func() i32 {
|
||||
if (min_value(i8) != -128) return 1
|
||||
if (max_value(i8) != 127) return 2
|
||||
if (min_value(u8) != 0) return 3
|
||||
if (max_value(u8) != 255) return 4
|
||||
if (min_value(isize) != -9223372036854775808) return 5
|
||||
if (max_value(usize) != 18446744073709551615) return 6
|
||||
if (MAX_U64 != 18446744073709551615) return 7
|
||||
if (maximum(u16) != 65535) return 8
|
||||
if (min_value(c_int) != -2147483648) return 9
|
||||
if (max_value(c_ulong) != 18446744073709551615) return 10
|
||||
return 0
|
||||
}
|
||||
`
|
||||
_ = os2.remove_all(directory)
|
||||
defer _ = os2.remove_all(directory)
|
||||
defer _ = os.remove(output)
|
||||
testing.expect(t, os.make_directory(directory) == nil)
|
||||
testing.expect(t, os.write_entire_file(main_path, transmute([]byte)text))
|
||||
status := compiler_core.compile_package(directory, output)
|
||||
testing.expect_value(t, status, 0)
|
||||
state := run_executable(output)
|
||||
testing.expect_value(t, state.exit_code, 0)
|
||||
}
|
||||
|
||||
@(test)
|
||||
integer_bound_builtins_reject_invalid_targets :: proc(t: ^testing.T) {
|
||||
text := `Named :: distinct u8
|
||||
Choice :: enum { one }
|
||||
|
||||
main func() void {
|
||||
_ = min_value()
|
||||
_ = max_value(u8, u16)
|
||||
_ = min_value(1)
|
||||
_ = max_value(int)
|
||||
_ = max_value(f32)
|
||||
_ = max_value(bool)
|
||||
_ = max_value(Named)
|
||||
_ = max_value(Choice)
|
||||
}
|
||||
`
|
||||
source_file := source.Source{path="test.bro", text=text}
|
||||
diagnostics := source.init_diagnostics(&source_file)
|
||||
defer source.destroy_diagnostics(&diagnostics)
|
||||
symbols := symbol.init_table()
|
||||
defer symbol.destroy_table(&symbols)
|
||||
stream := lexer.lex(&source_file, &diagnostics, &symbols)
|
||||
defer delete(stream.items)
|
||||
ast_module := parser.parse(&stream, &source_file, &diagnostics)
|
||||
defer ast.destroy_module(&ast_module)
|
||||
hir_module := checker.check(&ast_module, &diagnostics, &symbols)
|
||||
defer hir.destroy_module(&hir_module)
|
||||
|
||||
bad_arity := 0
|
||||
bad_type := false
|
||||
bad_target := 0
|
||||
for diagnostic in diagnostics.items {
|
||||
bad_arity += 1 if strings.contains(diagnostic.message, "expects 1 argument") else 0
|
||||
bad_type = bad_type || strings.contains(diagnostic.message, "integer bound target must be a type")
|
||||
bad_target += 1 if strings.contains(diagnostic.message, "integer bound target must be a concrete integer type") else 0
|
||||
}
|
||||
testing.expect_value(t, bad_arity, 2)
|
||||
testing.expect(t, bad_type)
|
||||
testing.expect_value(t, bad_target, 5)
|
||||
}
|
||||
|
||||
@(test)
|
||||
layout_builtins_reject_unsized_targets :: proc(t: ^testing.T) {
|
||||
text := `Opaque :: opaque
|
||||
@@ -3281,6 +3358,7 @@ allocator_contract_c_allocator_global_lowers :: proc(t: ^testing.T) {
|
||||
|
||||
found_c_allocator := false
|
||||
found_anyopaque_context := false
|
||||
found_vtable_pointer := false
|
||||
found_alloc_callback := false
|
||||
found_realloc_callback := false
|
||||
found_free_callback := false
|
||||
@@ -3291,7 +3369,6 @@ allocator_contract_c_allocator_global_lowers :: proc(t: ^testing.T) {
|
||||
found_c_allocator = true
|
||||
for field in types.fields_for(&hir_module.types, global.type) {
|
||||
name := symbol.resolve(&symbols, symbol.Id(field.name))
|
||||
callback_pointer, _, _, callable := types.function_pointer(field.type, &hir_module.types)
|
||||
if name == "context" {
|
||||
optional_item, optional_ok := types.node(&hir_module.types, field.type)
|
||||
if optional_ok && optional_item.kind == .Optional {
|
||||
@@ -3302,10 +3379,19 @@ allocator_contract_c_allocator_global_lowers :: proc(t: ^testing.T) {
|
||||
pointer_item.many &&
|
||||
pointer_item.child == types.ANYOPAQUE
|
||||
}
|
||||
} else if name == "vtable" {
|
||||
pointer_item, pointer_ok := types.node(&hir_module.types, field.type)
|
||||
found_vtable_pointer = pointer_ok && pointer_item.kind == .Pointer && !pointer_item.mutable && !pointer_item.many
|
||||
if found_vtable_pointer {
|
||||
for callback in types.fields_for(&hir_module.types, pointer_item.child) {
|
||||
callback_name := symbol.resolve(&symbols, symbol.Id(callback.name))
|
||||
callback_pointer, _, _, callable := types.function_pointer(callback.type, &hir_module.types)
|
||||
found_alloc_callback = found_alloc_callback || callback_name == "alloc" && callable && !callback_pointer.many
|
||||
found_realloc_callback = found_realloc_callback || callback_name == "realloc" && callable && !callback_pointer.many
|
||||
found_free_callback = found_free_callback || callback_name == "free" && callable && !callback_pointer.many
|
||||
}
|
||||
}
|
||||
}
|
||||
found_alloc_callback = found_alloc_callback || name == "alloc" && callable && !callback_pointer.many
|
||||
found_realloc_callback = found_realloc_callback || name == "realloc" && callable && !callback_pointer.many
|
||||
found_free_callback = found_free_callback || name == "free" && callable && !callback_pointer.many
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3313,6 +3399,7 @@ allocator_contract_c_allocator_global_lowers :: proc(t: ^testing.T) {
|
||||
testing.expect(t, len(ir_module.functions) > 0)
|
||||
testing.expect(t, found_c_allocator)
|
||||
testing.expect(t, found_anyopaque_context)
|
||||
testing.expect(t, found_vtable_pointer)
|
||||
testing.expect(t, found_alloc_callback)
|
||||
testing.expect(t, found_realloc_callback)
|
||||
testing.expect(t, found_free_callback)
|
||||
|
||||
Reference in New Issue
Block a user