diff --git a/README.md b/README.md index 215e25c..7fb1bad 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ types. C primitives use atomic target-dependent names and remain semantically distinct from exact-width Brolang primitives: ```bro -strlen :: c_func(value *c_char) c_ulong +strlen c_func(value *c_char) c_ulong ``` Additional native inputs and libraries are passed to the final `zig cc` @@ -35,7 +35,7 @@ Relative `.h` imports create synthetic package namespaces backed by libclang: ```bro native :: import "../include/native.h" -main :: func() void { +main func() void { _ = native.imported_add(20, 22) } ``` @@ -63,11 +63,11 @@ from Brolang requires an explicit unwrap: ```bro native :: import "../include/native.h" -double :: c_func(value c_int) c_int { +double c_func(value c_int) c_int { return value + value } -call_mapper :: func(mapper native.Imported_Mapper) c_int { +call_mapper func(mapper native.Imported_Mapper) c_int { return mapper?(21) } ``` @@ -75,16 +75,16 @@ call_mapper :: func(mapper native.Imported_Mapper) c_int { Bodyless manual and imported C functions may be variadic: ```bro -log_values :: c_func(tag c_int, ...) c_int +log_values c_func(tag c_int, ...) c_int ``` Zero-terminated byte strings can be passed directly to immutable C character pointers without making `u8` and `c_char` generally interchangeable: ```bro -printf :: c_func(format *c_char, ...) c_int +printf c_func(format *c_char, ...) c_int -main :: func() void { +main func() void { _ = printf("answer: %d\n", 42) } ``` diff --git a/TODO.md b/TODO.md index 9048c90..cd91802 100644 --- a/TODO.md +++ b/TODO.md @@ -223,7 +223,7 @@ 14.5. backward type-demand propagation through call boundaries (DEFERRED) - a callee's result/return demand flows back through the function body to constrain - the caller's arguments, so `R u32 :: echo(A)` (with `echo :: func(p int) int`) + the caller's arguments, so `R u32 :: echo(A)` (with `echo func(p int) int`) resolves A to u32 instead of erroring at the call's result coercion - requires reversing the per-call data flow: a specialization's argument types (`spec.args`) become outputs to solve, not just inputs — a new back-edge threaded @@ -981,7 +981,7 @@ Milestone 23 v1 implements named error channels, native sum composition, `return Functions that can fail declare their error type after `!`: ``` -read_file :: func(path []u8) []u8 ! IoError { ... } +read_file func(path []u8) []u8 ! IoError { ... } ``` This reads as: "returns `[]u8` or fails with `IoError`." The space around `!` is idiomatic but not required. @@ -1035,7 +1035,7 @@ Functions that can fail with multiple error types use `|` to compose a named err ``` ProcessError :: alias IoError | ParseError -process :: func(path []u8) Ast ! ProcessError { ... } +process func(path []u8) Ast ! ProcessError { ... } ``` Parentheses are optional in the composed type and can aid readability: @@ -1053,7 +1053,7 @@ Inline error types are planned, but not part of milestone 23 v1. Use named enums Fallible functions use ordinary `return` for both channels. If the returned expression coerces to the success type `T`, the function returns success with channel code `0`. If it coerces to the error type `E`, the function returns the error with that variant's global tag id: ``` -parse_section :: func(p: @mut Parser) void ! ParseError { +parse_section func(p: @mut Parser) void ! ParseError { start_line Line = p.line p.advance() @@ -1086,7 +1086,7 @@ The `try` keyword unwraps a successful result or returns early with the error: ``` ProcessError :: alias IoError | ParseError -process :: func(path []u8) Ast ! ProcessError { +process func(path []u8) Ast ! ProcessError { data :: try read_file(path) # read_file also returns []u8 ! ProcessError in v1 ast :: try parse(data) # parse also returns Ast ! ProcessError in v1 return ast @@ -1195,7 +1195,7 @@ Brolang provides a **thread-local global heap allocator** that is: ``` import "std/mem/heap" -process :: func(input []u8) u64 { +process func(input []u8) u64 { # heap used for internal temporary work — does not escape temp := heap.alloc(u8, size: input.len * 2) defer heap.free(temp) @@ -1227,20 +1227,20 @@ import "std/mem" import "std/mem/heap" # Allocation escapes via return value — requires allocator -duplicate :: func(input []u8, allocator @mem.Allocator) []u8 { +duplicate func(input []u8, allocator @mem.Allocator) []u8 { result := allocator.alloc(u8, size: input.len) mem.copy(result, input) return result # caller manages this memory } # Allocation escapes via mutable parameter — requires allocator -init :: func(obj: @mut MyStruct, allocator: @mem.Allocator) void { +init func(obj: @mut MyStruct, allocator: @mem.Allocator) void { obj.buffer = allocator.alloc(u8, size: 100) # caller now knows heap memory was written into obj } # No allocation escapes — no allocator needed -process :: func(input: []u8) u64 { +process func(input: []u8) u64 { temp := heap.alloc(u8, size: input.len) defer heap.free(temp) # ... work with temp ... @@ -1248,11 +1248,11 @@ process :: func(input: []u8) u64 { } # No heap allocation at all — no allocator needed -reset :: func(obj: @mut MyStruct) void { +reset func(obj: @mut MyStruct) void { obj.count = 0 } -main :: func() void { +main func() void { data := duplicate("hello", heap) defer heap.free(data) @@ -1302,7 +1302,7 @@ For specialized needs, you create explicit allocator instances. These are not gl import "std/mem" import "std/mem/heap" -process_file :: func(path: []u8, allocator: @mem.Allocator) !Data { +process_file func(path: []u8, allocator: @mem.Allocator) !Data { # arena manages its own backing memory via heap arena := mem.Arena.init(heap, capacity: mem.megabytes(1)) defer arena.deinit() @@ -1333,17 +1333,17 @@ EntitySystem :: struct { pool: mem.Pool(Entity), } -init_entities :: func(allocator: @mem.Allocator) EntitySystem { +init_entities func(allocator: @mem.Allocator) EntitySystem { return EntitySystem{ pool = mem.Pool(Entity).init(allocator, capacity: 10_000), } } -spawn :: func(sys: @mut EntitySystem) @Entity { +spawn func(sys: @mut EntitySystem) @Entity { return sys.pool.alloc() # O(1), no fragmentation } -despawn :: func(sys: @mut EntitySystem, entity: @Entity) void { +despawn func(sys: @mut EntitySystem, entity: @Entity) void { sys.pool.free(entity) # returned to pool for reuse } ``` @@ -1356,7 +1356,7 @@ As described in the escaping allocation rule, when a function heap-allocates mem import "std/mem" # Function that uses caller's allocator -parse :: func(input: []u8, allocator: @mem.Allocator) !ParseResult { +parse func(input: []u8, allocator: @mem.Allocator) !ParseResult { buffer := allocator.alloc(u8, size: input.len) defer allocator.free(buffer) @@ -1367,7 +1367,7 @@ parse :: func(input: []u8, allocator: @mem.Allocator) !ParseResult { } # Caller decides which allocator to use -main :: func() void { +main func() void { # use an arena for this parsing work arena := mem.Arena.init(heap, capacity: mem.kilobytes(64)) defer arena.deinit() diff --git a/benchmarks/symbols/main.odin b/benchmarks/symbols/main.odin index 2b806b4..7256861 100644 --- a/benchmarks/symbols/main.odin +++ b/benchmarks/symbols/main.odin @@ -24,8 +24,8 @@ Metrics :: struct { make_source :: proc(repetitions: int, allocator := context.allocator) -> string { builder := strings.builder_make(allocator) defer strings.builder_destroy(&builder) - strings.write_string(&builder, "identity :: func(value int) int { return value }\n") - strings.write_string(&builder, "main :: func() i32 {\n\tacc i32 = 0\n") + strings.write_string(&builder, "identity func(value int) int { return value }\n") + strings.write_string(&builder, "main func() i32 {\n\tacc i32 = 0\n") for _ in 0 ..< repetitions { strings.write_string(&builder, "\t_ = identity(acc)\n\tacc = acc + 1\n") } diff --git a/compiler/parser/parser.odin b/compiler/parser/parser.odin index 2ab30d4..7e579e6 100644 --- a/compiler/parser/parser.odin +++ b/compiler/parser/parser.odin @@ -2256,6 +2256,11 @@ parse_top_level :: proc(parser: ^Parser) { } parser.cursor = saved } + if current(parser).kind == .Keyword_Func || current(parser).kind == .Keyword_C_Func { + c_abi := current(parser).kind == .Keyword_C_Func + parse_function(parser, name, c_abi) + return + } type_syntax := types.INVALID if is_type_token(current(parser).kind) { type_syntax = parse_type(parser) @@ -2271,6 +2276,8 @@ parse_top_level :: proc(parser: ^Parser) { if operator.kind == .Colon_Colon && (current(parser).kind == .Keyword_Func || current(parser).kind == .Keyword_C_Func) { + source.add(parser.diagnostics, span_from(name.span, current(parser).span), + "function declarations do not use '::'; write 'name func(...)' or 'name c_func(...)'") c_abi := current(parser).kind == .Keyword_C_Func parse_function(parser, name, c_abi) return diff --git a/compiler/translatec/translatec.odin b/compiler/translatec/translatec.odin index cf22fb6..4c43c97 100644 --- a/compiler/translatec/translatec.odin +++ b/compiler/translatec/translatec.odin @@ -279,7 +279,7 @@ emit_functions :: proc(b: ^strings.Builder, result: ^cimport.Result, record_name wrote = true continue } - fmt.sbprintf(b, "%s :: ", function.name) + fmt.sbprintf(b, "%s ", function.name) render_c_func(b, result, function.params, function.param_names, function.result, function.variadic, record_names) strings.write_byte(b, '\n') wrote = true diff --git a/compiler_tests.odin b/compiler_tests.odin index 7ebfefd..c3ba286 100644 --- a/compiler_tests.odin +++ b/compiler_tests.odin @@ -51,7 +51,7 @@ symbol_table_deduplicates_and_owns_spellings :: proc(t: ^testing.T) { compact_tokens_intern_only_identifiers_and_preserve_parser_text :: proc(t: ^testing.T) { text := `other :: import "../math" value :: 42 -main :: func() void { _ = value } +main func() void { _ = value } ` source_file := source.Source{path="test.bro", text=text} diagnostics := source.init_diagnostics(&source_file) @@ -138,7 +138,7 @@ compact_ids_reserve_invalid_values_and_preserve_layout :: proc(t: ^testing.T) { @(test) lexer_preserves_newlines_and_skips_comments :: proc(t: ^testing.T) { - source_file := source.Source{path="test.bro", text="# comment\nmain :: func() void {}\n"} + source_file := source.Source{path="test.bro", text="# comment\nmain func() void {}\n"} diagnostics := source.init_diagnostics(&source_file) defer source.destroy_diagnostics(&diagnostics) symbols := symbol.init_table() @@ -153,12 +153,12 @@ lexer_preserves_newlines_and_skips_comments :: proc(t: ^testing.T) { @(test) parser_accepts_grouped_params_and_multiline_statements :: proc(t: ^testing.T) { - text := `sum :: func(a, + text := `sum func(a, b int) int { return (a + b) } -main :: func() void {} +main func() void {} ` source_file := source.Source{path="test.bro", text=text} diagnostics := source.init_diagnostics(&source_file) @@ -177,10 +177,10 @@ main :: func() void {} @(test) parser_accepts_sentinel_many_item_pointer_types :: proc(t: ^testing.T) { - text := `zero :: func(value [*;0]u8) void {} -newline :: func(value [*;'\n']mut u8) void {} -nullable :: func(value ?[*;0]u8) void {} -main :: func() void {} + text := `zero func(value [*;0]u8) void {} +newline func(value [*;'\n']mut u8) void {} +nullable func(value ?[*;0]u8) void {} +main func() void {} ` source_file := source.Source{path="test.bro", text=text} diagnostics := source.init_diagnostics(&source_file) @@ -207,8 +207,8 @@ main :: func() void {} @(test) parser_accepts_c_function_pointer_types :: proc(t: ^testing.T) { - text := `take :: c_func(callback ?*c_func(value c_int) c_int) void -main :: func() void {} + text := `take c_func(callback ?*c_func(value c_int) c_int) void +main func() void {} ` source_file := source.Source{path="test.bro", text=text} diagnostics := source.init_diagnostics(&source_file) @@ -233,10 +233,63 @@ main :: func() void {} testing.expect(t, params[0].type == types.C_INT) } +@(test) +parser_accepts_c_function_pointer_alias_types :: proc(t: ^testing.T) { + text := `callback_alias :: alias ?*c_func(value i32) i32 +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) + + name := symbol.intern(&symbols, "callback_alias") + alias := types.find_named(&module.type_store, 0, u32(name)) + alias_node, alias_ok := types.node(&module.type_store, alias) + optional, optional_ok := types.node(&module.type_store, alias_node.child) + pointer, pointer_ok := types.node(&module.type_store, optional.child) + function, function_ok := types.node(&module.type_store, pointer.child) + testing.expect_value(t, len(diagnostics.items), 0) + testing.expect(t, alias_ok && alias_node.kind == .Alias) + testing.expect(t, optional_ok && optional.kind == .Optional) + testing.expect(t, pointer_ok && pointer.kind == .Pointer) + testing.expect(t, function_ok && function.kind == .Function && function.c_abi) +} + +@(test) +parser_rejects_old_function_declaration_binding_syntax :: proc(t: ^testing.T) { + text := `main :: func() void {} +foreign :: c_func() i32 +` + 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) + + found := 0 + for diagnostic in diagnostics.items { + if strings.contains(diagnostic.message, "function declarations do not use '::'") { + found += 1 + } + } + testing.expect_value(t, found, 2) + testing.expect_value(t, len(module.functions), 2) +} + @(test) parser_diagnoses_malformed_sentinel_pointer_types :: proc(t: ^testing.T) { - text := `bad :: func(value [*0]u8) void {} -main :: func() void {} + text := `bad func(value [*0]u8) void {} +main func() void {} ` source_file := source.Source{path="test.bro", text=text} diagnostics := source.init_diagnostics(&source_file) @@ -257,8 +310,8 @@ main :: func() void {} @(test) parser_accepts_single_statement_one_line_functions :: proc(t: ^testing.T) { - text := `give :: func() i8 { return 7 } -main :: func() void { _ = give() } + text := `give func() i8 { return 7 } +main func() void { _ = give() } ` source_file := source.Source{path="test.bro", text=text} diagnostics := source.init_diagnostics(&source_file) @@ -280,13 +333,13 @@ main :: func() void { _ = give() } @(test) parser_distinguishes_bodyless_declarations_and_definitions :: proc(t: ^testing.T) { - text := `foreign :: c_func(value i32) i32 -defined :: c_func(value i32) i32 + text := `foreign c_func(value i32) i32 +defined c_func(value i32) i32 { return value } -native :: func() i32 -main :: func() void {} +native func() i32 +main func() void {} ` source_file := source.Source{path="test.bro", text=text} diagnostics := source.init_diagnostics(&source_file) @@ -312,10 +365,10 @@ main :: func() void {} @(test) parser_accepts_terminal_c_variadic_markers_and_recovers_nonterminal_markers :: proc(t: ^testing.T) { - text := `fixed :: c_func(value c_int, ...) c_int -zero :: c_func(...) void -bad :: c_func(..., value c_int) c_int -main :: func() void {} + text := `fixed c_func(value c_int, ...) c_int +zero c_func(...) void +bad c_func(..., value c_int) c_int +main func() void {} ` source_file := source.Source{path="test.bro", text=text} diagnostics := source.init_diagnostics(&source_file) @@ -346,9 +399,9 @@ main :: func() void {} parser_treats_c_as_contextual_only_before_func :: proc(t: ^testing.T) { text := `c :: 5 x :: c -foreign :: c_func() i32 +foreign c_func() i32 broken :: c 5 -main :: func() void {} +main func() void {} ` source_file := source.Source{path="test.bro", text=text} diagnostics := source.init_diagnostics(&source_file) @@ -377,7 +430,7 @@ main :: func() void {} @(test) parser_accepts_undefined_expression :: proc(t: ^testing.T) { - text := `main :: func() void { + text := `main func() void { value i32 = undefined } ` @@ -403,7 +456,7 @@ parser_accepts_undefined_expression :: proc(t: ^testing.T) { @(test) pratt_parser_preserves_left_associative_addition_shape :: proc(t: ^testing.T) { - source_file := source.Source{path="test.bro", text="value :: 1 + 2 + 3\nmain :: func() void {}\n"} + source_file := source.Source{path="test.bro", text="value :: 1 + 2 + 3\nmain func() void {}\n"} diagnostics := source.init_diagnostics(&source_file) defer source.destroy_diagnostics(&diagnostics) symbols := symbol.init_table() @@ -422,12 +475,12 @@ pratt_parser_preserves_left_associative_addition_shape :: proc(t: ^testing.T) { @(test) pratt_parser_handles_prefix_negation_precedence :: proc(t: ^testing.T) { - text := `identity :: func(value i8) i8 { return value } + text := `identity func(value i8) i8 { return value } loose :: -1 + 2 grouped :: -(1 + 2) called :: -identity(1) chained :: --1 -main :: func() void {} +main func() void {} ` source_file := source.Source{path="test.bro", text=text} diagnostics := source.init_diagnostics(&source_file) @@ -458,7 +511,7 @@ nested_expression_source :: proc(call: bool, depth: int) -> string { builder := strings.builder_make() defer strings.builder_destroy(&builder) if call { - strings.write_string(&builder, "identity :: func(value i32) i32 { return value }\nvalue :: ") + strings.write_string(&builder, "identity func(value i32) i32 { return value }\nvalue :: ") for _ in 0.. string { for _ in 0.. string { for _ in 0..= lo and key < hi` (inclusive uses // `<=`), emitted as signed integer comparisons for an i32 subject. - text := `main :: func() i32 { + text := `main func() i32 { n i32 = 5 out i32 = 0 match n { @@ -2603,7 +2656,7 @@ Box :: union(enum) { count i32 empty void } -void_capture :: func(b Box) i32 { +void_capture func(b Box) i32 { match b { .point |p|: { return p.x } .count |c|: { return c } @@ -2611,29 +2664,29 @@ void_capture :: func(b Box) i32 { } return 0 } -void_value :: func() i32 { +void_value func() i32 { b Box = Box{ empty = 5 } return 0 } -bare_on_nonvoid :: func() i32 { +bare_on_nonvoid func() i32 { b Box = Box{ count } return 0 } -range_on_enum :: func(a Animal) i32 { +range_on_enum func(a Animal) i32 { match a { 0..2: { return 1 } else: { return 0 } } return 0 } -incompatible_capture :: func(b Box) i32 { +incompatible_capture func(b Box) i32 { match b { .point, .count |v|: { return 0 } .empty: { return 0 } } return 0 } -main :: func() i32 { +main func() i32 { b Box = Box{ count = 1 } return void_capture(b) + void_value() + bare_on_nonvoid() + range_on_enum(.dog) + incompatible_capture(b) @@ -2685,10 +2738,10 @@ Box :: union(enum) { count i32 empty void } -get :: func() Animal { +get func() Animal { return .bird } -main :: func() i32 { +main func() i32 { e Box = .empty r i32 = 0 match get() { @@ -2735,11 +2788,11 @@ Box :: union(enum) { point Point empty void } -bad :: func() i32 { +bad func() i32 { e Box = .point return 0 } -main :: func() i32 { +main func() i32 { return bad() } ` @@ -2766,7 +2819,7 @@ main :: func() i32 { yield_misuse_is_diagnosed :: proc(t: ^testing.T) { // A value block that does not end in `yield`, and a `yield` nested inside an // `if` within a value block (only the final statement may yield). - text := `main :: func() i32 { + text := `main func() i32 { missing :: { k :: 5 } @@ -2808,7 +2861,7 @@ yield_control_flow_is_diagnosed :: proc(t: ^testing.T) { // fall-through `yield`; a `yield :label` with no matching value loop; a labeled value // block that does not yield on every path; a `break :label` naming no loop; and a // `continue :label` targeting a block (not a loop). - text := `main :: func() i32 { + text := `main func() i32 { noelse :: if (true) { yield 1 } @@ -3110,7 +3163,7 @@ checked_runtime_negation_traps_for_every_signed_width :: proc(t: ^testing.T) { builder := strings.builder_make() fmt.sbprintf( &builder, - "negate :: func(value %s) %s {{ return -value }}\nmain :: func() void {{ _ = negate(-%s) }}\n", + "negate func(value %s) %s {{ return -value }}\nmain func() void {{ _ = negate(-%s) }}\n", test_case.type_name, test_case.type_name, test_case.magnitude, @@ -3156,7 +3209,7 @@ constant_beyond_i64_produces_trap_executable :: proc(t: ^testing.T) { @(test) same_line_statements_are_diagnosed :: proc(t: ^testing.T) { - text := "main :: func() void { _ = 1 _ = 2 }\n" + text := "main func() void { _ = 1 _ = 2 }\n" source_file := source.Source{path="test.bro", text=text} diagnostics := source.init_diagnostics(&source_file) defer source.destroy_diagnostics(&diagnostics) @@ -4115,7 +4168,7 @@ source_store_owns_buffers_indexes_lines_and_deduplicates_diagnostics :: proc(t: @(test) maximum_signed_i64_literal_parses_exactly :: proc(t: ^testing.T) { - source_file := source.Source{path="test.bro", text="value :: 9223372036854775807\nmain :: func() void {}\n"} + source_file := source.Source{path="test.bro", text="value :: 9223372036854775807\nmain func() void {}\n"} diagnostics := source.init_diagnostics(&source_file) defer source.destroy_diagnostics(&diagnostics) symbols := symbol.init_table() @@ -4134,7 +4187,7 @@ negative_constants_fold_and_accept_signed_i64_minimum :: proc(t: ^testing.T) { text := `minimum :: -9223372036854775808 grouped i64 :: -(9223372036854775808) folded :: -(1 + 2) -main :: func() void {} +main func() void {} ` source_file := source.Source{path="test.bro", text=text} diagnostics := source.init_diagnostics(&source_file) @@ -4160,7 +4213,7 @@ main :: func() void {} @(test) constant_division_by_zero_has_a_precise_diagnostic :: proc(t: ^testing.T) { text := `value :: 5 / 0 -main :: func() void {} +main func() void {} ` source_file := source.Source{path="test.bro", text=text} diagnostics := source.init_diagnostics(&source_file) @@ -4193,7 +4246,7 @@ below_minimum :: -9223372036854775809 double_minimum :: --9223372036854775808 maximum_u64 :: 18446744073709551615 beyond_u64 :: 18446744073709551616 -main :: func() void {} +main func() void {} ` source_file := source.Source{path="test.bro", text=text} diagnostics := source.init_diagnostics(&source_file) @@ -4219,13 +4272,13 @@ main :: func() void {} @(test) runtime_negation_preserves_operand_type_before_result_widening :: proc(t: ^testing.T) { - text := `negate_i8 :: func(value i8) i8 { + text := `negate_i8 func(value i8) i8 { return -value } -widen_after_negate :: func(value i8) i16 { +widen_after_negate func(value i8) i16 { return -value } -main :: func() void { +main func() void { _ = negate_i8(1) _ = widen_after_negate(1) } @@ -4354,11 +4407,11 @@ malformed_ir_emits_traps_and_typed_sentinels :: proc(t: ^testing.T) { hundred_thousand_term_runtime_addition_uses_iterative_pipeline :: proc(t: ^testing.T) { builder := strings.builder_make() defer strings.builder_destroy(&builder) - strings.write_string(&builder, "sum :: func(value i32) i32 { return value") + strings.write_string(&builder, "sum func(value i32) i32 { return value") for _ in 0..<100_000 { strings.write_string(&builder, " + 1") } - strings.write_string(&builder, " }\nmain :: func() void { _ = sum(0) }\n") + strings.write_string(&builder, " }\nmain func() void { _ = sum(0) }\n") source_file := source.Source{path="test.bro", text=strings.to_string(builder)} diagnostics := source.init_diagnostics(&source_file) defer source.destroy_diagnostics(&diagnostics) @@ -4864,12 +4917,12 @@ deeply_nested_child_packages_load_recursively :: proc(t: ^testing.T) { @(test) function_returning_only_in_if_branch_is_diagnosed :: proc(t: ^testing.T) { - text := `classify :: func(n i32) i32 { + text := `classify func(n i32) i32 { if n > 0 { return 1 } } -main :: func() void { +main func() void { _ = classify(5) } ` @@ -4894,14 +4947,14 @@ main :: func() void { @(test) function_returning_in_both_if_arms_is_accepted :: proc(t: ^testing.T) { - text := `classify :: func(n i32) i32 { + text := `classify func(n i32) i32 { if n > 0 { return 1 } else { return 0 } } -main :: func() void { +main func() void { _ = classify(5) } ` @@ -4926,13 +4979,13 @@ main :: func() void { @(test) function_returning_after_if_is_accepted :: proc(t: ^testing.T) { - text := `classify :: func(n i32) i32 { + text := `classify func(n i32) i32 { if n > 0 { return 1 } return 0 } -main :: func() void { +main func() void { _ = classify(5) } ` @@ -4969,7 +5022,7 @@ conditional_unwrap_compiles_and_runs :: proc(t: ^testing.T) { @(test) conditional_unwrap_parser_captures_guard_and_parenthesized_chain :: proc(t: ^testing.T) { - text := `main :: func() void { + text := `main func() void { first ?i32 = 1 second ?i32 = 2 if (first and second) |a, b : a == 1 and b == 2| { @@ -5000,8 +5053,8 @@ conditional_unwrap_parser_captures_guard_and_parenthesized_chain :: proc(t: ^tes @(test) parser_accepts_braceless_if_bodies :: proc(t: ^testing.T) { - text := `ready :: func() bool { return true } -main :: func() void { + text := `ready func() bool { return true } +main func() void { x i32 = 0 if (x == 0) x = 1 if ready() x = 2 @@ -5050,7 +5103,7 @@ main :: func() void { @(test) parser_diagnoses_braceless_if_without_parens_or_call :: proc(t: ^testing.T) { - text := `main :: func() void { + text := `main func() void { x i32 = 0 if x == 0 x = 1 } @@ -5074,8 +5127,8 @@ braceless_if_compiles_and_runs :: proc(t: ^testing.T) { directory := "/tmp/brolang-test-braceless-if" main_path := "/tmp/brolang-test-braceless-if/main.bro" output := "/tmp/brolang-test-braceless-if-output" - text := `ready :: func() bool { return true } -main :: func() i32 { + text := `ready func() bool { return true } +main func() i32 { x i32 = 0 if (x == 0) x = 1 else x = 2 if ready() x = x + 10 @@ -5098,7 +5151,7 @@ main :: func() i32 { @(test) conditional_unwrap_allows_sink_captures :: proc(t: ^testing.T) { - text := `main :: func() void { + text := `main func() void { first ?i32 = 1 second ?i32 = 2 if first and second |_, value : value == 2| { @@ -5134,22 +5187,22 @@ parser_diagnoses_malformed_conditional_unwrap_captures_and_guards :: proc(t: ^te text: string, needle: string, }{ - {`main :: func() void { + {`main func() void { value ?i32 = 1 if value || {} } `, "expected an unwrap capture name"}, - {`main :: func() void { + {`main func() void { value ?i32 = 1 if value |capture,| {} } `, "expected an unwrap capture after ','"}, - {`main :: func() void { + {`main func() void { value ?i32 = 1 if value |capture :| {} } `, "expected a guard expression after ':'"}, - {`main :: func() void { + {`main func() void { value ?i32 = 1 if value |capture {} } @@ -5177,7 +5230,7 @@ parser_diagnoses_malformed_conditional_unwrap_captures_and_guards :: proc(t: ^te @(test) if_unwrap_on_non_optional_is_diagnosed :: proc(t: ^testing.T) { - text := `main :: func() i32 { + text := `main func() i32 { x i32 = 5 if x |v| { return v @@ -5206,7 +5259,7 @@ if_unwrap_on_non_optional_is_diagnosed :: proc(t: ^testing.T) { @(test) conditional_unwrap_diagnostics_cover_counts_guards_and_capture_scope :: proc(t: ^testing.T) { - text := `main :: func() void { + text := `main func() void { first ?i32 = 1 second ?i32 = 2 plain i32 = 3 @@ -5276,7 +5329,7 @@ conditional_unwrap_diagnostics_cover_counts_guards_and_capture_scope :: proc(t: @(test) if_unwrap_binding_is_scoped_to_then_block :: proc(t: ^testing.T) { // The binding `v` is usable in the then-block but not in the else-block. - text := `main :: func() i32 { + text := `main func() i32 { a ?i32 = 1 if a |v| { return v @@ -5306,7 +5359,7 @@ if_unwrap_binding_is_scoped_to_then_block :: proc(t: ^testing.T) { @(test) if_unwrap_binding_is_immutable :: proc(t: ^testing.T) { - text := `main :: func() i32 { + text := `main func() i32 { a ?i32 = 1 if a |v| { v = 2 @@ -5346,29 +5399,29 @@ while_loops_compile_and_run :: proc(t: ^testing.T) { @(test) while_loop_diagnostics_cover_condition_update_and_scope :: proc(t: ^testing.T) { - text := `bad_condition :: func() void { + text := `bad_condition func() void { while 1 {} } -bad_unresolved :: func() void { +bad_unresolved func() void { while false : missing = 1 {} } -bad_immutable :: func() void { +bad_immutable func() void { i :: 0 while false : i = i + 1 {} } -bad_body_scope :: func() void { +bad_body_scope func() void { running :: false while running : i = 1 { i u32 = 0 } } -bad_declaration_update :: func() void { +bad_declaration_update func() void { while false : i u32 = 0 {} } -bad_missing_update :: func() void { +bad_missing_update func() void { while false : {} } -main :: func() void { +main func() void { bad_condition() bad_unresolved() bad_immutable() @@ -5413,15 +5466,15 @@ main :: func() void { @(test) while_true_and_potential_fallthrough_have_distinct_return_analysis :: proc(t: ^testing.T) { - text := `forever :: func() i32 { + text := `forever func() i32 { while true {} } -maybe :: func(run bool) i32 { +maybe func(run bool) i32 { while run { return 1 } } -main :: func() void { +main func() void { if false { _ = forever() } @@ -5451,7 +5504,7 @@ main :: func() void { @(test) while_loop_allocas_are_emitted_in_the_entry_block :: proc(t: ^testing.T) { - text := `main :: func() i32 { + text := `main func() i32 { i u32 = 0 while i < 2 and true : i = i + 1 { value u32 = i @@ -5499,7 +5552,7 @@ while_loop_allocas_are_emitted_in_the_entry_block :: proc(t: ^testing.T) { @(test) for_loop_tokens_and_parser_capture_range_shape :: proc(t: ^testing.T) { - text := `main :: func() void { + text := `main func() void { for 0..4 |value| { _ = value } @@ -5556,7 +5609,7 @@ for_loop_tokens_and_parser_capture_range_shape :: proc(t: ^testing.T) { @(test) range_bound_parenthesization_is_enforced :: proc(t: ^testing.T) { - text := `main :: func() void { + text := `main func() void { limit :: 3 for 0..limit + 1 |bad| { _ = bad @@ -5589,19 +5642,19 @@ parser_diagnoses_malformed_for_captures :: proc(t: ^testing.T) { text: string, needle: string, }{ - {`main :: func() void { + {`main func() void { for [1] item {} } `, "expected '|' before for-loop captures"}, - {`main :: func() void { + {`main func() void { for [1] |@| {} } `, "expected a for-loop item capture"}, - {`main :: func() void { + {`main func() void { for [1] |item,| {} } `, "expected an index capture after ','"}, - {`main :: func() void { + {`main func() void { for [1] |item {} } `, "expected '|' to close for-loop captures"}, @@ -5648,68 +5701,68 @@ range_loop_edges_compile_and_run :: proc(t: ^testing.T) { @(test) for_loop_diagnostics_cover_iterables_captures_and_scope :: proc(t: ^testing.T) { - text := `bad_iterable :: func() void { + text := `bad_iterable func() void { for 1 |item| { _ = item } } -bad_array_pointer_capture :: func() void { +bad_array_pointer_capture func() void { for [1] |@item| { _ = item } } -bad_range_pointer_capture :: func() void { +bad_range_pointer_capture func() void { for 0..1 |@item| { _ = item } } -bad_range_index_capture :: func() void { +bad_range_index_capture func() void { for 0..1 |item, index| { _ = item _ = index } } -bad_duplicate_capture :: func() void { +bad_duplicate_capture func() void { for [1] |item, item| { _ = item } } -bad_capture_redeclaration :: func() void { +bad_capture_redeclaration func() void { for [1] |item| { item i32 = 2 _ = item } } -bad_capture_assignment :: func() void { +bad_capture_assignment func() void { for [1] |item| { item = 2 } } -bad_immutable_pointer_capture :: func() void { +bad_immutable_pointer_capture func() void { items :: [1] for (&items) |@item| { item^ = 2 } } -bad_scope :: func() void { +bad_scope func() void { for [1] |item| { _ = item } _ = item } -bad_integer_bounds :: func() void { +bad_integer_bounds func() void { start i32 = 0 end u32 = 1 for start..end |item| { _ = item } } -bad_float_bounds :: func() void { +bad_float_bounds func() void { for 0.0..1.0 |item| { _ = item } } -main :: func() void { +main func() void { bad_iterable() bad_array_pointer_capture() bad_range_pointer_capture() @@ -5771,7 +5824,7 @@ main :: func() void { @(test) for_pointer_capture_respects_pointer_and_array_mutability :: proc(t: ^testing.T) { - text := `readonly :: func() void { + text := `readonly func() void { values [1]mut i32 = [1] items @[1]mut i32 = &values items[0] = 7 @@ -5779,7 +5832,7 @@ for_pointer_capture_respects_pointer_and_array_mutability :: proc(t: ^testing.T) item^ = 7 } } -writable :: func() void { +writable func() void { values [1]mut i32 = [1] items @mut [1]mut i32 = &values items[0] = 7 @@ -5787,7 +5840,7 @@ writable :: func() void { item^ = 7 } } -main :: func() void { +main func() void { readonly() writable() } @@ -5816,16 +5869,16 @@ pointer_field_passthrough_respects_pointee_mutability :: proc(t: ^testing.T) { text := `Point :: struct { x i32 } -readonly :: func(point @Point) i32 { +readonly func(point @Point) i32 { return point.x } -bad_write :: func(point @Point) void { +bad_write func(point @Point) void { point.x = 7 } -writable :: func(point @mut Point) void { +writable func(point @mut Point) void { point.x += 1 } -main :: func() i32 { +main func() i32 { point Point = Point { x = 41 } writable(&point) bad_write(&point) @@ -5853,13 +5906,13 @@ main :: func() i32 { @(test) equal_range_returns_infer_a_usable_result_type :: proc(t: ^testing.T) { - text := `choose :: func(first bool) range { + text := `choose func(first bool) range { if first { return 0..1 } return 2..3 } -main :: func() i32 { +main func() i32 { total i32 = 0 for choose(false) |value| { total = total + value @@ -5898,13 +5951,13 @@ main :: func() i32 { @(test) for_loop_lowering_evaluates_once_and_avoids_index_bounds_checks :: proc(t: ^testing.T) { - text := `make_range :: func() range { + text := `make_range func() range { return 0..2 } -make_array :: func() [2]i32 { +make_array func() [2]i32 { return [1, 2] } -main :: func() i32 { +main func() i32 { total i32 = 0 for make_range() |value| { total = total + value @@ -5987,7 +6040,7 @@ lexer_emits_compound_assignment_and_slash_tokens :: proc(t: ^testing.T) { @(test) binary_operators_respect_multiplicative_precedence :: proc(t: ^testing.T) { - source_file := source.Source{path="test.bro", text="value :: 1 + 2 * 3\nmain :: func() void {}\n"} + source_file := source.Source{path="test.bro", text="value :: 1 + 2 * 3\nmain func() void {}\n"} diagnostics := source.init_diagnostics(&source_file) defer source.destroy_diagnostics(&diagnostics) symbols := symbol.init_table() @@ -6006,7 +6059,7 @@ binary_operators_respect_multiplicative_precedence :: proc(t: ^testing.T) { @(test) division_parses_left_associatively :: proc(t: ^testing.T) { - source_file := source.Source{path="test.bro", text="value :: 8 / 4 / 2\nmain :: func() void {}\n"} + source_file := source.Source{path="test.bro", text="value :: 8 / 4 / 2\nmain func() void {}\n"} diagnostics := source.init_diagnostics(&source_file) defer source.destroy_diagnostics(&diagnostics) symbols := symbol.init_table() @@ -6025,7 +6078,7 @@ division_parses_left_associatively :: proc(t: ^testing.T) { @(test) compound_assignment_preserves_operation_and_rhs :: proc(t: ^testing.T) { - text := `main :: func() void { + text := `main func() void { x i32 = 0 x += 5 } @@ -6053,7 +6106,7 @@ compound_assignment_preserves_operation_and_rhs :: proc(t: ^testing.T) { @(test) undefined_inferred_local_lowers_to_fill :: proc(t: ^testing.T) { - text := `choose :: func(flag bool) i32 { + text := `choose func(flag bool) i32 { value int = undefined if flag { value = 42 @@ -6062,7 +6115,7 @@ undefined_inferred_local_lowers_to_fill :: proc(t: ^testing.T) { } return value } -main :: func() i32 { +main func() i32 { return choose(true) } ` @@ -6108,12 +6161,12 @@ main :: func() i32 { @(test) local_int_inference_widens_from_assignments :: proc(t: ^testing.T) { - text := `wide :: func() int { + text := `wide func() int { value int = 1 value = 1000 return value } -main :: func() void { +main func() void { _ = wide() } ` @@ -6176,11 +6229,11 @@ float_result_type :: proc(hir_module: ^hir.Module, symbols: ^symbol.Table, funct @(test) float_constraint_resolves_to_f64 :: proc(t: ^testing.T) { - text := `make :: func() float { + text := `make func() float { pi float = 3.14 return pi } -main :: func() void { +main func() void { _ = make() } ` @@ -6207,11 +6260,11 @@ main :: func() void { @(test) float_constraint_accepts_integer_literal :: proc(t: ^testing.T) { - text := `make :: func() float { + text := `make func() float { pi float = 3 return pi } -main :: func() void { +main func() void { _ = make() } ` @@ -6236,10 +6289,10 @@ main :: func() void { @(test) float_constraint_result_resolves_to_f64 :: proc(t: ^testing.T) { - text := `make :: func() float { + text := `make func() float { return 3.0 } -main :: func() void { +main func() void { _ = make() } ` @@ -6264,12 +6317,12 @@ main :: func() void { @(test) float_constraint_widens_f32_to_f64 :: proc(t: ^testing.T) { - text := `wide :: func(a f32, b f64) float { + text := `wide func(a f32, b f64) float { x float = a x = b return x } -main :: func() void { +main func() void { _ = wide(1.0, 2.0) } ` @@ -6296,7 +6349,7 @@ main :: func() void { @(test) int_constraint_rejects_float_initializer :: proc(t: ^testing.T) { - text := `main :: func() void { + text := `main func() void { x int = 1.0 } ` @@ -6323,10 +6376,10 @@ int_constraint_rejects_float_initializer :: proc(t: ^testing.T) { @(test) float_constraint_rejects_runtime_integer :: proc(t: ^testing.T) { - text := `take :: func(n i32) void { + text := `take func(n i32) void { x float = n } -main :: func() void { +main func() void { take(7) } ` @@ -6353,11 +6406,11 @@ main :: func() void { @(test) range_constraint_local_resolves_to_inferred_range :: proc(t: ^testing.T) { - text := `make :: func() range { + text := `make func() range { r range :: 0..10 return r } -main :: func() void { +main func() void { _ = make() } ` @@ -6385,10 +6438,10 @@ main :: func() void { @(test) range_constraint_param_and_result_monomorphize :: proc(t: ^testing.T) { - text := `pass :: func(r range) range { + text := `pass func(r range) range { return r } -main :: func() void { +main func() void { once :: 0..5 for pass(once) |v| { _ = v @@ -6416,10 +6469,10 @@ main :: func() void { @(test) int_param_rejects_float_argument :: proc(t: ^testing.T) { - text := `take :: func(x int) int { + text := `take func(x int) int { return x } -main :: func() void { +main func() void { _ = take(1.5) } ` @@ -6446,10 +6499,10 @@ main :: func() void { @(test) float_param_accepts_integer_literal_argument :: proc(t: ^testing.T) { - text := `take :: func(x float) float { + text := `take func(x float) float { return x } -main :: func() void { +main func() void { y f64 = take(3) _ = y } @@ -6479,7 +6532,7 @@ undefined_accepts_concrete_runtime_annotations :: proc(t: ^testing.T) { x i32 y i32 } -main :: func() void { +main func() void { point Point = undefined pointer @i32 = undefined maybe ?i32 = undefined @@ -6517,7 +6570,7 @@ main :: func() void { @(test) undefined_rejects_non_declaration_uses_and_unresolved_inference :: proc(t: ^testing.T) { text := `global :: undefined -main :: func() void { +main func() void { immutable :: undefined typed_immutable int :: undefined unresolved int = undefined @@ -6562,10 +6615,10 @@ compound_assignment_evaluates_lvalue_once :: proc(t: ^testing.T) { // A compound assignment to an indexed lvalue must compute the element address // once and reuse it for the load and the store, rather than re-lowering the // lvalue (which would re-evaluate any side-effecting index subexpression). - text := `bump :: func() usize { + text := `bump func() usize { return 1 } -main :: func() i32 { +main func() i32 { values [3]mut i32 = [10, 20, 30] values[bump()] += 5 return 0 @@ -6612,16 +6665,16 @@ compound_assignment_evaluates_nested_locations_once :: proc(t: ^testing.T) { text := `Box :: struct { value i32 } -row :: func() usize { +row func() usize { return 0 } -column :: func() usize { +column func() usize { return 1 } -pointer_for :: func(value @mut i32) @mut i32 { +pointer_for func(value @mut i32) @mut i32 { return value } -main :: func() i32 { +main func() i32 { matrix [2]mut [2]mut i32 = [[1, 2], [3, 4]] (matrix[row()])[column()] += 1 boxes [2]mut Box = [Box { value = 5 }, Box { value = 6 }] @@ -6684,7 +6737,7 @@ main :: func() i32 { @(test) compound_assignment_supports_pointer_add_only :: proc(t: ^testing.T) { - valid_text := `main :: func() i32 { + valid_text := `main func() i32 { values [3]mut i32 = [10, 20, 30] pointer *mut i32 = (&values).ptr pointer += 1 @@ -6719,7 +6772,7 @@ compound_assignment_supports_pointer_add_only :: proc(t: ^testing.T) { testing.expect_value(t, len(diagnostics.items), 0) testing.expect_value(t, pointer_add_count, 2) - invalid_text := `main :: func() void { + invalid_text := `main func() void { values [1]mut i32 = [10] pointer *mut i32 = (&values).ptr pointer -= 1 @@ -6749,7 +6802,7 @@ compound_assignment_supports_pointer_add_only :: proc(t: ^testing.T) { @(test) compound_assignment_preserves_checked_numeric_operations :: proc(t: ^testing.T) { - text := `main :: func() i32 { + text := `main func() i32 { signed i32 = 24 signed += 6 signed -= 2 @@ -6816,7 +6869,7 @@ compound_assignment_preserves_checked_numeric_operations :: proc(t: ^testing.T) @(test) compound_assignment_rejects_narrowing_and_mixed_numeric_families :: proc(t: ^testing.T) { - text := `main :: func() void { + text := `main func() void { narrow i8 = 1 wide i32 = 2 narrow += wide @@ -6861,7 +6914,7 @@ compound_assignment_compiles_and_runs :: proc(t: ^testing.T) { @(test) binary_arithmetic_rejects_non_numeric_operands :: proc(t: ^testing.T) { - text := `main :: func() i32 { + text := `main func() i32 { a i32 = 1 b u32 = 2 _ = a / b @@ -6889,7 +6942,7 @@ binary_arithmetic_rejects_non_numeric_operands :: proc(t: ^testing.T) { @(test) compound_assignment_requires_writable_target :: proc(t: ^testing.T) { - text := `main :: func() i32 { + text := `main func() i32 { x :: 5 x += 1 return x @@ -6916,7 +6969,7 @@ compound_assignment_requires_writable_target :: proc(t: ^testing.T) { @(test) checked_division_and_subtraction_emit_guarded_llvm :: proc(t: ^testing.T) { - text := `main :: func() i32 { + text := `main func() i32 { a i32 = 10 b i32 = 3 c i32 = a - b @@ -6958,10 +7011,10 @@ PointID :: distinct Point Bytes :: distinct [2]u8 WrappedID :: distinct UserID static_id UserID :: UserID(42) -take :: func(value UserID) UserID { +take func(value UserID) UserID { return value } -main :: func() i32 { +main func() i32 { id UserID :: UserID(7) copy UserID = take(id) maybe ?UserID = copy @@ -7027,9 +7080,9 @@ BadInt :: distinct int BadVoid :: distinct void BadFunction :: distinct c_func() void BadOpaque :: distinct Opaque -foreign :: c_func(value UserID) void -foreign_pointer :: c_func(value @UserID) void -main :: func() void { +foreign c_func(value UserID) void +foreign_pointer c_func(value @UserID) void +main func() void { raw u32 = 1 id UserID = raw backing u32 = UserID(2) @@ -7084,10 +7137,10 @@ main :: func() void { @(test) distinct_type_construction_defers_to_callable_names :: proc(t: ^testing.T) { text := `Value :: distinct u32 -Value :: func(value i32) i32 { +Value func(value i32) i32 { return value } -main :: func() i32 { +main func() i32 { return Value(42) } ` @@ -7137,14 +7190,14 @@ Nat :: enum(u16) { five = 5 } global Animal :: Animal.dog -take :: func(value Animal) Animal { +take func(value Animal) Animal { return value } -identity :: c_func(value Nat) Nat { +identity c_func(value Nat) Nat { return value } -variadic :: c_func(marker c_int, ...) c_int -main :: func() i32 { +variadic c_func(marker c_int, ...) c_int +main func() i32 { value Animal = .cat values [2]Animal :: [.dog, Animal.bird] number Nat = identity(.two) @@ -7213,7 +7266,7 @@ unbacked_enum_uses_global_u16_backing :: proc(t: ^testing.T) { for index in 0..<257 { fmt.sbprintf(&builder, "value_%d\n", index) } - strings.write_string(&builder, "}\nmain :: func() void {}\n") + strings.write_string(&builder, "}\nmain func() void {}\n") source_file := source.Source{path="test.bro", text=strings.to_string(builder)} diagnostics := source.init_diagnostics(&source_file) defer source.destroy_diagnostics(&diagnostics) @@ -7256,9 +7309,9 @@ Overflow :: enum(u8) { Other :: enum { value } -foreign :: c_func(value Dense) void -allowed :: c_func(value Overflow) Overflow -main :: func() void { +foreign c_func(value Dense) void +allowed c_func(value Overflow) Overflow +main func() void { dense Dense = Other.value _ = Dense.zero + Dense.one _ = Dense.zero < Dense.one @@ -7392,7 +7445,7 @@ translate_c_emits_native_bindings_and_round_trips :: proc(t: ^testing.T) { // Function-pointer types carry no parameter names, so the callback renders `_`. testing.expect(t, strings.contains(output, "Mapper :: alias ?*c_func(_ c_int) c_int")) // Real C parameter names are used when present. - testing.expect(t, strings.contains(output, "imported_add :: c_func(a c_int, b c_int) c_int")) + testing.expect(t, strings.contains(output, "imported_add c_func(a c_int, b c_int) c_int")) testing.expect(t, strings.contains(output, "MAX_LEN c_int :: 256")) testing.expect(t, strings.contains(output, "# unsupported in bindings: C union 'Choice'")) testing.expect(t, strings.contains(output, "# unsupported in bindings: external variable 'some_global'")) @@ -7416,8 +7469,8 @@ translate_c_emits_native_bindings_and_round_trips :: proc(t: ^testing.T) { sink_named_parameters_are_allowed_and_not_duplicates :: proc(t: ^testing.T) { // Generated bindings use `_` for unnamed C params; the parser must accept it and // the checker must not flag repeated `_` as duplicate parameters. - text := `foo :: c_func(_ c_int, _ c_int) c_int -main :: func() void { + text := `foo c_func(_ c_int, _ c_int) c_int +main func() void { _ = foo(1, 2) } ` @@ -7445,7 +7498,7 @@ contextual_inference_resolves_signed_const_chain :: proc(t: ^testing.T) { text := `X :: 1000 Y int :: X Z i32 :: Y -main :: func() void {} +main func() void {} ` source_file := source.Source{path="test.bro", text=text} diagnostics := source.init_diagnostics(&source_file) @@ -7474,7 +7527,7 @@ B u16 :: A P :: 10 R u32 :: P N :: 42 -main :: func() void {} +main func() void {} ` source_file := source.Source{path="test.bro", text=text} diagnostics := source.init_diagnostics(&source_file) @@ -7502,7 +7555,7 @@ main :: func() void {} contextual_inference_rejects_constant_that_does_not_fit_demand :: proc(t: ^testing.T) { text := `BIG :: 100000 C u8 :: BIG -main :: func() void {} +main func() void {} ` source_file := source.Source{path="test.bro", text=text} diagnostics := source.init_diagnostics(&source_file) @@ -7527,10 +7580,10 @@ main :: func() void {} @(test) contextual_inference_does_not_cross_call_boundaries :: proc(t: ^testing.T) { - text := `echo :: func(p int) int { return p } + text := `echo func(p int) int { return p } A :: 10 R u32 :: echo(A) -main :: func() void {} +main func() void {} ` source_file := source.Source{path="test.bro", text=text} diagnostics := source.init_diagnostics(&source_file) @@ -7555,12 +7608,12 @@ main :: func() void {} @(test) contextual_inference_resolves_locals_like_globals :: proc(t: ^testing.T) { - text := `take_u16 :: func(v u16) void {} -get :: func() u16 { + text := `take_u16 func(v u16) void {} +get func() u16 { c :: 10 return c } -main :: func() void { +main func() void { x :: 1000 y int :: x z i32 :: y @@ -7591,9 +7644,9 @@ main :: func() void { @(test) contextual_inference_demand_from_function_body_reaches_global :: proc(t: ^testing.T) { - text := `take_u16 :: func(v u16) void {} + text := `take_u16 func(v u16) void {} G :: 10 -main :: func() void { +main func() void { take_u16(G) } ` @@ -7617,7 +7670,7 @@ main :: func() void { @(test) contextual_inference_flows_through_compound_assignment :: proc(t: ^testing.T) { - text := `main :: func() void { + text := `main func() void { s :: 5 v u16 = 0 v += s @@ -7644,11 +7697,11 @@ contextual_inference_flows_through_compound_assignment :: proc(t: ^testing.T) { @(test) contextual_inference_resolves_open_global_arithmetic_across_uses :: proc(t: ^testing.T) { - text := `take_ci :: func(v c_int) void {} + text := `take_ci func(v c_int) void {} W :: 800 Z :: 40 STEP :: 5 -main :: func() void { +main func() void { take_ci(W) x int = W - Z take_ci(Z) @@ -7685,7 +7738,7 @@ main :: func() void { @(test) contextual_inference_rejects_local_constant_that_does_not_fit :: proc(t: ^testing.T) { - text := `main :: func() void { + text := `main func() void { big :: 100000 c u8 :: big } @@ -7712,21 +7765,21 @@ contextual_inference_rejects_local_constant_that_does_not_fit :: proc(t: ^testin @(test) contextual_inference_flows_through_numeric_arithmetic :: proc(t: ^testing.T) { - text := `take_u16 :: func(v u16) void {} -take_f32 :: func(v f32) void {} + text := `take_u16 func(v u16) void {} +take_f32 func(v f32) void {} G :: 10 H u16 :: G + 2 GF :: 1.5 HF f32 :: GF + 2.5 CG :: 5 CFG :: 1.0 -get :: func() f32 { +get func() f32 { seed f32 :: 2.0 c :: seed + 3.0 d :: 4.0 + seed return c + d } -main :: func() void { +main func() void { a :: 10 b u16 :: a + 2 x :: 1.5 @@ -7804,7 +7857,7 @@ main :: func() void { contextual_inference_rejects_non_fitting_arithmetic_demand :: proc(t: ^testing.T) { text := `BIG :: 100000 C u8 :: BIG + 1 -main :: func() void { +main func() void { _ = C } ` diff --git a/examples/interop/foundation/main.bro b/examples/interop/foundation/main.bro index 2f262c7..28e20e3 100644 --- a/examples/interop/foundation/main.bro +++ b/examples/interop/foundation/main.bro @@ -3,8 +3,8 @@ Buffer :: c_struct { length c_ulong } -get_buffer :: c_func() @Buffer -verify :: c_func( +get_buffer c_func() @Buffer +verify c_func( char_value c_char, schar_value c_schar, uchar_value c_uchar, @@ -21,7 +21,7 @@ verify :: c_func( longdouble_value c_longdouble, ) i32 -main :: func() i32 { +main func() i32 { buffer @Buffer :: get_buffer() _ = buffer^.data _ = buffer^.length diff --git a/examples/interop/header/app/main.bro b/examples/interop/header/app/main.bro index dc24144..f623ede 100644 --- a/examples/interop/header/app/main.bro +++ b/examples/interop/header/app/main.bro @@ -1,22 +1,22 @@ native :: import "../include/native.h" -pass_alias :: func(value native.imported_int_alias) native.imported_int { +pass_alias func(value native.imported_int_alias) native.imported_int { return value } -double_value :: c_func(value c_int) c_int { +double_value c_func(value c_int) c_int { return value + value } -call_mapper :: func(mapper native.Imported_Mapper) c_int { +call_mapper func(mapper native.Imported_Mapper) c_int { return mapper?(21) } -enum_identity :: c_func(value native.Imported_Enum) native.Imported_Enum { +enum_identity c_func(value native.Imported_Enum) native.Imported_Enum { return value } -main :: func() void { +main func() void { _ = native.imported_add(pass_alias(20), 22) _ = native.imported_scalar(3, 4) _ = native.child_value(7) diff --git a/examples/interop/header_cache/main.bro b/examples/interop/header_cache/main.bro index 323cd8d..6e1bd26 100644 --- a/examples/interop/header_cache/main.bro +++ b/examples/interop/header_cache/main.bro @@ -1,4 +1,4 @@ first :: import "../header/include/native.h" second :: import "../header/include/native.h" -main :: func() void {} +main func() void {} diff --git a/examples/interop/header_conflict/main.bro b/examples/interop/header_conflict/main.bro index 9ed7a15..0c60c06 100644 --- a/examples/interop/header_conflict/main.bro +++ b/examples/interop/header_conflict/main.bro @@ -1,7 +1,7 @@ first :: import "first.h" second :: import "second.h" -main :: func() void { +main func() void { _ = first.conflict_global _ = second.conflict_global } diff --git a/examples/interop/header_duplicate/main.bro b/examples/interop/header_duplicate/main.bro index ef821e8..3d5b890 100644 --- a/examples/interop/header_duplicate/main.bro +++ b/examples/interop/header_duplicate/main.bro @@ -1,7 +1,7 @@ native :: import "../header/include/native.h" child :: import "../header/include/child.h" -main :: func() void { +main func() void { _ = native.child_value(1) _ = child.child_value(2) native.child_shared_global = 7 diff --git a/examples/interop/header_main_conflict/main.bro b/examples/interop/header_main_conflict/main.bro index 4aff593..c5ec208 100644 --- a/examples/interop/header_main_conflict/main.bro +++ b/examples/interop/header_main_conflict/main.bro @@ -1,5 +1,5 @@ native :: import "native.h" -main :: func() void { +main func() void { _ = native.main } diff --git a/examples/interop/header_symbol_conflict/main.bro b/examples/interop/header_symbol_conflict/main.bro index 4b6ec75..45a3b1f 100644 --- a/examples/interop/header_symbol_conflict/main.bro +++ b/examples/interop/header_symbol_conflict/main.bro @@ -1,7 +1,7 @@ variable :: import "variable.h" function :: import "function.h" -main :: func() void { +main func() void { _ = variable.conflict_symbol _ = function.conflict_symbol() } diff --git a/examples/interop/header_unsupported/main.bro b/examples/interop/header_unsupported/main.bro index 99f9b72..a881137 100644 --- a/examples/interop/header_unsupported/main.bro +++ b/examples/interop/header_unsupported/main.bro @@ -1,11 +1,11 @@ native :: import "../header/include/native.h" -use_callback :: c_func(value native.Imported_Callback) void -use_union :: c_func(value native.Imported_Union) void -use_enum :: c_func(value native.Imported_Enum) void -use_opaque :: c_func(value native.Imported_Handle) void +use_callback c_func(value native.Imported_Callback) void +use_union c_func(value native.Imported_Union) void +use_enum c_func(value native.Imported_Enum) void +use_opaque c_func(value native.Imported_Handle) void -main :: func() void { +main func() void { _ = native.IMPORTED_BAD_EXPR _ = native.IMPORTED_REDEFINED_BAD _ = native.IMPORTED_GONE diff --git a/examples/interop/header_write_conflict/main.bro b/examples/interop/header_write_conflict/main.bro index 2636368..2ec1eaa 100644 --- a/examples/interop/header_write_conflict/main.bro +++ b/examples/interop/header_write_conflict/main.bro @@ -1,5 +1,5 @@ native :: import "native.h" -main :: func() void { +main func() void { _ = native.write } diff --git a/examples/interop/manual/main.bro b/examples/interop/manual/main.bro index 8d69cd4..8b0f530 100644 --- a/examples/interop/manual/main.bro +++ b/examples/interop/manual/main.bro @@ -1,5 +1,5 @@ -foreign_add :: c_func(a, b i32) i32 +foreign_add c_func(a, b i32) i32 -main :: func() i32 { +main func() i32 { return foreign_add(20, 22) } diff --git a/examples/interop/printf/main.bro b/examples/interop/printf/main.bro index fa1adfd..f56d280 100644 --- a/examples/interop/printf/main.bro +++ b/examples/interop/printf/main.bro @@ -1,5 +1,5 @@ -printf :: c_func(format *c_char, ...) c_int +printf c_func(format *c_char, ...) c_int -main :: func() void { +main func() void { _ = printf("answer: %d\n", 42) } diff --git a/examples/interop/records/app/main.bro b/examples/interop/records/app/main.bro index a027132..7eccd96 100644 --- a/examples/interop/records/app/main.bro +++ b/examples/interop/records/app/main.bro @@ -4,21 +4,21 @@ Manual :: c_struct { value c_int } -mirror_manual :: c_func(value Manual) Manual { +mirror_manual c_func(value Manual) Manual { return value } -mirror_large :: c_func(value native.Large) native.Large { +mirror_large c_func(value native.Large) native.Large { return value } -native_pair :: func(value native.Pair) native.Pair { +native_pair func(value native.Pair) native.Pair { return value } global_pair native.Pair :: native.Pair { left = 1, right = 2 } -main :: func() i32 { +main func() i32 { pair native.Pair = native_pair(global_pair) pair.left = 10 pair = native.echo_pair(pair) diff --git a/examples/interop/recursive/app/main.bro b/examples/interop/recursive/app/main.bro index ccd7b20..9c1c7c5 100644 --- a/examples/interop/recursive/app/main.bro +++ b/examples/interop/recursive/app/main.bro @@ -4,7 +4,7 @@ native :: import "../include/native.h" # the importer must not recurse forever populating it, and the checker must accept the # self-referential `?*mut Node` field as C-layout-compatible. -main :: func() i32 { +main func() i32 { node native.Node = native.Node { next = none, value = 7 } if node.next |_| { return 1 diff --git a/examples/packages/absolute/app/main.bro b/examples/packages/absolute/app/main.bro index b3385d9..ec9157e 100644 --- a/examples/packages/absolute/app/main.bro +++ b/examples/packages/absolute/app/main.bro @@ -1,3 +1,3 @@ import "/definitely/not/a/brolang/package" -main :: func() void {} +main func() void {} diff --git a/examples/packages/alias_conflict/app/main.bro b/examples/packages/alias_conflict/app/main.bro index fe4c46b..5e37b4b 100644 --- a/examples/packages/alias_conflict/app/main.bro +++ b/examples/packages/alias_conflict/app/main.bro @@ -1,6 +1,6 @@ math i32 :: 7 import "../math" -main :: func() i32 { +main func() i32 { return math } diff --git a/examples/packages/aliases/app/main.bro b/examples/packages/aliases/app/main.bro index 4762be6..73eefb8 100644 --- a/examples/packages/aliases/app/main.bro +++ b/examples/packages/aliases/app/main.bro @@ -1,6 +1,6 @@ left :: import "../math" right :: import "../math" -main :: func() i32 { +main func() i32 { return left.value + right.value } diff --git a/examples/packages/basic/app/main.bro b/examples/packages/basic/app/main.bro index 89772b8..060d420 100644 --- a/examples/packages/basic/app/main.bro +++ b/examples/packages/basic/app/main.bro @@ -1,5 +1,5 @@ import "../math" -main :: func() i32 { +main func() i32 { return math.sum(local_value, math.value) } diff --git a/examples/packages/basic/math/math.bro b/examples/packages/basic/math/math.bro index 9e56a04..157d8bc 100644 --- a/examples/packages/basic/math/math.bro +++ b/examples/packages/basic/math/math.bro @@ -1,5 +1,5 @@ value i32 :: 2 -sum :: func(a, b i32) i32 { +sum func(a, b i32) i32 { return a + b } diff --git a/examples/packages/c_symbols/app/main.bro b/examples/packages/c_symbols/app/main.bro index e978b67..d92c29f 100644 --- a/examples/packages/c_symbols/app/main.bro +++ b/examples/packages/c_symbols/app/main.bro @@ -1,7 +1,7 @@ import "../left" import "../right" -main :: func() void { +main func() void { _ = left.same() _ = right.same() } diff --git a/examples/packages/c_symbols/left/left.bro b/examples/packages/c_symbols/left/left.bro index 1f12483..1b41712 100644 --- a/examples/packages/c_symbols/left/left.bro +++ b/examples/packages/c_symbols/left/left.bro @@ -1,3 +1,3 @@ -same :: c_func() int { +same c_func() int { return 1 } diff --git a/examples/packages/c_symbols/right/right.bro b/examples/packages/c_symbols/right/right.bro index d34099d..5e20b82 100644 --- a/examples/packages/c_symbols/right/right.bro +++ b/examples/packages/c_symbols/right/right.bro @@ -1,3 +1,3 @@ -same :: c_func() int { +same c_func() int { return 2 } diff --git a/examples/packages/cycle/a/a.bro b/examples/packages/cycle/a/a.bro index e351559..d8ec2c4 100644 --- a/examples/packages/cycle/a/a.bro +++ b/examples/packages/cycle/a/a.bro @@ -2,6 +2,6 @@ import "../b" seed i32 :: 4 -run :: func() i32 { +run func() i32 { return b.value } diff --git a/examples/packages/cycle/app/main.bro b/examples/packages/cycle/app/main.bro index 5ec8a3b..76c3cb9 100644 --- a/examples/packages/cycle/app/main.bro +++ b/examples/packages/cycle/app/main.bro @@ -1,5 +1,5 @@ import "../a" -main :: func() i32 { +main func() i32 { return a.run() } diff --git a/examples/packages/deep/app/level_one/level_two/two.bro b/examples/packages/deep/app/level_one/level_two/two.bro index e380a83..476f693 100644 --- a/examples/packages/deep/app/level_one/level_two/two.bro +++ b/examples/packages/deep/app/level_one/level_two/two.bro @@ -1,5 +1,5 @@ import "./level_three" -value :: func() i32 { +value func() i32 { return level_three.value } diff --git a/examples/packages/deep/app/level_one/one.bro b/examples/packages/deep/app/level_one/one.bro index 9d66bb0..594999d 100644 --- a/examples/packages/deep/app/level_one/one.bro +++ b/examples/packages/deep/app/level_one/one.bro @@ -1,5 +1,5 @@ import "./level_two" -value :: func() i32 { +value func() i32 { return level_two.value() } diff --git a/examples/packages/deep/app/main.bro b/examples/packages/deep/app/main.bro index 6e788d7..c33424f 100644 --- a/examples/packages/deep/app/main.bro +++ b/examples/packages/deep/app/main.bro @@ -1,5 +1,5 @@ import "./level_one" -main :: func() i32 { +main func() i32 { return level_one.value() } diff --git a/examples/packages/default_alias_invalid/app/main.bro b/examples/packages/default_alias_invalid/app/main.bro index 999cd26..912abf2 100644 --- a/examples/packages/default_alias_invalid/app/main.bro +++ b/examples/packages/default_alias_invalid/app/main.bro @@ -1,3 +1,3 @@ import "../bad-name" -main :: func() void {} +main func() void {} diff --git a/examples/packages/duplicate/app/main.bro b/examples/packages/duplicate/app/main.bro index 04a8f1b..4e2ca25 100644 --- a/examples/packages/duplicate/app/main.bro +++ b/examples/packages/duplicate/app/main.bro @@ -1,6 +1,6 @@ math :: import "../math" math :: import "../math" -main :: func() i32 { +main func() i32 { return math.value } diff --git a/examples/packages/eager_unused/app/main.bro b/examples/packages/eager_unused/app/main.bro index c8cc601..559bab5 100644 --- a/examples/packages/eager_unused/app/main.bro +++ b/examples/packages/eager_unused/app/main.bro @@ -1,3 +1,3 @@ import "../eager" -main :: func() void {} +main func() void {} diff --git a/examples/packages/empty_import/app/main.bro b/examples/packages/empty_import/app/main.bro index 2f367ad..2c76fd8 100644 --- a/examples/packages/empty_import/app/main.bro +++ b/examples/packages/empty_import/app/main.bro @@ -1,3 +1,3 @@ import "../empty" -main :: func() void {} +main func() void {} diff --git a/examples/packages/explicit_alias/app/main.bro b/examples/packages/explicit_alias/app/main.bro index 9b3596b..d754050 100644 --- a/examples/packages/explicit_alias/app/main.bro +++ b/examples/packages/explicit_alias/app/main.bro @@ -1,5 +1,5 @@ good :: import "../bad-name" -main :: func() i32 { +main func() i32 { return good.value } diff --git a/examples/packages/file_import/app/main.bro b/examples/packages/file_import/app/main.bro index 62e216e..bca33fc 100644 --- a/examples/packages/file_import/app/main.bro +++ b/examples/packages/file_import/app/main.bro @@ -1,3 +1,3 @@ import "../not_package.bro" -main :: func() void {} +main func() void {} diff --git a/examples/packages/file_import/not_package.bro b/examples/packages/file_import/not_package.bro index d7a03b8..2f8a1dd 100644 --- a/examples/packages/file_import/not_package.bro +++ b/examples/packages/file_import/not_package.bro @@ -1 +1 @@ -main :: func() void {} +main func() void {} diff --git a/examples/packages/file_local/app/a.bro b/examples/packages/file_local/app/a.bro index b4296b4..d0489e1 100644 --- a/examples/packages/file_local/app/a.bro +++ b/examples/packages/file_local/app/a.bro @@ -1,5 +1,5 @@ import "../math" -used_here :: func() int { +used_here func() int { return math.value } diff --git a/examples/packages/file_local/app/b.bro b/examples/packages/file_local/app/b.bro index 8cda583..11d1f74 100644 --- a/examples/packages/file_local/app/b.bro +++ b/examples/packages/file_local/app/b.bro @@ -1,8 +1,8 @@ -not_imported_here :: func() int { +not_imported_here func() int { return math.value } -main :: func() void { +main func() void { _ = used_here() _ = not_imported_here() } diff --git a/examples/packages/foreign_duplicate/app/main.bro b/examples/packages/foreign_duplicate/app/main.bro index e978b67..d92c29f 100644 --- a/examples/packages/foreign_duplicate/app/main.bro +++ b/examples/packages/foreign_duplicate/app/main.bro @@ -1,7 +1,7 @@ import "../left" import "../right" -main :: func() void { +main func() void { _ = left.same() _ = right.same() } diff --git a/examples/packages/foreign_duplicate/left/left.bro b/examples/packages/foreign_duplicate/left/left.bro index ff9aed7..61bb59e 100644 --- a/examples/packages/foreign_duplicate/left/left.bro +++ b/examples/packages/foreign_duplicate/left/left.bro @@ -1 +1 @@ -same :: c_func() i32 +same c_func() i32 diff --git a/examples/packages/foreign_duplicate/right/right.bro b/examples/packages/foreign_duplicate/right/right.bro index ff9aed7..61bb59e 100644 --- a/examples/packages/foreign_duplicate/right/right.bro +++ b/examples/packages/foreign_duplicate/right/right.bro @@ -1 +1 @@ -same :: c_func() i32 +same c_func() i32 diff --git a/examples/packages/generic/app/main.bro b/examples/packages/generic/app/main.bro index bbdcffa..7a4c07e 100644 --- a/examples/packages/generic/app/main.bro +++ b/examples/packages/generic/app/main.bro @@ -1,5 +1,5 @@ import "../math" -main :: func() i32 { +main func() i32 { return math.identity(127 + 1) } diff --git a/examples/packages/generic/math/math.bro b/examples/packages/generic/math/math.bro index e47087e..2b32c41 100644 --- a/examples/packages/generic/math/math.bro +++ b/examples/packages/generic/math/math.bro @@ -1,3 +1,3 @@ -identity :: func(value int) int { +identity func(value int) int { return value } diff --git a/examples/packages/global_cycle/app/main.bro b/examples/packages/global_cycle/app/main.bro index 08cfde4..b237b7d 100644 --- a/examples/packages/global_cycle/app/main.bro +++ b/examples/packages/global_cycle/app/main.bro @@ -1,5 +1,5 @@ import "../a" -main :: func() void { +main func() void { _ = a.value } diff --git a/examples/packages/import_order/app/main.bro b/examples/packages/import_order/app/main.bro index 5ee2804..b10c563 100644 --- a/examples/packages/import_order/app/main.bro +++ b/examples/packages/import_order/app/main.bro @@ -1,4 +1,4 @@ -main :: func() i32 { +main func() i32 { return math.value } diff --git a/examples/packages/imported_main/app/main.bro b/examples/packages/imported_main/app/main.bro index dd48b1e..ab41ffe 100644 --- a/examples/packages/imported_main/app/main.bro +++ b/examples/packages/imported_main/app/main.bro @@ -1,5 +1,5 @@ import "../dep" -main :: func() i32 { +main func() i32 { return dep.main() } diff --git a/examples/packages/imported_main/dep/dep.bro b/examples/packages/imported_main/dep/dep.bro index d3ae0cb..ab169ae 100644 --- a/examples/packages/imported_main/dep/dep.bro +++ b/examples/packages/imported_main/dep/dep.bro @@ -1,3 +1,3 @@ -main :: func() i32 { +main func() i32 { return 7 } diff --git a/examples/packages/lazy_import/app/main.bro b/examples/packages/lazy_import/app/main.bro index 452f4dd..3a6307c 100644 --- a/examples/packages/lazy_import/app/main.bro +++ b/examples/packages/lazy_import/app/main.bro @@ -1,7 +1,7 @@ import "../math" -unused :: func() int { +unused func() int { return math.missing } -main :: func() void {} +main func() void {} diff --git a/examples/packages/missing_root_main/dep/main.bro b/examples/packages/missing_root_main/dep/main.bro index 3d18c2d..0e146ea 100644 --- a/examples/packages/missing_root_main/dep/main.bro +++ b/examples/packages/missing_root_main/dep/main.bro @@ -1,3 +1,3 @@ -main :: func() i32 { +main func() i32 { return 1 } diff --git a/examples/packages/missing_unused/app/main.bro b/examples/packages/missing_unused/app/main.bro index 1f56dad..6b7e0e5 100644 --- a/examples/packages/missing_unused/app/main.bro +++ b/examples/packages/missing_unused/app/main.bro @@ -1,3 +1,3 @@ import "../missing" -main :: func() void {} +main func() void {} diff --git a/examples/packages/missing_used/app/main.bro b/examples/packages/missing_used/app/main.bro index 0a272e0..923cab5 100644 --- a/examples/packages/missing_used/app/main.bro +++ b/examples/packages/missing_used/app/main.bro @@ -1,5 +1,5 @@ import "../missing" -main :: func() void { +main func() void { _ = missing.value } diff --git a/examples/packages/non_transitive/app/main.bro b/examples/packages/non_transitive/app/main.bro index c31fde6..278e3dd 100644 --- a/examples/packages/non_transitive/app/main.bro +++ b/examples/packages/non_transitive/app/main.bro @@ -1,5 +1,5 @@ import "../bridge" -main :: func() void { +main func() void { _ = bridge.value } diff --git a/examples/packages/non_transitive/bridge/bridge.bro b/examples/packages/non_transitive/bridge/bridge.bro index 85bb814..58fa674 100644 --- a/examples/packages/non_transitive/bridge/bridge.bro +++ b/examples/packages/non_transitive/bridge/bridge.bro @@ -1,5 +1,5 @@ import "../math" -read :: func() i32 { +read func() i32 { return math.value } diff --git a/examples/packages/problematic_unused/app/main.bro b/examples/packages/problematic_unused/app/main.bro index 84c9722..0f30a66 100644 --- a/examples/packages/problematic_unused/app/main.bro +++ b/examples/packages/problematic_unused/app/main.bro @@ -1,3 +1,3 @@ import "../broken" -main :: func() void {} +main func() void {} diff --git a/examples/packages/qualified_shadow/app/main.bro b/examples/packages/qualified_shadow/app/main.bro index 92f57b4..ca7b657 100644 --- a/examples/packages/qualified_shadow/app/main.bro +++ b/examples/packages/qualified_shadow/app/main.bro @@ -1,9 +1,9 @@ import "../math" -read :: func(value i8) int { +read func(value i8) int { return math.value } -main :: func() i32 { +main func() i32 { return read(1) } diff --git a/examples/packages/recursive/a/a.bro b/examples/packages/recursive/a/a.bro index 718d810..09eb7fd 100644 --- a/examples/packages/recursive/a/a.bro +++ b/examples/packages/recursive/a/a.bro @@ -1,5 +1,5 @@ import "../b" -one :: func(value int) i32 { +one func(value int) i32 { return b.two(value) } diff --git a/examples/packages/recursive/app/main.bro b/examples/packages/recursive/app/main.bro index bb74994..c87d1ae 100644 --- a/examples/packages/recursive/app/main.bro +++ b/examples/packages/recursive/app/main.bro @@ -1,5 +1,5 @@ import "../a" -main :: func() i32 { +main func() i32 { return a.one(1) } diff --git a/examples/packages/recursive/b/b.bro b/examples/packages/recursive/b/b.bro index dce89e7..b5f7122 100644 --- a/examples/packages/recursive/b/b.bro +++ b/examples/packages/recursive/b/b.bro @@ -1,5 +1,5 @@ import "../a" -two :: func(value int) i32 { +two func(value int) i32 { return a.one(value) } diff --git a/examples/packages/repeated/app/a.bro b/examples/packages/repeated/app/a.bro index 911138f..bfbda49 100644 --- a/examples/packages/repeated/app/a.bro +++ b/examples/packages/repeated/app/a.bro @@ -1,5 +1,5 @@ import "../math" -from_a :: func() i32 { +from_a func() i32 { return math.value } diff --git a/examples/packages/repeated/app/b.bro b/examples/packages/repeated/app/b.bro index b3fe0bc..0b8617a 100644 --- a/examples/packages/repeated/app/b.bro +++ b/examples/packages/repeated/app/b.bro @@ -1,5 +1,5 @@ import "../math" -main :: func() i32 { +main func() i32 { return from_a() + math.value } diff --git a/examples/packages/self_import/app/main.bro b/examples/packages/self_import/app/main.bro index fac5d6c..098ca51 100644 --- a/examples/packages/self_import/app/main.bro +++ b/examples/packages/self_import/app/main.bro @@ -2,6 +2,6 @@ self :: import "." value i32 :: 5 -main :: func() i32 { +main func() i32 { return self.value } diff --git a/examples/packages/unused/app/main.bro b/examples/packages/unused/app/main.bro index fc93dfd..5875252 100644 --- a/examples/packages/unused/app/main.bro +++ b/examples/packages/unused/app/main.bro @@ -1,3 +1,3 @@ import "../math" -main :: func() void {} +main func() void {} diff --git a/examples/programs/break_continue/main.bro b/examples/programs/break_continue/main.bro index e0192dd..6d913e6 100644 --- a/examples/programs/break_continue/main.bro +++ b/examples/programs/break_continue/main.bro @@ -5,7 +5,7 @@ # innermost enclosing loop. Each section returns a distinct code on failure so # a regression points at the broken behaviour; success falls through to 42. -main :: func() i32 { +main func() i32 { # 1. `break` out of a `while` once i reaches 5. i i32 = 0 a i32 = 0 diff --git a/examples/programs/compound_assignment/main.bro b/examples/programs/compound_assignment/main.bro index 6e050e6..1dc442a 100644 --- a/examples/programs/compound_assignment/main.bro +++ b/examples/programs/compound_assignment/main.bro @@ -1,7 +1,7 @@ # Milestone 6: compound assignment (`+=`, `-=`, `*=`, `/=`) and the binary # arithmetic operators `-`, `*`, `/` with multiplicative precedence. -check_float :: func() i32 { +check_float func() i32 { x f64 = 10.0 x /= 4.0 # 2.5 x *= 2.0 # 5.0 @@ -13,7 +13,7 @@ check_float :: func() i32 { return 0 } -check_unsigned :: func() i32 { +check_unsigned func() i32 { n u32 = 100 n /= 7 # 14 (truncating integer division) n -= 4 # 10 @@ -23,7 +23,7 @@ check_unsigned :: func() i32 { return 0 } -main :: func() i32 { +main func() i32 { total i32 = 0 total += 10 # 10 total -= 3 # 7 diff --git a/examples/programs/conditional_unwrap/main.bro b/examples/programs/conditional_unwrap/main.bro index c3eee97..b0f92d6 100644 --- a/examples/programs/conditional_unwrap/main.bro +++ b/examples/programs/conditional_unwrap/main.bro @@ -1,11 +1,11 @@ # Milestone 5: conditional optional unwrapping, guards, and multi-unwrap. -observe :: func(counter @mut i32, value ?i32) ?i32 { +observe func(counter @mut i32, value ?i32) ?i32 { counter^ = counter^ + 1 return value } -main :: func() i32 { +main func() i32 { total i32 = 0 # present optional scalar -> binds v to the unwrapped value diff --git a/examples/programs/constant_context_error/main.bro b/examples/programs/constant_context_error/main.bro index 08364f8..46f2f4a 100644 --- a/examples/programs/constant_context_error/main.bro +++ b/examples/programs/constant_context_error/main.bro @@ -1,4 +1,4 @@ -main :: func() void { +main func() void { value i8 :: 127 + 1 _ = value } diff --git a/examples/programs/constant_fold/main.bro b/examples/programs/constant_fold/main.bro index d6fda21..ba91374 100644 --- a/examples/programs/constant_fold/main.bro +++ b/examples/programs/constant_fold/main.bro @@ -1,3 +1,3 @@ -main :: func() void { +main func() void { _ = 127 + 1 } diff --git a/examples/programs/constant_i64_overflow/main.bro b/examples/programs/constant_i64_overflow/main.bro index 0f8b820..129ffeb 100644 --- a/examples/programs/constant_i64_overflow/main.bro +++ b/examples/programs/constant_i64_overflow/main.bro @@ -1,3 +1,3 @@ -main :: func() void { +main func() void { _ = 9223372036854775807 + 1 } diff --git a/examples/programs/control_flow/main.bro b/examples/programs/control_flow/main.bro index 6fba07a..94464ad 100644 --- a/examples/programs/control_flow/main.bro +++ b/examples/programs/control_flow/main.bro @@ -1,9 +1,9 @@ # Milestone 5 foundation: booleans, comparisons, logical ops, if/else if/else. -printf :: c_func(format *c_char, ...) c_int +printf c_func(format *c_char, ...) c_int # Returns a distinct code per range using if / else if / else and comparisons. -classify :: func(n i32) i32 { +classify func(n i32) i32 { if n < 0 { return 1 } else if n == 0 { @@ -17,12 +17,12 @@ classify :: func(n i32) i32 { # A bool-returning function with a visible side effect, used to prove # short-circuit evaluation: it must only print when actually evaluated. -noisy :: func() bool { +noisy func() bool { _ = printf("rhs-evaluated\n") return true } -main :: func() i32 { +main func() i32 { total i32 = 0 # comparisons drive if / else if / else diff --git a/examples/programs/cycle_unused/main.bro b/examples/programs/cycle_unused/main.bro index b5718fa..a0fc041 100644 --- a/examples/programs/cycle_unused/main.bro +++ b/examples/programs/cycle_unused/main.bro @@ -1,6 +1,6 @@ a int :: b b int :: a -main :: func() void { +main func() void { _ = 1 } diff --git a/examples/programs/cycle_used/main.bro b/examples/programs/cycle_used/main.bro index 995f7b9..ffbe09c 100644 --- a/examples/programs/cycle_used/main.bro +++ b/examples/programs/cycle_used/main.bro @@ -1,6 +1,6 @@ a int :: b b int :: a -main :: func() void { +main func() void { _ = a } diff --git a/examples/programs/defer/main.bro b/examples/programs/defer/main.bro index 3af208d..bd6c84f 100644 --- a/examples/programs/defer/main.bro +++ b/examples/programs/defer/main.bro @@ -6,7 +6,7 @@ # The return value is captured before defers run, so the mutation here does not # change what is returned (Zig semantics). -spill_check :: func() i32 { +spill_check func() i32 { x i32 = 5 defer x = 999 return x @@ -14,7 +14,7 @@ spill_check :: func() i32 { # A function-scope defer runs only at function exit; a `break` runs the loop-body # defer but NOT the enclosing function-scope defer. -enclosing_defer_check :: func() i32 { +enclosing_defer_check func() i32 { v i32 = 0 defer v = v + 100 for 0..3 |i| { @@ -24,7 +24,7 @@ enclosing_defer_check :: func() i32 { return v # 0->1 (i=0 fall-through), ->2 (i=1 break); the +100 runs after capture } -main :: func() i32 { +main func() i32 { # 1. return value captured before defers run. if (spill_check() != 5) return 101 diff --git a/examples/programs/distinct_types/ids/ids.bro b/examples/programs/distinct_types/ids/ids.bro index a7cdd58..fc29bf7 100644 --- a/examples/programs/distinct_types/ids/ids.bro +++ b/examples/programs/distinct_types/ids/ids.bro @@ -1,5 +1,5 @@ UserID :: distinct u32 -make :: func(value u32) UserID { +make func(value u32) UserID { return UserID(value) } diff --git a/examples/programs/distinct_types/main.bro b/examples/programs/distinct_types/main.bro index 370a064..1406b1b 100644 --- a/examples/programs/distinct_types/main.bro +++ b/examples/programs/distinct_types/main.bro @@ -12,11 +12,11 @@ WrappedID :: distinct LocalID static_id LocalID :: LocalID(42) -take :: func(value LocalID) LocalID { +take func(value LocalID) LocalID { return value } -main :: func() i32 { +main func() i32 { id LocalID :: LocalID(7) copy LocalID = take(id) maybe ?LocalID = copy diff --git a/examples/programs/enums/animals/animals.bro b/examples/programs/enums/animals/animals.bro index 3354b6d..f7f43d0 100644 --- a/examples/programs/enums/animals/animals.bro +++ b/examples/programs/enums/animals/animals.bro @@ -3,6 +3,6 @@ Animal :: enum { cat } -favorite :: func() Animal { +favorite func() Animal { return .cat } diff --git a/examples/programs/enums/main.bro b/examples/programs/enums/main.bro index 32b647d..0931d52 100644 --- a/examples/programs/enums/main.bro +++ b/examples/programs/enums/main.bro @@ -8,15 +8,15 @@ State :: enum(u16) { initial State :: State.started -same :: func(left State, right State) bool { +same func(left State, right State) bool { return left == right } -identity :: c_func(value State) State { +identity c_func(value State) State { return value } -main :: func() i32 { +main func() i32 { state State = identity(.running) values [2]State :: [.started, State.stopped] animal animals.Animal :: animals.Animal.dog diff --git a/examples/programs/errors/main.bro b/examples/programs/errors/main.bro index 7e36e18..e2366e8 100644 --- a/examples/programs/errors/main.bro +++ b/examples/programs/errors/main.bro @@ -28,37 +28,37 @@ BoxB :: union(enum) { Box :: alias BoxA | BoxB -maybe :: func(value i32) i32 ! BasicError { +maybe func(value i32) i32 ! BasicError { if (value == 0) return .bad return value + 1 } -via_try :: func(value i32) i32 ! BasicError { +via_try func(value i32) i32 ! BasicError { unwrapped :: try maybe(value) return unwrapped + 1 } -with_detail :: func(value i32) i32 ! DetailError { +with_detail func(value i32) i32 ! DetailError { if (value == 0) return DetailError{ code = 5 } if (value == 1) return .empty return value } -pick :: func(value Both) i32 { +pick func(value Both) i32 { match value { .left: return 10 .right: return 20 } } -payload :: func(value Box) i32 { +payload func(value Box) i32 { match value { .a |n|: return n .b: return 3 } } -main :: func() i32 { +main func() i32 { acc i32 = 0 a :: maybe(0) catch 7 diff --git a/examples/programs/for_loop/main.bro b/examples/programs/for_loop/main.bro index 2c0a632..989a515 100644 --- a/examples/programs/for_loop/main.bro +++ b/examples/programs/for_loop/main.bro @@ -1,10 +1,10 @@ # Milestone 5: ranges and sequence for loops. -pass :: func(value range) range { +pass func(value range) range { return value } -main :: func() i32 { +main func() i32 { total i32 = 0 items [3]mut i32 = [1, 2, 3] diff --git a/examples/programs/for_loop_edges/main.bro b/examples/programs/for_loop_edges/main.bro index 1b78ac7..5ad5717 100644 --- a/examples/programs/for_loop_edges/main.bro +++ b/examples/programs/for_loop_edges/main.bro @@ -1,11 +1,11 @@ -make_range :: func(calls @mut i32, end usize) range { +make_range func(calls @mut i32, end usize) range { calls^ = calls^ + 1 return 0..end } global_range :: 0..1 -main :: func() i32 { +main func() i32 { total i32 = 0 first u8 = 254 diff --git a/examples/programs/function_global_unused/main.bro b/examples/programs/function_global_unused/main.bro index a7dbea1..e072a43 100644 --- a/examples/programs/function_global_unused/main.bro +++ b/examples/programs/function_global_unused/main.bro @@ -1,9 +1,9 @@ bad int = 1 -read_bad :: func() int { +read_bad func() int { return bad } derived :: read_bad() -main :: func() void {} +main func() void {} diff --git a/examples/programs/function_global_used/main.bro b/examples/programs/function_global_used/main.bro index 1762f86..f5eea79 100644 --- a/examples/programs/function_global_used/main.bro +++ b/examples/programs/function_global_used/main.bro @@ -1,11 +1,11 @@ bad int = 1 -read_bad :: func() int { +read_bad func() int { return bad } derived :: read_bad() -main :: func() void { +main func() void { _ = derived } diff --git a/examples/programs/invalid_transitive_unused_global/main.bro b/examples/programs/invalid_transitive_unused_global/main.bro index a741a10..cc8ca86 100644 --- a/examples/programs/invalid_transitive_unused_global/main.bro +++ b/examples/programs/invalid_transitive_unused_global/main.bro @@ -1,11 +1,11 @@ bad int = 4 -read_bad :: func() int { +read_bad func() int { return bad } derived int :: read_bad() -main :: func() void { +main func() void { _ = 1 } diff --git a/examples/programs/invalid_transitive_used_global/main.bro b/examples/programs/invalid_transitive_used_global/main.bro index 35f8717..8732ee6 100644 --- a/examples/programs/invalid_transitive_used_global/main.bro +++ b/examples/programs/invalid_transitive_used_global/main.bro @@ -1,11 +1,11 @@ bad int = 4 -read_bad :: func() int { +read_bad func() int { return bad } derived int :: read_bad() -main :: func() void { +main func() void { _ = derived } diff --git a/examples/programs/invalid_unused_function/main.bro b/examples/programs/invalid_unused_function/main.bro index 550157b..28b28e7 100644 --- a/examples/programs/invalid_unused_function/main.bro +++ b/examples/programs/invalid_unused_function/main.bro @@ -1,7 +1,7 @@ -broken :: func(value int) int { +broken func(value int) int { return missing + value } -main :: func() void { +main func() void { _ = 1 } diff --git a/examples/programs/invalid_unused_global/main.bro b/examples/programs/invalid_unused_global/main.bro index 037dbd2..40bfe51 100644 --- a/examples/programs/invalid_unused_global/main.bro +++ b/examples/programs/invalid_unused_global/main.bro @@ -1,5 +1,5 @@ bad int = 4 -main :: func() void { +main func() void { _ = 1 } diff --git a/examples/programs/invalid_used_function/main.bro b/examples/programs/invalid_used_function/main.bro index ed7f354..e058e57 100644 --- a/examples/programs/invalid_used_function/main.bro +++ b/examples/programs/invalid_used_function/main.bro @@ -1,7 +1,7 @@ -broken :: func(value int) int { +broken func(value int) int { return missing + value } -main :: func() void { +main func() void { _ = broken(1) } diff --git a/examples/programs/invalid_used_global/main.bro b/examples/programs/invalid_used_global/main.bro index 686559c..c9a9576 100644 --- a/examples/programs/invalid_used_global/main.bro +++ b/examples/programs/invalid_used_global/main.bro @@ -1,5 +1,5 @@ bad int = 4 -main :: func() void { +main func() void { _ = bad } diff --git a/examples/programs/main_i32/main.bro b/examples/programs/main_i32/main.bro index e77354d..d3d5364 100644 --- a/examples/programs/main_i32/main.bro +++ b/examples/programs/main_i32/main.bro @@ -1,3 +1,3 @@ -main :: func() i32 { +main func() i32 { return 4 } diff --git a/examples/programs/main_int/main.bro b/examples/programs/main_int/main.bro index 2e27c16..062beb7 100644 --- a/examples/programs/main_int/main.bro +++ b/examples/programs/main_int/main.bro @@ -1,3 +1,3 @@ -main :: func() int { +main func() int { return 3 } diff --git a/examples/programs/malformed_typed_recovery/main.bro b/examples/programs/malformed_typed_recovery/main.bro index b8324ad..3bf8624 100644 --- a/examples/programs/malformed_typed_recovery/main.bro +++ b/examples/programs/malformed_typed_recovery/main.bro @@ -1,12 +1,12 @@ -take :: func(value i8) i8 { +take func(value i8) i8 { return value } -bad_return :: func() i8 { +bad_return func() i8 { return missing } -main :: func() void { +main func() void { _ = take(missing) _ = bad_return() } diff --git a/examples/programs/match/main.bro b/examples/programs/match/main.bro index ca52d8e..57fff20 100644 --- a/examples/programs/match/main.bro +++ b/examples/programs/match/main.bro @@ -30,7 +30,7 @@ Box :: union(enum) { # Statement match with payload capture; every variant returns, so the function needs # no trailing return (the desugared if/else chain covers all paths). -describe :: func(d Data) i32 { +describe func(d Data) i32 { match d { .dog |age|: return age + 1 .bird |wingspan|: return wingspan + 2 @@ -38,7 +38,7 @@ describe :: func(d Data) i32 { } # Value match: single-expression arms yield implicitly, a block arm yields explicitly. -area :: func(s Shape) i32 { +area func(s Shape) i32 { result :: match s { .square |side|: side * side .circle |r|: { @@ -51,18 +51,18 @@ area :: func(s Shape) i32 { # Same-type multi-pattern capture: `.dog` and `.bird` are both i32, so one capture binds # either payload (read once at the union's shared carrier offset). -payload_of :: func(d Data) i32 { +payload_of func(d Data) i32 { v :: match d { .dog, .bird |n|: n } return v } -make_box :: func() Box { +make_box func() Box { return Box{ point = Point{ x = 4, y = 0 } } } -main :: func() i32 { +main func() i32 { acc i32 = 0 dog Data = Data{ dog = 9 } diff --git a/examples/programs/mutable_local/main.bro b/examples/programs/mutable_local/main.bro index e5c83c6..1b41ce7 100644 --- a/examples/programs/mutable_local/main.bro +++ b/examples/programs/mutable_local/main.bro @@ -1,4 +1,4 @@ -main :: func() i32 { +main func() i32 { value i32 = 1 value = value + 2 return value diff --git a/examples/programs/narrowing_error/main.bro b/examples/programs/narrowing_error/main.bro index df9ada3..b8a4a66 100644 --- a/examples/programs/narrowing_error/main.bro +++ b/examples/programs/narrowing_error/main.bro @@ -1,7 +1,7 @@ -take :: func(value i8) i8 { +take func(value i8) i8 { return value } -main :: func() void { +main func() void { _ = take(128) } diff --git a/examples/programs/one_line/main.bro b/examples/programs/one_line/main.bro index 1aafe30..b221f6c 100644 --- a/examples/programs/one_line/main.bro +++ b/examples/programs/one_line/main.bro @@ -1 +1 @@ -main :: func() i32 { return 7 } +main func() i32 { return 7 } diff --git a/examples/programs/overflow/main.bro b/examples/programs/overflow/main.bro index af605dd..e75cc8a 100644 --- a/examples/programs/overflow/main.bro +++ b/examples/programs/overflow/main.bro @@ -1,4 +1,4 @@ -main :: func() void { +main func() void { value i8 = 127 _ = value + 1 } diff --git a/examples/programs/prototype/main.bro b/examples/programs/prototype/main.bro index 3973a93..c0a9679 100644 --- a/examples/programs/prototype/main.bro +++ b/examples/programs/prototype/main.bro @@ -2,15 +2,15 @@ x int :: 2 -sum_c :: c_func(a, b int) int { +sum_c c_func(a, b int) int { return a + b } -sum_brolang :: func(a, b int) int { +sum_brolang func(a, b int) int { return a + b } -main :: func() void { +main func() void { y int = 4 a_add_b_c :: sum_c(1, 2) a_add_b_brolang :: sum_brolang(1, 2) diff --git a/examples/programs/runtime_global/main.bro b/examples/programs/runtime_global/main.bro index fb33fd2..00b93c1 100644 --- a/examples/programs/runtime_global/main.bro +++ b/examples/programs/runtime_global/main.bro @@ -1,10 +1,10 @@ -make_value :: func() int { +make_value func() int { return 40 + 2 } answer int :: make_value() -main :: func() i32 { +main func() i32 { _ = answer return 0 } diff --git a/examples/programs/sentinel_pointer/main.bro b/examples/programs/sentinel_pointer/main.bro index bd62a51..e098633 100644 --- a/examples/programs/sentinel_pointer/main.bro +++ b/examples/programs/sentinel_pointer/main.bro @@ -1,4 +1,4 @@ -main :: func() i32 { +main func() i32 { values [2;0]i32 :: [101, 101] array_pointer :: &values suffix [;0]i32 :: array_pointer[1..] diff --git a/examples/programs/tagged_union/main.bro b/examples/programs/tagged_union/main.bro index 1d862e5..9661485 100644 --- a/examples/programs/tagged_union/main.bro +++ b/examples/programs/tagged_union/main.bro @@ -15,7 +15,7 @@ Thing :: union(enum) { b f64 } -main :: func() i32 { +main func() i32 { x Data = Data{ bird = 37 } y Thing = Thing{ a = 5 } return x.bird + y.a diff --git a/examples/programs/unions/main.bro b/examples/programs/unions/main.bro index 1a41222..5628a1c 100644 --- a/examples/programs/unions/main.bro +++ b/examples/programs/unions/main.bro @@ -3,7 +3,7 @@ Val :: union { f f64 } -main :: func() i32 { +main func() i32 { x Val = Val{ n = 42 } return x.n } diff --git a/examples/programs/while_loop/main.bro b/examples/programs/while_loop/main.bro index 8734b52..22e16f4 100644 --- a/examples/programs/while_loop/main.bro +++ b/examples/programs/while_loop/main.bro @@ -1,13 +1,13 @@ # Milestone 5: boolean while loops with optional post-iteration updates. -return_before_update :: func() i32 { +return_before_update func() i32 { i i32 = 0 while true : i = i + 1 { return i } } -main :: func() i32 { +main func() i32 { total i32 = 0 # ordinary condition and update diff --git a/examples/programs/yield/main.bro b/examples/programs/yield/main.bro index 58521b1..3e75718 100644 --- a/examples/programs/yield/main.bro +++ b/examples/programs/yield/main.bro @@ -8,7 +8,7 @@ # --- value blocks (milestone 20) --------------------------------------------- # Untyped `::`: the local's type is the yield's natural type. -basic :: func() i32 { +basic func() i32 { x :: { a :: 20 b :: 22 @@ -18,7 +18,7 @@ basic :: func() i32 { } # Typed `T =`: the yield coerces to the annotation. -typed :: func() i64 { +typed func() i64 { x i64 = { yield 100 } @@ -27,7 +27,7 @@ typed :: func() i64 { # The yielded value is captured before defers run: the defer mutates a block # local, but the captured value is unchanged. -spill :: func() i32 { +spill func() i32 { v :: { n i32 = 5 defer n = 999 @@ -37,7 +37,7 @@ spill :: func() i32 { } # Reassignment into an existing mutable local. -reassign :: func() i32 { +reassign func() i32 { r i32 = 0 r = { yield 7 @@ -48,7 +48,7 @@ reassign :: func() i32 { # --- value if-statements (milestone 20.5) ------------------------------------ # Untyped `::` over an `else if` chain; the first branch fixes the type. -vif_untyped :: func(sel i32) i32 { +vif_untyped func(sel i32) i32 { r :: if (sel == 0) { yield 10 } else if (sel == 1) { @@ -60,13 +60,13 @@ vif_untyped :: func(sel i32) i32 { } # Typed `T =`: every branch coerces to the annotation. -vif_typed :: func(sel i32) i32 { +vif_typed func(sel i32) i32 { r i32 = if (sel == 0) { yield 100 } else { yield 200 } return r } # Assigned into an existing local. -vif_reassign :: func(sel i32) i32 { +vif_reassign func(sel i32) i32 { r i32 = 0 r = if (sel == 0) { yield 7 } else { yield 9 } return r @@ -74,7 +74,7 @@ vif_reassign :: func(sel i32) i32 { # A branch is a full value block: leading statements + a defer captured before # the yield. -vif_defer :: func() i32 { +vif_defer func() i32 { r :: if (true) { n i32 = 5 defer n = 999 @@ -90,7 +90,7 @@ vif_defer :: func() i32 { # Labeled `for` used as a value: `yield :blk i` exits early with a value, the # trailing `yield none` supplies the value when the loop completes. The `{i, # none}` yields resolve the result to an optional. -loop_search :: func() i32 { +loop_search func() i32 { # first i in 0..10 whose square exceeds 40 (6*6=36 no, 7*7=49 yes -> 7). idx :: for 0..10 |i| blk: { if (i * i > 40) yield :blk i @@ -104,7 +104,7 @@ loop_search :: func() i32 { } # Same loop, but nothing matches -> the fall-through `yield none` is the result. -loop_none :: func() i32 { +loop_none func() i32 { idx :: for 0..10 |i| blk: { if (i > 100) yield :blk i yield none @@ -117,7 +117,7 @@ loop_none :: func() i32 { } # Labeled `while` value loop (label follows the `: update` clause). -loop_while :: func() i32 { +loop_while func() i32 { n i32 = 0 found :: while n < 100 : n += 1 blk: { if (n == 8) yield :blk n @@ -134,7 +134,7 @@ loop_while :: func() i32 { # A branch may exit on every path (here `return`) instead of yielding; the slot # read after the `if` is only reached on the yielding path. -vif_return :: func(sel i32) i32 { +vif_return func(sel i32) i32 { r :: if (sel == 0) { yield 10 } else { @@ -144,7 +144,7 @@ vif_return :: func(sel i32) i32 { } # unwrap-`if` as a value source: present -> transform, absent -> default. -vif_unwrap :: func(opt ?i32) i32 { +vif_unwrap func(opt ?i32) i32 { r :: if opt |v| { yield v * 2 } else { @@ -154,14 +154,14 @@ vif_unwrap :: func(opt ?i32) i32 { } # The simple "unwrap or fallback" case is just `orelse` (already a plain expression). -orelse_value :: func(opt ?i32) i32 { +orelse_value func(opt ?i32) i32 { r :: opt orelse 7 return r } # Untyped value loop where `none` is yielded (in a labeled yield) before any # concrete value: the element type still resolves to ? from `yield :blk i`. -loop_none_first :: func() i32 { +loop_none_first func() i32 { r :: for 0..10 |i| blk: { if (i > 100) yield :blk none if (i * i > 40) yield :blk i # first concrete yield: i == 7 @@ -178,7 +178,7 @@ loop_none_first :: func() i32 { # A labeled value block: `yield :blk` exits the block (past a nested `if`) with a # value. Every path must yield. -lblock :: func(sel i32) i32 { +lblock func(sel i32) i32 { r :: blk: { base :: 10 if (sel == 0) { @@ -192,7 +192,7 @@ lblock :: func(sel i32) i32 { # An early `yield :blk` skips the rest of the block; the value is captured before # the block's defer runs. -lblock_defer :: func() i32 { +lblock_defer func() i32 { r :: blk: { n i32 = 5 defer n = 999 @@ -203,7 +203,7 @@ lblock_defer :: func() i32 { } # A labeled block whose `{T, none}` yields resolve the result to an optional. -lblock_optional :: func(present i32) i32 { +lblock_optional func(present i32) i32 { r :: blk: { if (present == 0) yield :blk none yield :blk 8 @@ -215,7 +215,7 @@ lblock_optional :: func(present i32) i32 { } # `yield :outer v` exits an OUTER value loop from inside an inner loop. -yield_outer :: func(target i32) i32 { +yield_outer func(target i32) i32 { found :: for 0..3 |row| outer: { for 0..3 |col| { if (row * 3 + col == target) yield :outer (row * 10 + col) @@ -229,7 +229,7 @@ yield_outer :: func(target i32) i32 { } # Plain `break :outer` exits an outer loop from an inner loop. -break_outer :: func() i32 { +break_outer func() i32 { count i32 = 0 for 0..3 |a| outer: { for 0..3 |b| { @@ -241,7 +241,7 @@ break_outer :: func() i32 { } # A labeled block *statement* (not a value source): `break :blk` exits it early. -stmt_block :: func(early i32) i32 { +stmt_block func(early i32) i32 { x i32 = 0 blk: { x = 1 @@ -253,7 +253,7 @@ stmt_block :: func(early i32) i32 { # `break :search` escapes a nested loop and the block in one jump; the block's # defer still runs on the way out. -stmt_block_escape :: func() i32 { +stmt_block_escape func() i32 { hits i32 = 0 search: { defer hits += 1000 @@ -267,7 +267,7 @@ stmt_block_escape :: func() i32 { } # Item B: a `none` yielded before a concrete `yield :blk` that references a block local. -lblock_local :: func() i32 { +lblock_local func() i32 { r :: blk: { val :: 9 if (false) yield :blk none @@ -279,7 +279,7 @@ lblock_local :: func() i32 { return -1 } -main :: func() i32 { +main func() i32 { if (basic() != 42) return 101 if (typed() != 100) return 102 if (spill() != 5) return 103 diff --git a/testbed/cstdio.bro b/testbed/cstdio.bro index 109ef84..e6bd2c2 100644 --- a/testbed/cstdio.bro +++ b/testbed/cstdio.bro @@ -1,4 +1,4 @@ # generated by brolang translate-c from testbed/cstdio.h -printf :: c_func(format ?*c_char, ...) c_int +printf c_func(format ?*c_char, ...) c_int diff --git a/testbed/main.bro b/testbed/main.bro index ca39afe..2e5d207 100644 --- a/testbed/main.bro +++ b/testbed/main.bro @@ -15,7 +15,7 @@ Player :: struct { active bool } -tier_bonus :: func(tier Tier) i32 { +tier_bonus func(tier Tier) i32 { if tier == .gold { return 30 } else if tier == .silver { @@ -24,7 +24,7 @@ tier_bonus :: func(tier Tier) i32 { return 5 } -projected_score :: func(player Player) i32 { +projected_score func(player Player) i32 { total i32 = player.score total += tier_bonus(player.tier) if player.active and player.streak > 2 { @@ -33,7 +33,7 @@ projected_score :: func(player Player) i32 { return total } -apply_decay :: func(players []mut Player) void { +apply_decay func(players []mut Player) void { for players |@player| { if !player.active { player.score -= 4 @@ -41,7 +41,7 @@ apply_decay :: func(players []mut Player) void { } } -best_player :: func(players []mut Player) ?@mut Player { +best_player func(players []mut Player) ?@mut Player { best ?@mut Player = none best_score i32 = 0 @@ -61,7 +61,7 @@ best_player :: func(players []mut Player) ?@mut Player { return best } -main :: func() i32 { +main func() i32 { players [4]mut Player = [ Player { id = PlayerID(1), name = "Ada", tier = .gold, score = 41, streak = 4, active = true }, Player { id = PlayerID(2), name = "Ken", tier = .silver, score = 56, streak = 1, active = true },