function values as comptime params
This commit is contained in:
+91
-4
@@ -2789,9 +2789,7 @@ milestone_39_rejects_values_without_stable_identity :: proc(t: ^testing.T) {
|
||||
text := `BadUnion :: union { number i32, flag bool }
|
||||
Config :: struct { value i32 }
|
||||
|
||||
identity func() i32 { return 1 }
|
||||
reject_pointer func($value @i32) void {}
|
||||
reject_function func($value @func() i32) void {}
|
||||
reject_slice func($value []i32) void {}
|
||||
reject_range func($value range) void {}
|
||||
reject_union func($value BadUnion) void {}
|
||||
@@ -2802,7 +2800,6 @@ items [2]i32 :: [1, 2]
|
||||
|
||||
main func() void {
|
||||
reject_pointer(&stored)
|
||||
reject_function(identity)
|
||||
reject_slice(items[..])
|
||||
reject_range(0..3)
|
||||
reject_union(BadUnion {number = 1})
|
||||
@@ -2827,7 +2824,97 @@ main func() void {
|
||||
found += 1
|
||||
}
|
||||
}
|
||||
testing.expect(t, found >= 6)
|
||||
testing.expect(t, found >= 5)
|
||||
}
|
||||
|
||||
@(test)
|
||||
comptime_function_parameters_specialize_and_lower_directly :: proc(t: ^testing.T) {
|
||||
text := `Callback_Config :: struct { call @func(value i32) i32 }
|
||||
|
||||
increment func(value i32) i32 { return value + 1 }
|
||||
decrement func(value i32) i32 { return value - 1 }
|
||||
external c_func(value i32) i32
|
||||
|
||||
apply func($callback @func(value i32) i32, value i32) i32 {
|
||||
return callback(value)
|
||||
}
|
||||
|
||||
apply_c func($callback *c_func(value i32) i32, value i32) i32 {
|
||||
return callback(value)
|
||||
}
|
||||
|
||||
apply_config func($config Callback_Config, value i32) i32 {
|
||||
return config.call(value)
|
||||
}
|
||||
|
||||
main func() i32 {
|
||||
a i32 :: apply(increment, 1)
|
||||
b i32 :: apply(increment, 2)
|
||||
c i32 :: apply(decrement, 3)
|
||||
d i32 :: apply(func(value i32) i32 { return value + 2 }, 4)
|
||||
e i32 :: apply_c(external, 5)
|
||||
f i32 :: apply_config(Callback_Config {call = increment}, 6)
|
||||
return a + b + c + d + e + f
|
||||
}
|
||||
`
|
||||
stable_names: [dynamic]string
|
||||
defer {
|
||||
for name in stable_names {
|
||||
delete(name)
|
||||
}
|
||||
delete(stable_names)
|
||||
}
|
||||
for pass := 0; pass < 2; pass += 1 {
|
||||
source_file := source.Source{path="test.bro", text=text}
|
||||
diagnostics := source.init_diagnostics(&source_file)
|
||||
symbols := symbol.init_table()
|
||||
stream := lexer.lex(&source_file, &diagnostics, &symbols)
|
||||
ast_module := parser.parse(&stream, &source_file, &diagnostics)
|
||||
hir_module := checker.check(&ast_module, &diagnostics, &symbols)
|
||||
ir_module := lower.lower(&hir_module)
|
||||
|
||||
apply_count := 0
|
||||
callback_specializations := 0
|
||||
for function in ir_module.functions {
|
||||
plain_apply := strings.contains(function.link_name, "bro__p0__apply__")
|
||||
callback_specialization := plain_apply ||
|
||||
strings.contains(function.link_name, "bro__p0__apply_c__") ||
|
||||
strings.contains(function.link_name, "bro__p0__apply_config__")
|
||||
if !callback_specialization {
|
||||
continue
|
||||
}
|
||||
if plain_apply {
|
||||
apply_count += 1
|
||||
}
|
||||
if pass == 0 {
|
||||
append(&stable_names, strings.clone(function.link_name))
|
||||
} else {
|
||||
testing.expect_value(t, function.link_name, stable_names[callback_specializations])
|
||||
}
|
||||
callback_specializations += 1
|
||||
testing.expect_value(t, len(function.param_types), 1)
|
||||
found_direct_call := false
|
||||
for instruction in function.instructions {
|
||||
testing.expect(t, instruction.op != .Function_Address)
|
||||
if instruction.op == .Call {
|
||||
testing.expect(t, ir.as_function(instruction.target) != ir.INVALID_FUNCTION)
|
||||
found_direct_call = true
|
||||
}
|
||||
}
|
||||
testing.expect(t, found_direct_call)
|
||||
}
|
||||
|
||||
testing.expect_value(t, len(diagnostics.items), 0)
|
||||
testing.expect_value(t, apply_count, 3)
|
||||
testing.expect_value(t, callback_specializations, 5)
|
||||
|
||||
ir.destroy_module(&ir_module)
|
||||
hir.destroy_module(&hir_module)
|
||||
ast.destroy_module(&ast_module)
|
||||
delete(stream.items)
|
||||
symbol.destroy_table(&symbols)
|
||||
source.destroy_diagnostics(&diagnostics)
|
||||
}
|
||||
}
|
||||
|
||||
@(test)
|
||||
|
||||
Reference in New Issue
Block a user