comptime storage and function values
This commit is contained in:
+77
-7
@@ -293,6 +293,43 @@ main func() void {}
|
||||
testing.expect(t, params[0].type == types.C_INT)
|
||||
}
|
||||
|
||||
@(test)
|
||||
parser_accepts_native_function_pointer_types :: proc(t: ^testing.T) {
|
||||
text := `Error :: enum {
|
||||
bad
|
||||
}
|
||||
take func(callback ?*func(value i32) i32, fallible *func() i32 ! Error) void
|
||||
main func() void {}
|
||||
`
|
||||
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)
|
||||
module := parser.parse(&stream, &source_file, &diagnostics)
|
||||
defer ast.destroy_module(&module)
|
||||
|
||||
optional, optional_ok := types.node(&module.type_store, module.functions[0].params[0].type)
|
||||
pointer, pointer_ok := types.node(&module.type_store, optional.child)
|
||||
function, function_ok := types.node(&module.type_store, pointer.child)
|
||||
params := types.params_for(&module.type_store, pointer.child)
|
||||
fallible_pointer, fallible_pointer_ok := types.node(&module.type_store, module.functions[0].params[1].type)
|
||||
fallible_function, fallible_function_ok := types.node(&module.type_store, fallible_pointer.child)
|
||||
fallible, fallible_ok := types.node(&module.type_store, fallible_function.child)
|
||||
testing.expect_value(t, len(diagnostics.items), 0)
|
||||
testing.expect(t, optional_ok && optional.kind == .Optional)
|
||||
testing.expect(t, pointer_ok && pointer.kind == .Pointer && pointer.many && !pointer.mutable)
|
||||
testing.expect(t, function_ok && function.kind == .Function && !function.c_abi && !function.variadic)
|
||||
testing.expect(t, function.child == types.I32)
|
||||
testing.expect_value(t, len(params), 1)
|
||||
testing.expect(t, params[0].type == types.I32)
|
||||
testing.expect(t, fallible_pointer_ok && fallible_pointer.kind == .Pointer)
|
||||
testing.expect(t, fallible_function_ok && fallible_function.kind == .Function && !fallible_function.c_abi)
|
||||
testing.expect(t, fallible_ok && fallible.kind == .Fallible && fallible.child == types.I32)
|
||||
}
|
||||
|
||||
@(test)
|
||||
parser_accepts_c_function_pointer_alias_types :: proc(t: ^testing.T) {
|
||||
text := `callback_alias :: alias ?*c_func(value i32) i32
|
||||
@@ -882,13 +919,15 @@ main func() void {
|
||||
defer hir.destroy_module(&hir_module)
|
||||
|
||||
found_global := false
|
||||
found_function := false
|
||||
found_old_function_error := false
|
||||
for diagnostic in diagnostics.items {
|
||||
found_global = found_global || strings.contains(diagnostic.message, "'value' is a global, not a function")
|
||||
found_function = found_function || strings.contains(diagnostic.message, "'give' is a function, not a global value")
|
||||
found_old_function_error =
|
||||
found_old_function_error ||
|
||||
strings.contains(diagnostic.message, "'give' is a function, not a global value")
|
||||
}
|
||||
testing.expect(t, found_global)
|
||||
testing.expect(t, found_function)
|
||||
testing.expect(t, !found_old_function_error)
|
||||
}
|
||||
|
||||
@(test)
|
||||
@@ -2354,6 +2393,10 @@ main func() void {
|
||||
runtime i32 = 1
|
||||
_ = $runtime
|
||||
_ = $native()
|
||||
_ = ${
|
||||
callback :: native
|
||||
yield callback()
|
||||
}
|
||||
_ = $&GLOBAL
|
||||
_ = $spin()
|
||||
_ = $missing()
|
||||
@@ -2375,7 +2418,7 @@ main func() void {
|
||||
defer hir.destroy_module(&hir_module)
|
||||
|
||||
found_runtime := false
|
||||
found_external := false
|
||||
runtime_only_count := 0
|
||||
found_pointer := false
|
||||
found_quota := false
|
||||
found_missing := false
|
||||
@@ -2383,20 +2426,47 @@ main func() void {
|
||||
for diagnostic in diagnostics.items {
|
||||
message := diagnostic.message
|
||||
found_runtime = found_runtime || strings.contains(message, "unresolved comptime value 'runtime'")
|
||||
found_external = found_external || strings.contains(message, "runtime-only")
|
||||
found_pointer = found_pointer || strings.contains(message, "pointers and slices are not supported")
|
||||
runtime_only_count += 1 if strings.contains(message, "runtime-only") else 0
|
||||
found_pointer = found_pointer || strings.contains(message, "comptime storage pointers and slices cannot materialize as runtime memory")
|
||||
found_quota = found_quota || strings.contains(message, "comptime evaluation exceeded the step quota")
|
||||
found_missing = found_missing || strings.contains(message, "did not return a value")
|
||||
found_yield = found_yield || strings.contains(message, "comptime block must yield a value")
|
||||
}
|
||||
testing.expect(t, found_runtime)
|
||||
testing.expect(t, found_external)
|
||||
testing.expect(t, runtime_only_count >= 2)
|
||||
testing.expect(t, found_pointer)
|
||||
testing.expect(t, found_quota)
|
||||
testing.expect(t, found_missing)
|
||||
testing.expect(t, found_yield)
|
||||
}
|
||||
|
||||
@(test)
|
||||
native_function_pointer_type_restrictions_are_diagnosed :: proc(t: ^testing.T) {
|
||||
text := `main func() void {
|
||||
callback *func(...) void = undefined
|
||||
}
|
||||
`
|
||||
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)
|
||||
|
||||
found_variadic := false
|
||||
for diagnostic in diagnostics.items {
|
||||
found_variadic =
|
||||
found_variadic ||
|
||||
strings.contains(diagnostic.message, "native function pointer types do not support variadic parameters")
|
||||
}
|
||||
testing.expect(t, found_variadic)
|
||||
}
|
||||
|
||||
@(test)
|
||||
unused_function_signatures_are_validated_eagerly :: proc(t: ^testing.T) {
|
||||
text := `broken func(value, value i8, nope void) void {}
|
||||
|
||||
Reference in New Issue
Block a user