io interface (first pass)
This commit is contained in:
+113
-1
@@ -2051,6 +2051,116 @@ bodyless_root_main_recovers_as_a_trap_definition :: proc(t: ^testing.T) {
|
||||
testing.expect(t, !strings.contains(llvm_text, "declare i32 @main()"))
|
||||
}
|
||||
|
||||
@(test)
|
||||
milestone_33_injects_explicit_io_provider_and_runs_std_io :: proc(t: ^testing.T) {
|
||||
sources := source.init_store()
|
||||
defer source.destroy_store(&sources)
|
||||
diagnostics := source.init_store_diagnostics(&sources)
|
||||
defer source.destroy_diagnostics(&diagnostics)
|
||||
symbols := symbol.init_table()
|
||||
defer symbol.destroy_table(&symbols)
|
||||
ast_module, loaded := loader.load(
|
||||
"examples/programs/io",
|
||||
&sources,
|
||||
&diagnostics,
|
||||
&symbols,
|
||||
project_root_path=".",
|
||||
)
|
||||
defer ast.destroy_module(&ast_module)
|
||||
hir_module := checker.check(&ast_module, &diagnostics, &symbols)
|
||||
defer hir.destroy_module(&hir_module)
|
||||
ir_module := lower.lower(&hir_module)
|
||||
defer ir.destroy_module(&ir_module)
|
||||
llvm_text := llvm.emit(&ir_module, &diagnostics, &symbols)
|
||||
defer delete(llvm_text)
|
||||
|
||||
testing.expect(t, loaded)
|
||||
testing.expect_value(t, len(diagnostics.items), 0)
|
||||
testing.expect(t, hir_module.injected_main != hir.INVALID_FUNCTION)
|
||||
testing.expect(t, hir_module.io_provider != hir.INVALID_FUNCTION)
|
||||
testing.expect_value(t, count_substring_occurrences(llvm_text, "define i32 @main()"), 1)
|
||||
testing.expect_value(t, count_substring_occurrences(llvm_text, "define internal fastcc i32 @bro__p0__main__"), 1)
|
||||
testing.expect_value(t, count_substring_occurrences(llvm_text, "declare i64 @write("), 1)
|
||||
|
||||
output := "/tmp/brolang-test-io"
|
||||
defer _ = os.remove(output)
|
||||
status := compiler_core.compile_package(
|
||||
"examples/programs/io",
|
||||
output,
|
||||
nil,
|
||||
target.DEFAULT,
|
||||
cimport.Options{},
|
||||
".",
|
||||
)
|
||||
testing.expect_value(t, status, 0)
|
||||
state, stdout, stderr, _ := os2.process_exec(
|
||||
os2.Process_Desc{command=[]string{output}},
|
||||
context.allocator,
|
||||
)
|
||||
defer delete(stdout)
|
||||
defer delete(stderr)
|
||||
testing.expect_value(t, state.exit_code, 0)
|
||||
testing.expect_value(t, string(stdout), "io-ok\n")
|
||||
}
|
||||
|
||||
@(test)
|
||||
milestone_33_rejects_non_io_and_extra_main_parameters :: proc(t: ^testing.T) {
|
||||
cases := [?]string{
|
||||
"main func(value i32) void {}\n",
|
||||
"main func(left, right i32) void {}\n",
|
||||
}
|
||||
for text in cases {
|
||||
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)
|
||||
|
||||
found := false
|
||||
for diagnostic in diagnostics.items {
|
||||
found = found || strings.contains(
|
||||
diagnostic.message,
|
||||
"take no parameters or one @std/io Io",
|
||||
)
|
||||
}
|
||||
testing.expect(t, found)
|
||||
|
||||
hir.destroy_module(&hir_module)
|
||||
ast.destroy_module(&ast_module)
|
||||
delete(stream.items)
|
||||
symbol.destroy_table(&symbols)
|
||||
source.destroy_diagnostics(&diagnostics)
|
||||
}
|
||||
}
|
||||
|
||||
@(test)
|
||||
milestone_33_rejects_an_incompatible_runtime_write_declaration :: proc(t: ^testing.T) {
|
||||
text := `write c_func(_ c_int, _ c_int, _ c_ulong) c_long
|
||||
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)
|
||||
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,
|
||||
"external C function 'write' conflicts with the compiler runtime declaration",
|
||||
)
|
||||
}
|
||||
testing.expect(t, found)
|
||||
}
|
||||
|
||||
@(test)
|
||||
literal_addition_trees_fold_with_contextual_types :: proc(t: ^testing.T) {
|
||||
text := `return_i16 func() i16 {
|
||||
@@ -9911,8 +10021,9 @@ main func() i32 {
|
||||
value Animal = .cat
|
||||
values [2]Animal :: [.dog, Animal.bird]
|
||||
number Nat = identity(.two)
|
||||
ordinal c_int :: c_int(number)
|
||||
_ = variadic(0, number)
|
||||
if take(value) == Animal.cat and values[0] != values[1] and number == Nat.two {
|
||||
if take(value) == Animal.cat and values[0] != values[1] and number == Nat.two and ordinal == 2 {
|
||||
return 0
|
||||
}
|
||||
return 1
|
||||
@@ -9954,6 +10065,7 @@ main func() i32 {
|
||||
testing.expect_value(t, nat_members[0].value, i128(1))
|
||||
testing.expect_value(t, nat_members[1].value, i128(2))
|
||||
testing.expect_value(t, nat_members[2].value, i128(5))
|
||||
testing.expect(t, strings.contains(llvm_text, "zext i16"))
|
||||
testing.expect_value(t, types.runtime_representation(animal, &ast_module.type_store), types.U16)
|
||||
testing.expect_value(t, types.size(animal, &ast_module.type_store), u64(2))
|
||||
testing.expect(t, hir_module.globals[0].is_static)
|
||||
|
||||
Reference in New Issue
Block a user