function literals (non-capturing)
This commit is contained in:
+46
-5
@@ -2913,19 +2913,21 @@ milestone_24_rejects_invalid_forms :: proc(t: ^testing.T) {
|
||||
}
|
||||
|
||||
@(test)
|
||||
field_function_pointer_calls_lower_as_indirect_calls :: proc(t: ^testing.T) {
|
||||
function_literals_lower_as_function_pointer_values :: proc(t: ^testing.T) {
|
||||
text := `Callbacks :: struct {
|
||||
call @func(value i32) i32
|
||||
value i32
|
||||
}
|
||||
plus_one func(value i32) i32 {
|
||||
return value + 1
|
||||
}
|
||||
run func(callbacks Callbacks) i32 {
|
||||
return callbacks.call(callbacks.value)
|
||||
}
|
||||
main func() i32 {
|
||||
callbacks Callbacks = Callbacks { call = plus_one, value = 41 }
|
||||
callbacks Callbacks = Callbacks {
|
||||
call = func(value i32) i32 {
|
||||
return value + 1
|
||||
},
|
||||
value = 41,
|
||||
}
|
||||
return run(callbacks) - 42
|
||||
}
|
||||
`
|
||||
@@ -2943,6 +2945,14 @@ main func() i32 {
|
||||
ir_module := lower.lower(&hir_module)
|
||||
defer ir.destroy_module(&ir_module)
|
||||
|
||||
generated_functions := 0
|
||||
literal_exprs := 0
|
||||
for function in ast_module.functions {
|
||||
generated_functions += 1 if function.generated else 0
|
||||
}
|
||||
for expr in ast_module.exprs {
|
||||
literal_exprs += 1 if expr.kind == .Function_Literal else 0
|
||||
}
|
||||
indirect_calls := 0
|
||||
for expr in hir_module.exprs {
|
||||
if expr.kind == .Call && expr.left != hir.INVALID_EXPR {
|
||||
@@ -2950,10 +2960,41 @@ main func() i32 {
|
||||
}
|
||||
}
|
||||
testing.expect_value(t, len(diagnostics.items), 0)
|
||||
testing.expect_value(t, generated_functions, 1)
|
||||
testing.expect_value(t, literal_exprs, 1)
|
||||
testing.expect(t, len(ir_module.functions) > 0)
|
||||
testing.expect(t, indirect_calls > 0)
|
||||
}
|
||||
|
||||
@(test)
|
||||
function_literals_do_not_capture_locals :: proc(t: ^testing.T) {
|
||||
text := `main func() i32 {
|
||||
offset i32 = 1
|
||||
callback @func(value i32) i32 = func(value i32) i32 {
|
||||
return value + offset
|
||||
}
|
||||
return callback(1)
|
||||
}
|
||||
`
|
||||
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 := false
|
||||
for diagnostic in diagnostics.items {
|
||||
found = found || strings.contains(diagnostic.message, "unresolved global 'offset'")
|
||||
}
|
||||
testing.expect(t, found)
|
||||
}
|
||||
|
||||
@(test)
|
||||
field_function_pointer_calls_reject_non_callable_fields :: proc(t: ^testing.T) {
|
||||
text := `Box :: struct {
|
||||
|
||||
Reference in New Issue
Block a user