richer formatting
This commit is contained in:
+126
-7
@@ -2461,7 +2461,10 @@ main func(init process.Init) void {
|
||||
io.print(writer, "{d}", {"bro",}) catch |_| {}
|
||||
io.print(writer, "{d}{d}", {1,}) catch |_| {}
|
||||
io.print(writer, "{d}", {1, 2}) catch |_| {}
|
||||
io.print(writer, "{x}", {}) catch |_| {}
|
||||
io.print(writer, "{q}", {}) catch |_| {}
|
||||
io.print(writer, "{b}", {1.5,}) catch |_| {}
|
||||
io.print(writer, "{e}", {1,}) catch |_| {}
|
||||
io.print(writer, "{c}", {i16(65),}) catch |_| {}
|
||||
io.print(writer, "}", {}) catch |_| {}
|
||||
}
|
||||
`
|
||||
@@ -2481,16 +2484,19 @@ main func(init process.Init) void {
|
||||
hir_module := checker.check(&ast_module, &diagnostics, &symbols)
|
||||
defer hir.destroy_module(&hir_module)
|
||||
|
||||
found := [7]bool{}
|
||||
found := [10]bool{}
|
||||
for diagnostic in diagnostics.items {
|
||||
message := diagnostic.message
|
||||
found[0] = found[0] || strings.contains(message, "arguments must be a tuple")
|
||||
found[1] = found[1] || strings.contains(message, "cannot implicitly convert i8 to []u8")
|
||||
found[2] = found[2] || strings.contains(message, "'{d}' requires an integer")
|
||||
found[2] = found[2] || strings.contains(message, "'{d}' requires an integer or float")
|
||||
found[3] = found[3] || strings.contains(message, "argument count does not match")
|
||||
found[4] = found[4] || strings.contains(message, "unknown specifier")
|
||||
found[5] = found[5] || strings.contains(message, "unmatched '}'")
|
||||
found[6] = found[6] || strings.contains(message, "compile-time-only metadata")
|
||||
found[7] = found[7] || strings.contains(message, "integer format requires an integer argument")
|
||||
found[8] = found[8] || strings.contains(message, "float format requires a float argument")
|
||||
found[9] = found[9] || strings.contains(message, "'{c}' requires an unsigned integer that fits in u8")
|
||||
}
|
||||
testing.expect(t, loaded)
|
||||
for present in found {
|
||||
@@ -2498,6 +2504,121 @@ main func(init process.Init) void {
|
||||
}
|
||||
}
|
||||
|
||||
@(test)
|
||||
milestone_39_stable_values_and_richer_formatting_compile_and_run :: proc(t: ^testing.T) {
|
||||
stable_names: [dynamic]string
|
||||
defer {
|
||||
for name in stable_names {
|
||||
delete(name)
|
||||
}
|
||||
delete(stable_names)
|
||||
}
|
||||
for pass := 0; pass < 2; pass += 1 {
|
||||
sources := source.init_store()
|
||||
diagnostics := source.init_store_diagnostics(&sources)
|
||||
symbols := symbol.init_table()
|
||||
ast_module, loaded := loader.load(
|
||||
"examples/programs/milestone_39", &sources, &diagnostics, &symbols, project_root_path=".",
|
||||
)
|
||||
hir_module := checker.check(&ast_module, &diagnostics, &symbols)
|
||||
ir_module := lower.lower(&hir_module)
|
||||
llvm_text := llvm.emit(&ir_module, &diagnostics, &symbols)
|
||||
|
||||
score_count := 0
|
||||
for function in hir_module.functions {
|
||||
if strings.contains(function.link_name, "bro__p0__score__ca") {
|
||||
if pass == 0 {
|
||||
append(&stable_names, strings.clone(function.link_name))
|
||||
} else {
|
||||
testing.expect_value(t, function.link_name, stable_names[score_count])
|
||||
}
|
||||
score_count += 1
|
||||
}
|
||||
}
|
||||
testing.expect(t, loaded)
|
||||
testing.expect_value(t, len(diagnostics.items), 0)
|
||||
testing.expect_value(t, score_count, 2)
|
||||
testing.expect_value(t, count_substring_occurrences(llvm_text, "define internal fastcc i32 @bro__p0__read_carrier__"), 1)
|
||||
testing.expect(t, !strings.contains(llvm_text, "FormatToken"))
|
||||
testing.expect(t, !strings.contains(llvm_text, "parse_format"))
|
||||
testing.expect(t, !strings.contains(llvm_text, "FieldInfo"))
|
||||
testing.expect(t, !strings.contains(llvm_text, "EnumInfo"))
|
||||
|
||||
delete(llvm_text)
|
||||
ir.destroy_module(&ir_module)
|
||||
hir.destroy_module(&hir_module)
|
||||
ast.destroy_module(&ast_module)
|
||||
symbol.destroy_table(&symbols)
|
||||
source.destroy_diagnostics(&diagnostics)
|
||||
source.destroy_store(&sources)
|
||||
}
|
||||
|
||||
output := "/tmp/brolang-test-milestone-39"
|
||||
defer _ = os.remove(output)
|
||||
status := compiler_core.compile_package(
|
||||
"examples/programs/milestone_39", 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),
|
||||
"true -42 1.5 .running bro 2.5 1010 12 ff FF A 1.5000000000000000e+00 {} -9223372036854775808 0 inf nan 1.50000000e+00\n",
|
||||
)
|
||||
testing.expect_value(t, string(stderr), "debug=.idle 2a\n")
|
||||
}
|
||||
|
||||
@(test)
|
||||
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 {}
|
||||
reject_undefined func($value Config) void {}
|
||||
|
||||
stored i32 :: 1
|
||||
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})
|
||||
reject_undefined(Config {value = 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 := 0
|
||||
for diagnostic in diagnostics.items {
|
||||
if strings.contains(diagnostic.message, "comptime argument has no stable comptime identity") {
|
||||
found += 1
|
||||
}
|
||||
}
|
||||
testing.expect(t, found >= 6)
|
||||
}
|
||||
|
||||
@(test)
|
||||
milestone_37_inline_loop_control_must_be_statically_resolvable :: proc(t: ^testing.T) {
|
||||
text := `main func() void {
|
||||
@@ -3327,12 +3448,13 @@ comptime_value_params_diagnose_invalid_uses :: proc(t: ^testing.T) {
|
||||
tiny func($N u8) i32 {
|
||||
return N
|
||||
}
|
||||
bad_type func($T bool) void {}
|
||||
good_bool func($T bool) void {}
|
||||
bad_use func($N usize) void {
|
||||
N = 1
|
||||
_ = &N
|
||||
}
|
||||
main func() void {
|
||||
good_bool(true)
|
||||
x usize = 4
|
||||
_ = make(x)
|
||||
_ = make()
|
||||
@@ -3359,7 +3481,6 @@ main func() void {
|
||||
found_extra := false
|
||||
found_negative := false
|
||||
found_range := false
|
||||
found_bad_type := false
|
||||
found_assignment := false
|
||||
found_address := false
|
||||
for diagnostic in diagnostics.items {
|
||||
@@ -3369,7 +3490,6 @@ main func() void {
|
||||
found_extra = found_extra || strings.contains(message, "has no unique complete argument mapping")
|
||||
found_negative = found_negative || strings.contains(message, "integer constant -1 does not fit in usize")
|
||||
found_range = found_range || strings.contains(message, "integer constant 300 does not fit in u8")
|
||||
found_bad_type = found_bad_type || strings.contains(message, "requires type, a concrete integer type, or immutable []u8")
|
||||
found_assignment = found_assignment || strings.contains(message, "cannot assign comptime parameter 'N'")
|
||||
found_address = found_address || strings.contains(message, "'&' requires an addressable location")
|
||||
}
|
||||
@@ -3379,7 +3499,6 @@ main func() void {
|
||||
testing.expect(t, found_extra)
|
||||
testing.expect(t, found_negative)
|
||||
testing.expect(t, found_range)
|
||||
testing.expect(t, found_bad_type)
|
||||
testing.expect(t, found_assignment)
|
||||
testing.expect(t, found_address)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user