From 081a3fd5df8c628866cd625add0cdaa80b109a8a Mon Sep 17 00:00:00 2001 From: hl-valdemar Date: Wed, 5 Aug 2026 21:19:41 +0200 Subject: [PATCH] mutable decl syntax change --- LANGUAGE.md | 3 +- README.md | 2 +- TODO.md | 39 +- compiler/checker/checker.odin | 22 +- compiler/lexer/lexer.odin | 13 +- compiler/parser/parser.odin | 53 +- compiler/testing.odin | 2 +- compiler/token/token.odin | 1 + compiler_tests.odin | 828 ++++++++++-------- examples/build/raylib/source/main.bro | 22 +- examples/interop/records/app/main.bro | 4 +- examples/interop/recursive/app/main.bro | 2 +- examples/packages/hidden_valid/app/a.bro | 6 +- examples/packages/hidden_valid/app/b.bro | 6 +- .../problematic_unused/broken/broken.bro | 2 +- .../programs/array_const_size_error/main.bro | 4 +- examples/programs/arraylist/main.bro | 12 +- examples/programs/bitwise/main.bro | 4 +- examples/programs/break_continue/main.bro | 12 +- .../programs/compound_assignment/main.bro | 8 +- examples/programs/comptime_eval/main.bro | 2 +- .../programs/comptime_type_params/main.bro | 8 +- examples/programs/comptime_v1/main.bro | 22 +- .../programs/comptime_value_params/main.bro | 2 +- examples/programs/conditional_unwrap/main.bro | 18 +- examples/programs/control_flow/main.bro | 6 +- examples/programs/defer/main.bro | 18 +- examples/programs/distinct_types/main.bro | 24 +- examples/programs/enums/main.bro | 2 +- examples/programs/errors/main.bro | 8 +- examples/programs/for_loop/main.bro | 6 +- examples/programs/for_loop_edges/main.bro | 20 +- .../index_int_constraint_error/main.bro | 4 +- examples/programs/index_signed_error/main.bro | 4 +- examples/programs/inline/main.bro | 10 +- .../invalid_transitive_used_global/main.bro | 2 +- examples/programs/io/main.bro | 4 +- examples/programs/match/main.bro | 18 +- examples/programs/mem_allocator/raw_alloc.bro | 18 +- examples/programs/mem_allocator/task_list.bro | 32 +- .../programs/mem_allocator/typed_alloc.bro | 28 +- examples/programs/milestone_24/main.bro | 12 +- examples/programs/milestone_39/main.bro | 4 +- examples/programs/mutable_global/main.bro | 12 +- examples/programs/mutable_local/main.bro | 2 +- examples/programs/overflow/main.bro | 2 +- examples/programs/prototype/main.bro | 2 +- examples/programs/scalar_cast_error/main.bro | 2 +- examples/programs/tagged_union/main.bro | 4 +- examples/programs/tuples/main.bro | 8 +- examples/programs/unions/main.bro | 2 +- examples/programs/unused_locals/main.bro | 6 +- examples/programs/while_loop/main.bro | 16 +- examples/programs/yield/main.bro | 24 +- std/arraylist/arraylist.hon | 2 +- std/arraylist/arraylist.test.hon | 6 +- std/debug/debug.hon | 2 +- std/enums/enums.hon | 2 +- std/enums/enums.test.hon | 2 +- std/hashmap/hashmap.hon | 10 +- std/hashmap/hashmap.test.hon | 2 +- std/io/file.hon | 6 +- std/io/io.hon | 38 +- std/mem/mem.hon | 22 +- std/meta/meta.hon | 6 +- std/meta/meta.test.hon | 4 +- std/static_string_map/static_string_map.hon | 16 +- testbed/game/main.bro | 22 +- testbed/lexer/main.bro | 6 +- testbed/lexer/std/arraylist/arraylist.bro | 2 +- testbed/lexer/std/io/io.bro | 6 +- testbed/lexer/std/mem/mem.bro | 26 +- testbed/main.bro | 8 +- testbed/mem_alloc/std/mem/mem.bro | 18 +- 74 files changed, 870 insertions(+), 733 deletions(-) diff --git a/LANGUAGE.md b/LANGUAGE.md index a6784b2..143e166 100644 --- a/LANGUAGE.md +++ b/LANGUAGE.md @@ -8,7 +8,8 @@ roadmap and milestone history. ### source, declarations, and packages - newline-terminated statements and `#` comments -- immutable `::` bindings, typed mutable `=` locals/globals, and `_` sinks +- immutable `name :: value` / `name Type :: value` bindings and mutable `name := value` / `name Type := value` bindings +- `=` is assignment, including `_ = value` sinks; keyed record initializers and named struct field defaults also use `=` - immutable package globals, mutable runtime globals, function-local mutable locals, and mutable declarations initialized with `undefined` - package-level functions, globals, native type declarations, and `Name :: alias T` - directory packages with merged declarations diff --git a/README.md b/README.md index 172c795..e4416db 100644 --- a/README.md +++ b/README.md @@ -222,7 +222,7 @@ Current prototype features: - Newline-terminated, multiline statements; `}` may terminate a block's final statement - `#` comments -- Immutable `::` bindings, typed mutable `=` locals/globals, and `_` sinks +- Immutable inferred/typed `::` bindings, mutable inferred/typed `:=` locals/globals, and `_` sinks - Exact-width signed/unsigned integers, `f32`, `f64`, `isize`, `usize`, and loose integer-constrained `int` - Target-dependent atomic `c_*` primitive types, `c_func`, complete `c_struct`, `opaque`, `anyopaque`, and V1 `ptrcast!(T, ptr)` - Arrays, sentinel arrays, single-item pointers, many-item pointers, sentinel many-item pointers, slices, sentinel slices, strings, character literals, optionals, and native structs diff --git a/TODO.md b/TODO.md index 6059a5d..0148122 100644 --- a/TODO.md +++ b/TODO.md @@ -12,7 +12,7 @@ - unsigned integers, floats, and target-dependent c scalar types - atomic `c_*` primitive types remain distinct until target-aware lowering - `c_func`, complete `c_struct`, and pointer-only `opaque`; `c` remains an ordinary identifier - - keep binding mutability (`::` / `=`) separate from element or pointee mutability (`mut`) + - keep binding mutability (`::` / `:=`) separate from element or pointee mutability (`mut`) - arrays and indexing - `[N]T`: array with `N` logical elements - `[N;S]T`: array with `N` logical elements followed by sentinel `S` @@ -184,7 +184,7 @@ - undefined values are assigned a poison value (0xaa...) - allows for something like: ``` - a int = undefined + a int := undefined if (condition) { a = 42 } else { @@ -323,7 +323,7 @@ - a `{ ... }` on the right of a declaration or assignment is a *value block*: its final statement must be `yield `, which supplies the block's value (the block analogue of `return`). Supported: `x :: { ...; yield v }` (untyped — the local takes the yield's - natural type), `x T = { ... }` (coerces to `T`), and `target = { ... }` (coerces to the + natural type), `x T := { ... }` (coerces to `T`), and `target = { ... }` (coerces to the target's type, including complex targets like `a[i] = { ... }`) - the yielded value is captured *before* the block's defers run (a defer that mutates a block local can't change what is yielded), reusing the `return` spill-to-temp pattern @@ -695,9 +695,9 @@ 27.8 source-defined mutable runtime globals (implemented) - allow mutable global declarations in Brolang source for process-global runtime state, matching the writable-global support already needed for imported C globals - - require source type syntax and an initializer; constraints (`int`/`float`/`range`) - and inferred array counts may resolve through the existing inference fixpoint, but - the final type must be concrete runtime storage + - require an initializer and infer or explicitly declare a concrete runtime storage type; + constraints (`int`/`float`/`range`) and inferred array counts resolve through the existing + inference fixpoint - emit source-defined mutable globals as writable globals, not constants - allow `undefined` initializers for runtime storage initialized explicitly by a function - allow assignment, address-taking, field/index mutation, and pointer passing under @@ -774,7 +774,7 @@ improving layout or specialization - the smallest fitting feature is call-local inference of omitted comptime type arguments: ``` - values ArrayList(i32) = arraylist.init(mem.c_allocator) + values ArrayList(i32) := arraylist.init(mem.c_allocator) defer arraylist.deinit(&values) try arraylist.append(&values, 42) ``` @@ -988,9 +988,9 @@ f: f32 = 3.14 bits := bitcast(f, u32) # IEEE 754 representation # pointer casts -buf *u8 = get_buffer() -ints *u32 = ptrcast!(u32, buf) # element type change, same pointer shape -writable *mut u8 = constcast!(buf) # explicit unsafe mutability restoration +buf *u8 := get_buffer() +ints *u32 := ptrcast!(u32, buf) # element type change, same pointer shape +writable *mut u8 := constcast!(buf) # explicit unsafe mutability restoration ``` ## A word on multi-unwrap @@ -1069,8 +1069,7 @@ layer: ```bro UserID :: distinct u32 OuterID :: distinct UserID - -index usize = 42 +index usize := 42 id UserID :: UserID(index) raw u32 :: u32(id) outer OuterID :: OuterID(id) @@ -1222,7 +1221,7 @@ data :: { } # match arms -label []u8 = match p { +label []u8 := match p { .high: "HIGH", # single expression: implicit yield .low: { log("low priority") @@ -1231,7 +1230,7 @@ label []u8 = match p { } # catch handlers (planned; block form deferred in milestone 23 v1) -data []u8 = read(path) catch |e| { +data []u8 := read(path) catch |e| { log(e) yield fallback_data # block: explicit yield } @@ -1252,7 +1251,7 @@ result :: if a { } # yielding to a variable -result int = if a { +result int := if a { yield 1 } else if b { yield 2 @@ -1482,7 +1481,7 @@ Fallible functions use ordinary `return` for both channels. If the returned expr ``` parse_section func(p: @mut Parser) void ! ParseError { - start_line Line = p.line + start_line Line := p.line p.advance() # ... parsing logic ... @@ -1497,7 +1496,7 @@ Since errors are just union values, you can also construct them separately: ``` # Construct error value (it's just a union) -e ParseError = .timeout{500} +e ParseError := .timeout{500} # Return it via error channel later return e @@ -1647,7 +1646,7 @@ Brolang provides a libc-backed allocator value: mem :: import "@std/mem" process func(input []u8) u64 { - temp ?*mut u8 = mem.alloc(mem.c_allocator, input.len * 2, 1) + temp ?*mut u8 := mem.alloc(mem.c_allocator, input.len * 2, 1) defer mem.free(mem.c_allocator, temp, input.len * 2, 1) # ... work with temp ... @@ -1677,7 +1676,7 @@ mem :: import "@std/mem" # Allocation escapes via return value — requires allocator duplicate func(input []u8, allocator mem.Allocator) ?*mut u8 { - result ?*mut u8 = mem.alloc(allocator, input.len, 1) + result ?*mut u8 := mem.alloc(allocator, input.len, 1) mem.copy(result, input) return result # caller manages this memory } @@ -1690,7 +1689,7 @@ init func(obj @mut MyStruct, allocator mem.Allocator) void { # No allocation escapes — no allocator needed process func(input []u8) u64 { - temp ?*mut u8 = mem.alloc(mem.c_allocator, input.len, 1) + temp ?*mut u8 := mem.alloc(mem.c_allocator, input.len, 1) defer mem.free(mem.c_allocator, temp, input.len, 1) # ... work with temp ... return compute_hash(temp) diff --git a/compiler/checker/checker.odin b/compiler/checker/checker.odin index 41f7fae..e710474 100644 --- a/compiler/checker/checker.odin +++ b/compiler/checker/checker.odin @@ -5952,7 +5952,7 @@ infer_statements :: proc( #partial switch statement.kind { case .Declaration: if statement.expr == ast.INVALID_EXPR { - // Value block (`x :: { ... yield v }` / `x T = { ... }`): register the + // Value block (`x :: { ... yield v }` / `x T := { ... }`): register the // binding (its declared type when annotated, else left open) and walk // the block body. The build pass resolves the yielded value's type // independently — value blocks don't join the demand fixpoint. @@ -6026,7 +6026,7 @@ infer_statements :: proc( continue } expected_assignment := types.INVALID - if statement.target != ast.INVALID_EXPR { + if statement.target != ast.INVALID_EXPR && !symbol.is_valid(statement.name) { expected_assignment = infer_expr(checker, statement.target, locals^[:], pkg, file, demanded, local_types) target_expr := checker.ast_module.exprs[statement.target] if target_expr.kind == .Name && !symbol.is_valid(target_expr.qualifier) { @@ -6055,7 +6055,7 @@ infer_statements :: proc( // type onto open-constant operands and poison their family. Operands of an // arithmetic RHS resolve from their own authoritative uses. rhs_is_arith := is_arith_kind(checker.ast_module.exprs[statement.expr].kind) - if statement.target != ast.INVALID_EXPR { + if statement.target != ast.INVALID_EXPR && !symbol.is_valid(statement.name) { target_type := expected_assignment target_expr := checker.ast_module.exprs[statement.target] if target_expr.kind == .Name && !symbol.is_valid(target_expr.qualifier) { @@ -10922,7 +10922,7 @@ build_block :: proc( } switch statement.kind { case .Declaration: - // A value block (`x :: { ... yield v }` / `x T = { ... }`): the parser + // A value block (`x :: { ... yield v }` / `x T := { ... }`): the parser // leaves `expr` invalid and stashes the block in `body`. Build it, then // declare the local from the yielded value (its type for an untyped `::`). if statement.expr == ast.INVALID_EXPR { @@ -11123,7 +11123,7 @@ build_block :: proc( ctx.problematic^ = ctx.problematic^ || checker.module.exprs[value].kind == .Invalid } case .Assignment: - if statement.target != ast.INVALID_EXPR { + if statement.target != ast.INVALID_EXPR && !symbol.is_valid(statement.name) { target_expr := build_expr( checker, statement.target, ctx.locals^[:], ctx.global_reads, ctx.calls, types.INVALID, ctx.pkg, ctx.file, @@ -14349,18 +14349,6 @@ build_globals :: proc(checker: ^Checker) { ) expr = invalid_hir_expr(checker, global.span, diagnostic) } - if !global.immutable { - if !types.is_valid(global.type) { - diagnostic = source.addf( - checker.diagnostics, - global.span, - "mutable global '%s' requires a type annotation", - symbol_text(checker, global.name), - ) - global_type = types.I64 - expr = invalid_hir_expr(checker, global.span, diagnostic, global_type) - } - } static_value, is_static := static_integer_value(&checker.module, expr) is_static = is_static && diagnostic == source.INVALID_DIAGNOSTIC && global.immutable _ = hir.global_id(len(checker.module.globals)) diff --git a/compiler/lexer/lexer.odin b/compiler/lexer/lexer.odin index 4961087..5ea2d0a 100644 --- a/compiler/lexer/lexer.odin +++ b/compiler/lexer/lexer.odin @@ -133,9 +133,16 @@ lex :: proc( case ':': start := cursor cursor += 1 - if cursor < len(bytes) && bytes[cursor] == ':' { - cursor += 1 - append_token(&stream, source_file, .Colon_Colon, start, cursor) + if cursor < len(bytes) { + if bytes[cursor] == ':' { + cursor += 1 + append_token(&stream, source_file, .Colon_Colon, start, cursor) + } else if bytes[cursor] == '=' { + cursor += 1 + append_token(&stream, source_file, .Colon_Equal, start, cursor) + } else { + append_token(&stream, source_file, .Colon, start, cursor) + } } else { append_token(&stream, source_file, .Colon, start, cursor) } diff --git a/compiler/parser/parser.odin b/compiler/parser/parser.odin index e39bd75..b9c694a 100644 --- a/compiler/parser/parser.odin +++ b/compiler/parser/parser.odin @@ -1868,15 +1868,35 @@ parse_statement :: proc(parser: ^Parser) -> ast.Stmt_Id { had_type = true } operator := current(parser) - if operator.kind == .Colon_Colon || operator.kind == .Equal { + if had_type && operator.kind == .Equal { + diagnostic := source.add( + parser.diagnostics, + operator.span, + "mutable declarations use ':=' instead of '='", + ) + for current(parser).kind != .Newline && + current(parser).kind != .Right_Brace && + current(parser).kind != .Eof { + advance(parser) + } + id := ast.stmt_id(len(parser.module.statements)) + append(&parser.module.statements, ast.Stmt{ + kind=.Invalid, + span=span_from(name.span, operator.span), + expr=ast.INVALID_EXPR, + diagnostic=diagnostic, + }) + return id + } + is_sink := name.kind == .Underscore && operator.kind == .Equal + if operator.kind == .Colon_Colon || operator.kind == .Colon_Equal || is_sink { advance(parser) skip_newlines(parser) - kind := ast.Stmt_Kind.Assignment - immutable := false - if operator.kind == .Colon_Colon || had_type { - kind = .Declaration - immutable = operator.kind == .Colon_Colon + kind := ast.Stmt_Kind.Declaration + if is_sink { + kind = .Assignment } + immutable := operator.kind == .Colon_Colon // A labeled value block (`x :: blk: { … yield :blk v }`): the label lets a // `yield :blk` exit the block past a nested `if`. Block-init body + label. if current(parser).kind == .Identifier && peek(parser).kind == .Colon { @@ -1954,6 +1974,11 @@ parse_statement :: proc(parser: ^Parser) -> ast.Stmt_Id { } expr := parse_expression(parser) + assignment_name := symbol.INVALID + target_expr := parser.module.exprs[expr] + if target_expr.kind == .Name && !symbol.is_valid(target_expr.qualifier) { + assignment_name = target_expr.name + } if _, ok := allow(parser, .Equal); ok { skip_newlines(parser) // A labeled value block assigned to a complex target (`a[i] = blk: { … }`). @@ -1964,6 +1989,7 @@ parse_statement :: proc(parser: ^Parser) -> ast.Stmt_Id { append(&parser.module.statements, ast.Stmt{ kind=.Assignment, span=span_from(parser.module.exprs[expr].span, previous(parser).span), + name=assignment_name, target=expr, label=label, expr=ast.INVALID_EXPR, @@ -1980,6 +2006,7 @@ parse_statement :: proc(parser: ^Parser) -> ast.Stmt_Id { append(&parser.module.statements, ast.Stmt{ kind=.Assignment, span=span_from(parser.module.exprs[expr].span, brace.span), + name=assignment_name, target=expr, expr=ast.INVALID_EXPR, body=body, @@ -1995,6 +2022,7 @@ parse_statement :: proc(parser: ^Parser) -> ast.Stmt_Id { append(&parser.module.statements, ast.Stmt{ kind=.Assignment, span=span_from(parser.module.exprs[expr].span, previous(parser).span), + name=assignment_name, target=expr, value_control_flow=true, expr=ast.INVALID_EXPR, @@ -2008,6 +2036,7 @@ parse_statement :: proc(parser: ^Parser) -> ast.Stmt_Id { append(&parser.module.statements, ast.Stmt{ kind=.Assignment, span=span_from(parser.module.exprs[expr].span, parser.module.exprs[value].span), + name=assignment_name, target=expr, expr=value, diagnostic=source.INVALID_DIAGNOSTIC, @@ -3312,8 +3341,16 @@ parse_top_level :: proc(parser: ^Parser) { type_syntax = parse_type(parser) } operator := current(parser) - if operator.kind != .Colon_Colon && operator.kind != .Equal { - source.add(parser.diagnostics, operator.span, "expected '::' or '=' after top-level name") + if operator.kind == .Equal { + source.add(parser.diagnostics, operator.span, "mutable declarations use ':=' instead of '='") + for current(parser).kind != .Newline && current(parser).kind != .Eof { + advance(parser) + } + _ = finish_statement(parser) + return + } + if operator.kind != .Colon_Colon && operator.kind != .Colon_Equal { + source.add(parser.diagnostics, operator.span, "expected '::' or ':=' after top-level name") _ = finish_statement(parser) return } diff --git a/compiler/testing.odin b/compiler/testing.odin index 3fc56f2..88eba0b 100644 --- a/compiler/testing.odin +++ b/compiler/testing.odin @@ -180,7 +180,7 @@ append_runner :: proc( fmt.sbprintf(&builder, "%s.%s() catch |_| ", alias, symbol.resolve(symbols, test.name)) strings.write_string(&builder, "{\n\t\treturn .expectation_failed\n\t}\n}\n\n") } - strings.write_string(&builder, "main func() i32 {\n\tfailed i32 = 0\n") + strings.write_string(&builder, "main func() i32 {\n\tfailed i32 := 0\n") for entry, index in tests { test_id := entry.function test := module.functions[test_id] diff --git a/compiler/token/token.odin b/compiler/token/token.odin index 64c0404..e228824 100644 --- a/compiler/token/token.odin +++ b/compiler/token/token.odin @@ -16,6 +16,7 @@ Kind :: enum u8 { Underscore, Colon, Colon_Colon, + Colon_Equal, Equal, Equal_Equal, Bang, diff --git a/compiler_tests.odin b/compiler_tests.odin index 66c0542..f98d45e 100644 --- a/compiler_tests.odin +++ b/compiler_tests.odin @@ -214,12 +214,32 @@ lexer_recognizes_bitwise_operators_with_longest_match :: proc(t: ^testing.T) { } } +@(test) +lexer_recognizes_declaration_operators_with_longest_match :: proc(t: ^testing.T) { + source_file := source.Source{path="test.bro", 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) + + expected := [?]token.Kind{ + .Colon, .Colon_Colon, .Colon_Equal, .Equal, .Equal_Equal, .Eof, + } + testing.expect_value(t, len(diagnostics.items), 0) + testing.expect_value(t, len(stream.items), len(expected)) + for kind, index in expected { + testing.expect_value(t, stream.items[index].kind, kind) + } +} + @(test) parser_applies_bitwise_precedence_and_preserves_capture_and_deref_pipes :: proc(t: ^testing.T) { text := `main func() void { _ = 1 + 2 << 1 & 7 xor 3 | 4 == 5 and true or false - value i32 = 1 - pointer *i32 = &value + value i32 := 1 + pointer *i32 := &value _ = pointer^ & 1 if (null | null) |captured| { _ = captured } } @@ -368,10 +388,10 @@ bitwise_checker_rejects_invalid_operands_and_known_overshifts :: proc(t: ^testin text := `D :: distinct u8 E :: enum { one } main func() void { - p *u8 = null - d D = D(1) - e E = .one - signed_count i8 = 1 + p *u8 := null + d D := D(1) + e E := .one + signed_count i8 := 1 _ = true & false _ = 1.0 | 2.0 _ = ~p @@ -716,6 +736,89 @@ foreign :: c_func() i32 testing.expect_value(t, len(module.functions), 2) } +@(test) +parser_distinguishes_inferred_typed_immutable_and_mutable_declarations :: proc(t: ^testing.T) { + text := `global_inferred_immutable :: 1 +global_typed_immutable i32 :: 2 +global_inferred_mutable := 3 +global_typed_mutable i32 := 4 +main func() void { + local_inferred_immutable :: 1 + local_typed_immutable i32 :: 2 + local_inferred_mutable := 3 + local_typed_mutable i32 := 4 + local_inferred_mutable = 5 +} +` + 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) + + testing.expect_value(t, len(diagnostics.items), 0) + testing.expect_value(t, len(module.globals), 4) + testing.expect(t, !types.is_valid(module.globals[0].type)) + testing.expect(t, module.globals[0].immutable) + testing.expect(t, types.is_valid(module.globals[1].type)) + testing.expect(t, module.globals[1].immutable) + testing.expect(t, !types.is_valid(module.globals[2].type)) + testing.expect(t, !module.globals[2].immutable) + testing.expect(t, types.is_valid(module.globals[3].type)) + testing.expect(t, !module.globals[3].immutable) + + body := module.functions[0].body + testing.expect_value(t, len(body), 5) + testing.expect(t, !types.is_valid(module.statements[body[0]].type)) + testing.expect(t, module.statements[body[0]].immutable) + testing.expect(t, types.is_valid(module.statements[body[1]].type)) + testing.expect(t, module.statements[body[1]].immutable) + testing.expect(t, !types.is_valid(module.statements[body[2]].type)) + testing.expect(t, !module.statements[body[2]].immutable) + testing.expect(t, types.is_valid(module.statements[body[3]].type)) + testing.expect(t, !module.statements[body[3]].immutable) + testing.expect_value(t, module.statements[body[4]].kind, ast.Stmt_Kind.Assignment) + testing.expect(t, module.statements[body[4]].target != ast.INVALID_EXPR) +} + +@(test) +parser_rejects_legacy_typed_mutable_declarations_and_recovers :: proc(t: ^testing.T) { + text := `legacy_global i32 = 1 +kept_global := 2 +main func() void { + legacy_local i32 = 1 + kept_local := 2 +} +` + 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 diagnostic.message == "mutable declarations use ':=' instead of '='" { + found += 1 + } + } + testing.expect_value(t, found, 2) + testing.expect_value(t, len(module.globals), 1) + testing.expect(t, !module.globals[0].immutable) + body := module.functions[0].body + testing.expect_value(t, len(body), 2) + testing.expect_value(t, module.statements[body[0]].kind, ast.Stmt_Kind.Invalid) + testing.expect_value(t, module.statements[body[1]].kind, ast.Stmt_Kind.Declaration) +} + @(test) parser_diagnoses_malformed_sentinel_pointer_types :: proc(t: ^testing.T) { text := `bad func(value [*0]u8) void {} @@ -861,7 +964,7 @@ main func() void {} @(test) parser_accepts_undefined_expression :: proc(t: ^testing.T) { text := `main func() void { - value i32 = undefined + value i32 := undefined } ` source_file := source.Source{path="test.bro", text=text} @@ -1461,9 +1564,9 @@ fallback func() i32 { } main func() void { c :: 1 - values [2;0]mut u8 = [1, 2] + values [2;0]mut u8 := [1, 2] point Point :: Point{x = 3, y = 4} - maybe ?i32 = 5 + maybe ?i32 := 5 _ = c _ = values[2] _ = (&values).ptr + 1 @@ -1520,7 +1623,7 @@ take_c_string c_func(value *c_char) c_int take_c_sentinel c_func(value [*;0]c_char) c_int main func() void { text :: "hello" - values [2;0]mut u8 = [1, 2] + values [2;0]mut u8 := [1, 2] pointer :: &values _ = text.len _ = text.ptr @@ -1636,12 +1739,12 @@ take_mut_pointer func(value *mut u8) void {} take_slice func(value []u8) void {} bad_sentinel func(value [*;256]u8) void {} main func() void { - values [1;0]mut u8 = [1] + values [1;0]mut u8 := [1] _ = values.ptr take_pointer(values) take_slice(values) ordinary *u8 :: "hello" - nonzero [1;'\n']mut u8 = [1] + nonzero [1;'\n']mut u8 := [1] take_pointer("hello"[1..]) _ = take_c_string(ordinary) _ = take_c_string((&nonzero).ptr) @@ -1680,7 +1783,7 @@ main func() void { @(test) immutable_pointer_and_slice_bindings_preserve_mutable_pointees :: proc(t: ^testing.T) { text := `main func() void { - values [2]mut u8 = [1, 2] + values [2]mut u8 := [1, 2] pointer *mut u8 :: (&values).ptr slice []mut u8 :: values[0..] pointer[0] = 3 @@ -1708,7 +1811,7 @@ many_item_pointer_slices_compile_and_run :: proc(t: ^testing.T) { main_path := "/tmp/brolang-test-pointer-slices/main.bro" output := "/tmp/brolang-test-pointer-slices-output" text := `main func() i32 { - values [4]mut i32 = [3, 4, 5, 6] + values [4]mut i32 := [3, 4, 5, 6] pointer *mut i32 :: (&values).ptr const_pointer *i32 :: pointer all []mut i32 :: pointer[..4] @@ -1737,7 +1840,7 @@ many_item_pointer_slices_compile_and_run :: proc(t: ^testing.T) { @(test) many_item_pointer_slices_require_end_bound :: proc(t: ^testing.T) { text := `main func() void { - values [2]i32 = [1, 2] + values [2]i32 := [1, 2] pointer *i32 :: (&values).ptr _ = pointer[..] _ = pointer[1..] @@ -1797,19 +1900,19 @@ needs_usize func(value usize) usize { } buffer func($T type) [sizeof!(T)]u8 { - data [sizeof!(T)]u8 = undefined + data [sizeof!(T)]u8 := undefined return data } make_bool_first func() Bool_First { - value Bool_First = undefined + value Bool_First := undefined value.flag = true value.byte = 41 return value } make_bool_last func() Bool_Last { - value Bool_Last = undefined + value Bool_Last := undefined value.byte = 42 value.flag = true return value @@ -1881,11 +1984,11 @@ main func() i32 { if (maximum(u16) != 65535) return 8 if (minval!(c_int) != -2147483648) return 9 if (maxval!(c_ulong) != 18446744073709551615) return 10 - signed_min Signed = minval!(Signed) - unsigned_max Unsigned = maxval!(Unsigned) - nested_max Outer = maxval!(Outer) - generic_min Signed = maximum(Signed) - generic_nested Outer = maximum(Outer) + signed_min Signed := minval!(Signed) + unsigned_max Unsigned := maxval!(Unsigned) + nested_max Outer := maxval!(Outer) + generic_min Signed := maximum(Signed) + generic_nested Outer := maximum(Outer) if i16(signed_min) != -32768 { return 11 } if u16(unsigned_max) != 65535 { return 12 } if u8(nested_max) != 255 { return 13 } @@ -1995,7 +2098,7 @@ slicing_an_array_variable_takes_its_address_implicitly :: proc(t: ^testing.T) { return s[0] } main func() i32 { - arr [4]i32 = [10, 20, 30, 40] + arr [4]i32 := [10, 20, 30, 40] full :: sink(arr[..]) part :: sink(arr[1..3]) return full + part @@ -2269,22 +2372,22 @@ opaque_anyopaque_and_ptrcast_compile_and_lower :: proc(t: ^testing.T) { take func(_ ?*mut anyopaque) void {} use_handle func(_ ?@mut Handle) void {} main func() void { - values [2]mut u8 = [1, 2] - raw ?*mut anyopaque = (&values).ptr - bytes ?*mut u8 = ptrcast!(u8, raw) + values [2]mut u8 := [1, 2] + raw ?*mut anyopaque := (&values).ptr + bytes ?*mut u8 := ptrcast!(u8, raw) take(bytes) if bytes |p| { p[1] = 5 } - one u8 = 1 - single ?@mut anyopaque = &one - typed ?@mut u8 = ptrcast!(u8, single) + one u8 := 1 + single ?@mut anyopaque := &one + typed ?@mut u8 := ptrcast!(u8, single) if typed |p| { p^ = 2 } - handle ?@mut Handle = null + handle ?@mut Handle := null use_handle(handle) } ` @@ -2322,8 +2425,8 @@ main func() void { anyopaque_by_value_and_invalid_ptrcasts_are_rejected :: proc(t: ^testing.T) { text := `Callback :: alias c_func() void main func() void { - raw ?*mut anyopaque = null - value anyopaque = undefined + raw ?*mut anyopaque := null + value anyopaque := undefined _ = ptrcast!(void, raw) _ = ptrcast!(anyopaque, raw) _ = ptrcast!(Callback, raw) @@ -2362,25 +2465,25 @@ main func() void { @(test) constcast_restores_pointer_and_slice_mutability :: proc(t: ^testing.T) { text := `main func() i32 { - values [2]mut u8 = [1, 2] - immutable_slice []u8 = values[..] - mutable_slice []mut u8 = constcast!(immutable_slice) + values [2]mut u8 := [1, 2] + immutable_slice []u8 := values[..] + mutable_slice []mut u8 := constcast!(immutable_slice) mutable_slice[0] = 3 - immutable_many *u8 = immutable_slice.ptr - mutable_many *mut u8 = constcast!(immutable_many) + immutable_many *u8 := immutable_slice.ptr + mutable_many *mut u8 := constcast!(immutable_many) mutable_many[1] = 4 - number i32 = 5 - immutable_single @i32 = &number - mutable_single @mut i32 = constcast!(immutable_single) + number i32 := 5 + immutable_single @i32 := &number + mutable_single @mut i32 := constcast!(immutable_single) mutable_single^ = 6 - maybe ?@i32 = immutable_single - mutable_maybe ?@mut i32 = constcast!(maybe) + maybe ?@i32 := immutable_single + mutable_maybe ?@mut i32 := constcast!(maybe) if mutable_maybe |pointer| { pointer^ = 7 } - already_mutable []mut u8 = constcast!(mutable_slice) + already_mutable []mut u8 := constcast!(mutable_slice) if already_mutable[0] != 3 or already_mutable[1] != 4 or number != 7 { return 1 } return 0 } @@ -2428,7 +2531,7 @@ constcast_restores_pointer_and_slice_mutability :: proc(t: ^testing.T) { @(test) invalid_constcasts_are_rejected :: proc(t: ^testing.T) { text := `main func() void { - values [2]mut u8 = [1, 2] + values [2]mut u8 := [1, 2] _ = constcast!() _ = constcast!(1, 2) _ = constcast!(1) @@ -2461,9 +2564,9 @@ immutable_allocations_can_be_freed_and_constcast_keeps_slice_bounds_checks :: pr main func() i32 { memory []mut u8 :: mem.alloc(u8, mem.c_allocator, 4) catch |_| { return 1 } memory[0] = 42 - immutable []u8 = memory + immutable []u8 := memory mem.free(mem.c_allocator, immutable) - empty []u8 = mem.empty(u8) + empty []u8 := mem.empty(u8) mem.free(mem.c_allocator, empty) return 0 } @@ -2483,9 +2586,9 @@ main func() i32 { testing.expect_value(t, state.exit_code, 0) bounds_text := `main func() void { - values [2]mut u8 = [1, 2] - immutable []u8 = values[..] - mutable []mut u8 = constcast!(immutable) + values [2]mut u8 := [1, 2] + immutable []u8 := values[..] + mutable []mut u8 := constcast!(immutable) _ = mutable[mutable.len] } ` @@ -2619,7 +2722,7 @@ intrinsic_call_diagnostics_are_precise :: proc(t: ^testing.T) { memory_intrinsics_compile_run_and_lower :: proc(t: ^testing.T) { text := `Pair :: struct { x i32, y i32 } -calls i32 = 0 +calls i32 := 0 destination_view func(value []mut u8) []mut u8 { calls += 1 @@ -2632,8 +2735,8 @@ source_view func(value []u8) []u8 { } compile_value func() [4]mut u8 { - source [4]mut u8 = [1, 2, 3, 4] - destination [4]mut u8 = undefined + source [4]mut u8 := [1, 2, 3, 4] + destination [4]mut u8 := undefined memset!(&destination, undefined) memcopy!(&destination, &source) memset!(destination[1..3], 9) @@ -2646,20 +2749,20 @@ known :: $compile_value() main func() i32 { if known[0] != 1 or known[1] != 9 or known[2] != 9 or known[3] != 4 { return 1 } - bytes [4]mut u8 = undefined - source [4]mut u8 = [4, 3, 2, 1] + bytes [4]mut u8 := undefined + source [4]mut u8 := [4, 3, 2, 1] memset!(&bytes, undefined) memcopy!(destination_view(bytes[..]), source_view(source[..])) if calls != 2 or bytes[0] != 4 or bytes[3] != 1 { return 2 } memset!(bytes[1..3], 7) if bytes[1] != 7 or bytes[2] != 7 { return 3 } - wide [2]mut i32 = undefined + wide [2]mut i32 := undefined memset!(&wide, 42) if wide[0] != 42 or wide[1] != 42 { return 4 } - pairs [2]mut Pair = undefined - pair_source [2]mut Pair = [Pair{x = 1, y = 2}, Pair{x = 3, y = 4}] + pairs [2]mut Pair := undefined + pair_source [2]mut Pair := [Pair{x = 1, y = 2}, Pair{x = 3, y = 4}] memcopy!(&pairs, &pair_source) memset!(pairs[1..], Pair{x = 7, y = 8}) if pairs[0].x != 1 or pairs[1].y != 8 { return 5 } @@ -2717,20 +2820,20 @@ main func() i32 { @(test) memory_intrinsic_diagnostics_are_precise :: proc(t: ^testing.T) { text := `bad_length func() [1]mut u8 { - destination [1]mut u8 = undefined - source [2]mut u8 = [1, 2] + destination [1]mut u8 := undefined + source [2]mut u8 := [1, 2] memcopy!(&destination, &source) return destination } bad_overlap func() [3]mut u8 { - items [3]mut u8 = [1, 2, 3] + items [3]mut u8 := [1, 2, 3] memcopy!(items[..2], items[1..]) return items } bad_undefined func() u8 { - items [1]mut u8 = [1] + items [1]mut u8 := [1] memset!(&items, undefined) return items[0] } @@ -2740,9 +2843,9 @@ overlap_value :: $bad_overlap() undefined_value :: $bad_undefined() main func() void { - immutable [2]u8 = [1, 2] - mutable [2]mut u8 = undefined - wide [2]mut u16 = undefined + immutable [2]u8 := [1, 2] + mutable [2]mut u8 := undefined + wide [2]mut u16 := undefined memcopy!(&immutable, &mutable) memcopy!(&mutable, &wide) memcopy!(1, 2) @@ -2794,8 +2897,8 @@ memory_intrinsic_runtime_guards_trap :: proc(t: ^testing.T) { "/tmp/brolang-test-memcopy-length-trap-output", `copy func(destination []mut u8, source []u8) void { memcopy!(destination, source) } main func() void { - destination [2]mut u8 = undefined - source [3]mut u8 = [1, 2, 3] + destination [2]mut u8 := undefined + source [3]mut u8 := [1, 2, 3] copy(destination[..], source[..]) } `, @@ -2805,7 +2908,7 @@ main func() void { "/tmp/brolang-test-memcopy-overlap-trap-output", `copy func(destination []mut u8, source []u8) void { memcopy!(destination, source) } main func() void { - items [4]mut u8 = [1, 2, 3, 4] + items [4]mut u8 := [1, 2, 3, 4] copy(items[1..], items[..3]) } `, @@ -3082,7 +3185,7 @@ missing_fails func(system io.Io) bool { } wrong_read_fails func(file io.File) bool { - buffer [1]mut u8 = [0] + buffer [1]mut u8 := [0] _ = io.read(io.reader(file), buffer[..]) catch |err| { return err == .not_open_for_reading } @@ -3104,8 +3207,8 @@ main func(init process.Init) i32 { read_file io.File :: io.open(init.io, "/tmp/brolang-test-file-io/data", .read_only) catch |_| { return 2 } - buffer [5]mut u8 = [0, 0, 0, 0, 0] - count usize = io.read(io.reader(read_file), buffer[..]) catch |_| { + buffer [5]mut u8 := [0, 0, 0, 0, 0] + count usize := io.read(io.reader(read_file), buffer[..]) catch |_| { return 4 } if count != 5 or buffer[0] != 'x' or !wrong_write_fails(read_file) { @@ -3383,10 +3486,10 @@ Plain :: union { value i32 } main func() void { inline for {1} |value| { _ = value } - n i32 = 1 + n i32 := 1 match n { inline |value|: _ = value } - e E = .a + e E := .a match e { inline |value, tag|: _ = value } match e { .a, .b: {} @@ -3401,7 +3504,7 @@ main func() void { inline |value|: _ = value } - u Plain = Plain{value = 1} + u Plain := Plain{value = 1} _ = tag!(u) _ = tagname!(e) @@ -3773,10 +3876,10 @@ increment func(value i32) i32 { return value + 1 } bad_param func(callback Callback) i32 { return callback(1) } bad_config func(config Config) i32 { return config.callback(1) } bad_result func() Callback { return increment } -stored Callback = increment +stored Callback := increment main func() void { - local Callback = increment + local Callback := increment _ = bad_result() } ` @@ -3870,7 +3973,7 @@ main func() i32 { return answer } @(test) milestone_37_expand_loop_control_must_be_statically_resolvable :: proc(t: ^testing.T) { text := `main func() void { - total i32 = 0 + total i32 := 0 inline for {1, 2} |value| { if total == 0 { break @@ -3909,20 +4012,20 @@ milestone_37_comptime_undefined_aggregates_support_full_initialization :: proc(t } Partial :: struct { initialized i32, text []u8 } make_tokens func() [2]mut Token { - tokens [2]mut Token = undefined + tokens [2]mut Token := undefined tokens[0] = Token {text = "a", count = 1} tokens[1].text = "bro" tokens[1].count = 3 return tokens } read_initialized_sibling func() i32 { - value Partial = undefined + value Partial := undefined value.initialized = 42 return value.initialized } answer :: $read_initialized_sibling() main func() i32 { - total usize = 0 + total usize := 0 inline for make_tokens() |token| { total += token.text.len + token.count } @@ -3951,11 +4054,11 @@ main func() i32 { milestone_37_comptime_undefined_values_cannot_be_observed :: proc(t: ^testing.T) { text := `Bad :: struct { value i32, text []u8 } read_scalar func() i32 { - value i32 = undefined + value i32 := undefined return value } return_partial func() Bad { - value Bad = undefined + value Bad := undefined value.value = 1 return value } @@ -3963,7 +4066,7 @@ take_bad func(value Bad) i32 { return value.value } pass_partial func() i32 { - value Bad = undefined + value Bad := undefined value.value = 1 return take_bad(value) } @@ -4003,7 +4106,7 @@ milestone_37_expand_expansions_keep_distinct_call_resolutions :: proc(t: ^testin return value } main func() i32 { - total i64 = 0 + total i64 := 0 inline for {{i8(1), i16(2)}, {i32(3), i64(4)}} |row| { inline for row |value| { total += i64(identity(value)) @@ -4399,10 +4502,10 @@ main func() void { @(test) unused_locals_and_params_warn_without_traps :: proc(t: ^testing.T) { text := `warn_only func(value i32, unused i32) i32 { - local i32 = 1 - write_only i32 = 2 + local i32 := 1 + write_only i32 := 2 write_only = 3 - consumed i32 = value + consumed i32 := value _ = consumed return value } @@ -4690,17 +4793,17 @@ main func() i32 { @(test) zero_runtime_calls_fold_with_runtime_fallback :: proc(t: ^testing.T) { - text := `runtime_value i32 = 41 + text := `runtime_value i32 := 41 folded func() i32 { return 42 } by_value func($N usize) usize { return N } backed func() []i32 { - values [2]mut i32 = [3, 4] + values [2]mut i32 := [3, 4] return values[..] } fallback func() i32 { return runtime_value } undefined_result func() i32 { - value i32 = undefined + value i32 := undefined return value } @@ -4757,8 +4860,8 @@ zero_runtime_fold_tracks_mutated_locals_in_dependent_array_types :: proc(t: ^tes } Pair func($V type) type { return struct { []u8, V } } build_map func($V type, $N usize, $entries [N]Pair(V)) FoldedMap(V) { - keys [N]mut []u8 = undefined - values [N]mut V = undefined + keys [N]mut []u8 := undefined + values [N]mut V := undefined for entries |entry, i| { keys[i] = entry.0 values[i] = entry.1 @@ -4766,7 +4869,7 @@ build_map func($V type, $N usize, $entries [N]Pair(V)) FoldedMap(V) { for 1..N |i| { key :: keys[i] value :: values[i] - j usize = i + j usize := i while j > 0 and keys[j - 1].len > key.len : j -= 1 { keys[j] = keys[j - 1] values[j] = values[j - 1] @@ -4775,7 +4878,7 @@ build_map func($V type, $N usize, $entries [N]Pair(V)) FoldedMap(V) { values[j] = value } max_len usize :: keys[N - 1].len - indexes [max_len + 1]mut u32 = undefined + indexes [max_len + 1]mut u32 := undefined for 0..=max_len |length| { indexes[length] = 0 } @@ -4845,7 +4948,7 @@ main func() i32 { return fail() } @(test) comptime_value_params_specialize_by_value_and_omit_runtime_args :: proc(t: ^testing.T) { text := `make_array func($N usize) [N]u8 { - data [N]u8 = undefined + data [N]u8 := undefined return data } main func() void { @@ -4904,7 +5007,7 @@ bad_use func($N usize) void { } main func() void { good_bool(true) - x usize = 4 + x usize := 4 _ = make(x) _ = make() _ = make(1, 2) @@ -4964,7 +5067,7 @@ BoxAlias func($T type) type { return Box(T) } conflict func($T type, left, right T) T { return left } -unknown func($T type) T { value T = undefined; return value } +unknown func($T type) T { value T := undefined; return value } partial func($T type, $N usize, value T) T { return value } use_ignored func($T type, value Ignored(T)) i32 { return value } use_alias func($T type, value BoxAlias(T)) T { return value.value } @@ -5069,22 +5172,22 @@ main func() void { @(test) comptime_params_may_be_interleaved_and_are_erased_from_the_abi :: proc(t: ^testing.T) { text := `valid func($T type, $N usize, value T) [N]T { - result [N]T = undefined + result [N]T := undefined _ = value return result } runtime_first func(value T, $T type, $N usize) T { return value } split func($T type, value T, $N usize) [N]T { - result [N]T = undefined + result [N]T := undefined _ = value return result } from_result func($T type) T { - value T = undefined + value T := undefined return value } choose_mapping func($A usize, value i32, $B usize) [A]u8 { - result [A]u8 = undefined + result [A]u8 := undefined _ = value _ = B return result @@ -5094,7 +5197,7 @@ main func() void { _ = runtime_first(42, _, 4) _ = split(i32, 42, 4) _ = split(42, 4) - value i32 = from_result() + value i32 := from_result() chosen [1]u8 :: choose_mapping(7, 2) _ = value _ = chosen @@ -5134,11 +5237,11 @@ id func($T type, value T) T { return value } zero func($T type) T { - value T = undefined + value T := undefined return value } buffer func($T type, $N usize, _ T) [N]T { - data [N]T = undefined + data [N]T := undefined return data } main func() void { @@ -5207,7 +5310,7 @@ bad_assign func($T type) void { T = 1 } main func() void { - x i32 = 1 + x i32 := 1 _ = id(x, x) bad_value(i32) bad_assign(i32) @@ -5259,7 +5362,7 @@ nested func(value int) int { return sum(value, two) } make_array func($N usize) [N]u8 { - data [N]u8 = undefined + data [N]u8 := undefined return data } forced :: $sum(1, 2) @@ -5323,7 +5426,7 @@ missing func() i32 { } GLOBAL :: 1 main func() void { - runtime i32 = 1 + runtime i32 := 1 _ = $runtime _ = $native() _ = ${ @@ -5332,26 +5435,26 @@ main func() void { } _ = $&GLOBAL _ = ${ - values [2]mut i32 = [1, 2] + values [2]mut i32 := [1, 2] pointer *mut i32 :: (&values).ptr yield pointer } _ = ${ - values [2]mut i32 = [1, 2] + values [2]mut i32 := [1, 2] yield values[1..].ptr } _ = ${ - values [2]mut i32 = [1, 2] + values [2]mut i32 := [1, 2] yield &values[0] } _ = ${ - values [2]mut i32 = [1, 2] - view []mut i32 = values[..] + values [2]mut i32 := [1, 2] + view []mut i32 := values[..] yield view } _ = ${ - values [2]mut i32 = [1, 2] - view []i32 = values[1..] + values [2]mut i32 := [1, 2] + view []i32 := values[1..] yield view } _ = $spin() @@ -5402,7 +5505,7 @@ main func() void { @(test) native_function_pointer_type_restrictions_are_diagnosed :: proc(t: ^testing.T) { text := `main func() void { - callback @func(...) void = undefined + callback @func(...) void := undefined } ` source_file := source.Source{path="test.bro", text=text} @@ -5812,7 +5915,7 @@ run func(callbacks Callbacks) i32 { return callbacks.call(callbacks.value) } main func() i32 { - callbacks Callbacks = Callbacks { + callbacks Callbacks := Callbacks { call = func(value i32) i32 { return value + 1 }, @@ -5862,7 +5965,7 @@ qualified_value_calls_do_not_imply_package_resolution :: proc(t: ^testing.T) { call @func() void } main func() void { - callbacks Callbacks = Callbacks{call = func() void {}} + callbacks Callbacks := Callbacks{call = func() void {}} callbacks.call() missing.call() } @@ -5887,8 +5990,8 @@ main func() void { @(test) function_literals_do_not_capture_locals :: proc(t: ^testing.T) { text := `main func() i32 { - offset i32 = 1 - callback @func(value i32) i32 = func(value i32) i32 { + offset i32 := 1 + callback @func(value i32) i32 := func(value i32) i32 { return value + offset } return callback(1) @@ -5919,7 +6022,7 @@ field_function_pointer_calls_reject_non_callable_fields :: proc(t: ^testing.T) { value i32 } main func() void { - box Box = Box { value = 1 } + box Box := Box { value = 1 } box.value() } ` @@ -6310,7 +6413,7 @@ labeled_block_supplies_value_if_branch_through_catch :: proc(t: ^testing.T) { ScanResult :: struct { end usize } scan func() ScanResult ! Failure { return .bad } main func() i32 { - start usize = 3 + start usize := 3 end :: if (true) done: { result :: scan() catch { yield :done start @@ -6381,7 +6484,7 @@ Data :: union(Animal) { bird i32 } main func() i32 { - x Data = Data{ bird = 99 } + x Data := Data{ bird = 99 } return x.bird } ` @@ -6482,10 +6585,10 @@ payload func(value UBoth) i32 { } } main func() i32 { - a A = .left - b B = .right - u UA = UA{ item = 4 } - v UB = .empty + a A := .left + b B := .right + u UA := UA{ item = 4 } + v UB := .empty return pick(.same) + pick(a) + pick(b) + payload(u) + payload(v) } ` @@ -6829,7 +6932,7 @@ comptime_scenario func() i32 { } main func() i32 { comptime_result i32 :: $comptime_scenario() - handled bool = false + handled bool := false fail() catch |_| { handled = true } if !handled { return 3 } succeed() catch |_| { return 1 } @@ -6992,7 +7095,7 @@ aliased func() usize ! GoodError { } mutable_subject func() usize ! GoodError { source() catch |err| { - value Combined = err + value Combined := err match value { .bad: unreachable else: return value @@ -7044,8 +7147,8 @@ conversion_diagnostics_render_source_types :: proc(t: ^testing.T) { } take func(allocator Allocator, memory []mut u8) void {} main func() void { - allocator Allocator = Allocator { marker = 0 } - data [1]mut u8 = [0] + allocator Allocator := Allocator { marker = 0 } + data [1]mut u8 := [0] take(data[..], allocator) } ` @@ -7100,7 +7203,7 @@ with_detail func(value i32) i32 ! DetailError { return value } main func() i32 { - e DetailError = .code{3} + e DetailError := .code{3} recovered :: with_detail(0) catch |err| { result i32 :: match err { .code |n|: n @@ -7179,7 +7282,7 @@ inline_payload func(value i32) i32 ! union(enum) { return value } main func() i32 { - e PayloadError = .not_found{path = 1, line = 2} + e PayloadError := .not_found{path = 1, line = 2} a :: accept(e) b :: accept(.wrapped{line = 4, path = 3}) c :: with_payload(0) catch |err| { @@ -7452,8 +7555,8 @@ Data :: union(Animal) { bird i32 } main func() i32 { - d Data = Data{ bird = 7 } - out i32 = 0 + d Data := Data{ bird = 7 } + out i32 := 0 match d { .dog |v|: out = v .bird |v|: out = v + 1 @@ -7537,7 +7640,7 @@ unknown_variant func(d Data) i32 { } main func() i32 { # Functions are specialized on use, so call each so its body is type-checked. - d Data = Data{ dog = 0 } + d Data := Data{ dog = 0 } return not_exhaustive(.dog) + missing_else(0) + bad_capture(.dog) + redundant_else(.dog) + unknown_variant(d) } @@ -7578,8 +7681,8 @@ match_range_arm_emits_bounds :: proc(t: ^testing.T) { // A scalar range arm `lo..hi:` desugars to `key >= lo and key < hi` (inclusive uses // `<=`), emitted as signed integer comparisons for an i32 subject. text := `main func() i32 { - n i32 = 5 - out i32 = 0 + n i32 := 5 + out i32 := 0 match n { 0..10: out = 1 10..=20: out = 2 @@ -7640,11 +7743,11 @@ void_capture func(b Box) i32 { return 0 } void_value func() i32 { - b Box = Box{ empty = 5 } + b Box := Box{ empty = 5 } return 0 } bare_on_nonvoid func() i32 { - b Box = Box{ count } + b Box := Box{ count } return 0 } range_on_enum func(a Animal) i32 { @@ -7662,7 +7765,7 @@ incompatible_capture func(b Box) i32 { return 0 } main func() i32 { - b Box = Box{ count = 1 } + b Box := Box{ count = 1 } return void_capture(b) + void_value() + bare_on_nonvoid() + range_on_enum(.dog) + incompatible_capture(b) } @@ -7717,8 +7820,8 @@ get func() Animal { return .bird } main func() i32 { - e Box = .empty - r i32 = 0 + e Box := .empty + r i32 := 0 match get() { .dog: r = 1 .cat: r = 2 @@ -7764,7 +7867,7 @@ Box :: union(enum) { empty void } bad func() i32 { - e Box = .point + e Box := .point return 0 } main func() i32 { @@ -9286,7 +9389,7 @@ main func() void { sink(missing_arg) missing_stmt() missing_target.field = 1 - value i32 = 0 + value i32 := 0 value += missing_rhs _ = broken(1) } @@ -9722,12 +9825,12 @@ mutable_globals_infer_constraints_and_emit_writable_storage :: proc(t: ^testing. text := `Point :: struct { x i32 } -counter int = 0 -ratio float = 1 -span range = 0..2 -point Point = Point { x = 1 } -unset Point = undefined -values [_]mut i32 = [10, 20] +counter := i32(0) +ratio := 1.0 +span := 0..2 +point Point := Point { x = 1 } +unset Point := undefined +values [_]mut i32 := [10, 20] main func() void { counter = 1 counter += 1 @@ -9789,27 +9892,28 @@ main func() void { mutable_global_diagnostics_and_no_shadowing :: proc(t: ^testing.T) { text := `ID :: distinct i32 OtherID :: distinct i32 -ID i32 = 0 -counter = 0 -runtime i32 = 1 +ID i32 := 0 +counter := 0 +runtime i32 := 1 +unresolved := undefined immutable :: 1 foo func(foo i32) void {} main func() void { _ = $runtime immutable = 2 - OtherID i32 = 0 - local i32 = 0 + OtherID i32 := 0 + local i32 := 0 if true { - local i32 = 1 + local i32 := 1 } for 0..1 |local| {} - scope i32 = 0 + scope i32 := 0 scope: {} mark: { - mark i32 = 0 + mark i32 := 0 } - value i32 = value_label: { - value_label i32 = 1 + value i32 := value_label: { + value_label i32 := 1 yield :value_label 1 } } @@ -9826,8 +9930,8 @@ main func() void { hir_module := checker.check(&ast_module, &diagnostics, &symbols) defer hir.destroy_module(&hir_module) - missing_type := false not_comptime := false + unresolved_type := false immutable_write := false global_type_shadow := false param_shadow := false @@ -9838,8 +9942,8 @@ main func() void { local_label_shadow := false value_label_shadow := false for diagnostic in diagnostics.items { - missing_type = missing_type || strings.contains(diagnostic.message, "mutable global 'counter' requires a type annotation") not_comptime = not_comptime || strings.contains(diagnostic.message, "global 'runtime' is not comptime-known") + unresolved_type = unresolved_type || strings.contains(diagnostic.message, "could not resolve a concrete type for global 'unresolved'") immutable_write = immutable_write || strings.contains(diagnostic.message, "assignment target is not writable") global_type_shadow = global_type_shadow || strings.contains(diagnostic.message, "global 'ID' shadows visible type") param_shadow = param_shadow || strings.contains(diagnostic.message, "parameter 'foo' shadows visible function") @@ -9850,8 +9954,8 @@ main func() void { local_label_shadow = local_label_shadow || strings.contains(diagnostic.message, "local 'mark' shadows visible label") value_label_shadow = value_label_shadow || strings.contains(diagnostic.message, "local 'value_label' shadows visible label") } - testing.expect(t, missing_type) testing.expect(t, not_comptime) + testing.expect(t, unresolved_type) testing.expect(t, immutable_write) testing.expect(t, global_type_shadow) testing.expect(t, param_shadow) @@ -10009,7 +10113,7 @@ hide_is_rejected_outside_named_top_level_declarations :: proc(t: ^testing.T) { `hide func() void {}`, `main func(hide value i32) void {}`, `Box :: struct { hide i32 }`, - `main func() void { hide value i32 = 1 }`, + `main func() void { hide value i32 := 1 }`, } for text in cases { source_file := source.Source{path="test.bro", text=text} @@ -10177,7 +10281,7 @@ declaration_aliases_preserve_identity_and_chain :: proc(t: ^testing.T) { return struct { value T } } Point :: struct { value i32 } -counter i32 = 1 +counter i32 := 1 answer func() i32 { return 40 } ` facade_text := `dep :: import "../dep" @@ -10482,12 +10586,12 @@ type_factory_rejects_runtime_parameters_and_recursion :: proc(t: ^testing.T) { `Bad func($T type, n usize) type { return struct { value [n]T } } -main func() void { value Bad(i32, 4) = undefined; _ = &value } +main func() void { value Bad(i32, 4) := undefined; _ = &value } `, `Loop func($T type) type { return struct { next @Loop(T) } } -main func() void { value Loop(i32) = undefined; _ = &value } +main func() void { value Loop(i32) := undefined; _ = &value } `, `Box func($T type) type { return struct { value T } @@ -10497,7 +10601,7 @@ main func() void { _ = Box(i32) } `Bad func($T type) type { return 1 } -main func() void { value Bad(i32) = undefined; _ = &value } +main func() void { value Bad(i32) := undefined; _ = &value } `, } wanted := []string{"must be comptime", "recursive type-factory specialization", "only valid in type position", "cannot implicitly convert"} @@ -10591,11 +10695,11 @@ render_literal func(node @Node, tokens []Token, program []u8) ?[]u8 { main_text := `ast :: import "./ast" main func() i32 { - nodes [1]mut ast.Node = undefined + nodes [1]mut ast.Node := undefined nodes[0].token = 0 - token_storage [1]mut ast.Token = undefined + token_storage [1]mut ast.Token := undefined token_storage[0].start = 0 - mutable_tokens []mut ast.Token = token_storage[..] + mutable_tokens []mut ast.Token := token_storage[..] program :: "x" for nodes |node| { _ = ast.render_literal(&node, mutable_tokens, program) @@ -10873,8 +10977,8 @@ 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 { - first ?i32 = 1 - second ?i32 = 2 + first ?i32 := 1 + second ?i32 := 2 if (first and second) |a, b : a == 1 and b == 2| { _ = a _ = b @@ -10905,12 +11009,12 @@ conditional_unwrap_parser_captures_guard_and_parenthesized_chain :: proc(t: ^tes parser_accepts_braceless_if_bodies :: proc(t: ^testing.T) { text := `ready func() bool { return true } main func() void { - x i32 = 0 + x i32 := 0 if (x == 0) x = 1 if ready() x = 2 if (x == 2) x = 3 else x = 4 if (x > 0) { x = 10 } else x = 11 - v ?i32 = 5 + v ?i32 := 5 if (v) |u| _ = u } ` @@ -10955,7 +11059,7 @@ main func() void { match_else_arm_is_not_captured_by_braceless_if :: proc(t: ^testing.T) { text := `ready func() bool { return true } main func() void { - value i32 = 0 + value i32 := 0 match value { 0: if ready() _ = value else: _ = value @@ -10986,7 +11090,7 @@ main func() void { @(test) parser_diagnoses_braceless_if_without_parens_or_call :: proc(t: ^testing.T) { text := `main func() void { - x i32 = 0 + x i32 := 0 if x == 0 x = 1 } ` @@ -11011,7 +11115,7 @@ parser_separates_contextual_enum_literal_from_if_block :: proc(t: ^testing.T) { other } main func() void { - kind Kind = .other + kind Kind := .other if kind != .newline { } } @@ -11061,7 +11165,7 @@ main func() i32 { parser_accepts_braceless_while_bodies :: proc(t: ^testing.T) { text := `ready func() bool { return false } main func() void { - cursor i32 = 0 + cursor i32 := 0 while (cursor < 1) cursor += 1 while ready() cursor += 1 } @@ -11094,8 +11198,8 @@ main func() void { @(test) parser_diagnoses_braceless_while_without_parens_or_call :: proc(t: ^testing.T) { text := `main func() void { - cursor i32 = 0 - limit i32 = 1 + cursor i32 := 0 + limit i32 := 1 while cursor < limit cursor += 1 } ` @@ -11123,7 +11227,7 @@ braceless_while_compiles_and_runs :: proc(t: ^testing.T) { main_path := "/tmp/brolang-test-braceless-while/main.bro" output := "/tmp/brolang-test-braceless-while-output" text := `main func() i32 { - cursor i32 = 0 + cursor i32 := 0 while (cursor < 42) cursor += 1 return cursor } @@ -11143,7 +11247,7 @@ braceless_while_compiles_and_runs :: proc(t: ^testing.T) { parser_diagnoses_braceless_for_and_unwrap_without_parens_or_call :: proc(t: ^testing.T) { text := `main func() void { for tokens.items |item| _ = item - value ?i32 = 1 + value ?i32 := 1 if value |present| _ = present } ` @@ -11169,10 +11273,10 @@ braceless_if_compiles_and_runs :: proc(t: ^testing.T) { output := "/tmp/brolang-test-braceless-if-output" text := `ready func() bool { return true } main func() i32 { - x i32 = 0 + x i32 := 0 if (x == 0) x = 1 else x = 2 if ready() x = x + 10 - y i32 = 5 + y i32 := 5 if (y == 0) y = 1 else y = 30 x = x + y return x @@ -11192,8 +11296,8 @@ main func() i32 { @(test) conditional_unwrap_allows_sink_captures :: proc(t: ^testing.T) { text := `main func() void { - first ?i32 = 1 - second ?i32 = 2 + first ?i32 := 1 + second ?i32 := 2 if first and second |_, value : value == 2| { _ = value } @@ -11228,22 +11332,22 @@ parser_diagnoses_malformed_conditional_unwrap_captures_and_guards :: proc(t: ^te needle: string, }{ {`main func() void { - value ?i32 = 1 + value ?i32 := 1 if value || {} } `, "expected an unwrap capture name"}, {`main func() void { - value ?i32 = 1 + value ?i32 := 1 if value |capture,| {} } `, "expected an unwrap capture after ','"}, {`main func() void { - value ?i32 = 1 + value ?i32 := 1 if value |capture :| {} } `, "expected a guard expression after ':'"}, {`main func() void { - value ?i32 = 1 + value ?i32 := 1 if value |capture {} } `, "expected '|' to close unwrap captures"}, @@ -11272,7 +11376,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 { - x i32 = 5 + x i32 := 5 if x |v| { return v } @@ -11301,9 +11405,9 @@ 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 { - first ?i32 = 1 - second ?i32 = 2 - plain i32 = 3 + first ?i32 := 1 + second ?i32 := 2 + plain i32 := 3 if first and second |one| {} if first |one, two| {} @@ -11316,7 +11420,7 @@ conditional_unwrap_diagnostics_cover_counts_guards_and_capture_scope :: proc(t: value = 2 } if first |value| { - value i32 = 2 + value i32 := 2 _ = value } if first |value| { @@ -11371,7 +11475,7 @@ conditional_unwrap_diagnostics_cover_counts_guards_and_capture_scope :: proc(t: 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 { - a ?i32 = 1 + a ?i32 := 1 if a |v| { return v } else { @@ -11401,7 +11505,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 { - a ?i32 = 1 + a ?i32 := 1 if a |v| { v = 2 return v @@ -11453,11 +11557,11 @@ bad_immutable func() void { bad_body_scope func() void { running :: false while running : i = 1 { - i u32 = 0 + i u32 := 0 } } bad_declaration_update func() void { - while false : i u32 = 0 {} + while false : i u32 := 0 {} } bad_missing_update func() void { while false : {} @@ -11546,9 +11650,9 @@ main func() void { @(test) while_loop_allocas_are_emitted_in_the_entry_block :: proc(t: ^testing.T) { text := `main func() i32 { - i u32 = 0 + i u32 := 0 while i < 2 and true : i = i + 1 { - value u32 = i + value u32 := i _ = value } return 0 @@ -11597,7 +11701,7 @@ for_loop_tokens_and_parser_capture_range_shape :: proc(t: ^testing.T) { for 0..4 |value| { _ = value } - items [1]mut i32 = [1] + items [1]mut i32 := [1] for (&items) |@item, index| { _ = item _ = index @@ -11728,7 +11832,7 @@ braceless_for_compiles_and_runs :: proc(t: ^testing.T) { output := "/tmp/brolang-test-braceless-for-output" text := `make_items func() [2]i32 { return [20, 2] } main func() i32 { - total i32 = 0 + total i32 := 0 items :: [10, 11] for (items) |item| total += item for make_items() |item| @@ -11876,7 +11980,7 @@ bad_duplicate_capture func() void { } bad_capture_redeclaration func() void { for [1] |item| { - item i32 = 2 + item i32 := 2 _ = item } } @@ -11898,8 +12002,8 @@ bad_scope func() void { _ = item } bad_integer_bounds func() void { - start i32 = 0 - end u32 = 1 + start i32 := 0 + end u32 := 1 for start..end |item| { _ = item } @@ -11972,16 +12076,16 @@ main func() void { @(test) for_pointer_capture_respects_pointer_and_array_mutability :: proc(t: ^testing.T) { text := `readonly func() void { - values [1]mut i32 = [1] - items @[1]mut i32 = &values + values [1]mut i32 := [1] + items @[1]mut i32 := &values items[0] = 7 for items |@item| { item^ = 7 } } writable func() void { - values [1]mut i32 = [1] - items @mut [1]mut i32 = &values + values [1]mut i32 := [1] + items @mut [1]mut i32 := &values items[0] = 7 for items |@item| { item^ = 7 @@ -12026,7 +12130,7 @@ writable func(point @mut Point) void { point.x += 1 } main func() i32 { - point Point = Point { x = 41 } + point Point := Point { x = 41 } writable(&point) bad_write(&point) return readonly(&point) @@ -12060,7 +12164,7 @@ equal_range_returns_infer_a_usable_result_type :: proc(t: ^testing.T) { return 2..3 } main func() i32 { - total i32 = 0 + total i32 := 0 for choose(false) |value| { total = total + value } @@ -12105,7 +12209,7 @@ make_array func() [2]i32 { return [1, 2] } main func() i32 { - total i32 = 0 + total i32 := 0 for make_range() |value| { total = total + value } @@ -12227,7 +12331,7 @@ division_parses_left_associatively :: proc(t: ^testing.T) { @(test) compound_assignment_preserves_operation_and_rhs :: proc(t: ^testing.T) { text := `main func() void { - x i32 = 0 + x i32 := 0 x += 5 } ` @@ -12255,7 +12359,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 { - value int = undefined + value int := undefined if flag { value = 42 } else { @@ -12310,7 +12414,7 @@ main func() i32 { @(test) local_int_inference_widens_from_assignments :: proc(t: ^testing.T) { text := `wide func() int { - value int = 1 + value int := 1 value = 1000 return value } @@ -12378,7 +12482,7 @@ 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 { - pi float = 3.14 + pi float := 3.14 return pi } main func() void { @@ -12409,7 +12513,7 @@ main func() void { @(test) float_constraint_accepts_integer_literal :: proc(t: ^testing.T) { text := `make func() float { - pi float = 3 + pi float := 3 return pi } main func() void { @@ -12466,7 +12570,7 @@ main func() void { @(test) float_constraint_widens_f32_to_f64 :: proc(t: ^testing.T) { text := `wide func(a f32, b f64) float { - x float = a + x float := a x = b return x } @@ -12498,7 +12602,7 @@ main func() void { @(test) int_constraint_rejects_float_initializer :: proc(t: ^testing.T) { text := `main func() void { - x int = 1.0 + x int := 1.0 } ` source_file := source.Source{path="test.bro", text=text} @@ -12525,7 +12629,7 @@ 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 { - x float = n + x float := n } main func() void { take(7) @@ -12651,7 +12755,7 @@ float_param_accepts_integer_literal_argument :: proc(t: ^testing.T) { return x } main func() void { - y f64 = take(3) + y f64 := take(3) _ = y } ` @@ -12681,9 +12785,9 @@ undefined_accepts_concrete_runtime_annotations :: proc(t: ^testing.T) { y i32 } main func() void { - point Point = undefined - pointer @i32 = undefined - maybe ?i32 = undefined + point Point := undefined + pointer @i32 := undefined + maybe ?i32 := undefined _ = point _ = pointer _ = maybe @@ -12724,10 +12828,10 @@ undefined_rejects_non_declaration_uses_and_unresolved_inference :: proc(t: ^test main func() void { immutable :: undefined typed_immutable int :: undefined - unresolved int = undefined - existing i32 = 1 + unresolved int := undefined + existing i32 := 1 existing = undefined - mismatch int = undefined + mismatch int := undefined mismatch = 1 mismatch = 1.0 } @@ -12766,12 +12870,12 @@ 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 := `index usize = 1 + text := `index usize := 1 bump func() usize { return index } main func() i32 { - values [3]mut i32 = [10, 20, 30] + values [3]mut i32 := [10, 20, 30] values[bump()] += 5 return 0 } @@ -12817,8 +12921,8 @@ compound_assignment_evaluates_nested_locations_once :: proc(t: ^testing.T) { text := `Box :: struct { value i32 } -row_index usize = 0 -column_index usize = 1 +row_index usize := 0 +column_index usize := 1 row func() usize { return row_index } @@ -12829,11 +12933,11 @@ pointer_for func(value @mut i32) @mut i32 { return value } main func() i32 { - matrix [2]mut [2]mut i32 = [[1, 2], [3, 4]] + matrix [2]mut [2]mut i32 := [[1, 2], [3, 4]] (matrix[row()])[column()] += 1 - boxes [2]mut Box = [Box { value = 5 }, Box { value = 6 }] + boxes [2]mut Box := [Box { value = 5 }, Box { value = 6 }] boxes[row()].value += 1 - value i32 = 7 + value i32 := 7 pointer_for(&value)^ += 1 return 0 } @@ -12892,10 +12996,10 @@ main func() i32 { @(test) compound_assignment_supports_pointer_add_only :: proc(t: ^testing.T) { valid_text := `main func() i32 { - values [3]mut i32 = [10, 20, 30] - pointer *mut i32 = (&values).ptr + values [3]mut i32 := [10, 20, 30] + pointer *mut i32 := (&values).ptr pointer += 1 - offset usize = 1 + offset usize := 1 pointer += offset return pointer^ } @@ -12927,8 +13031,8 @@ compound_assignment_supports_pointer_add_only :: proc(t: ^testing.T) { testing.expect_value(t, pointer_add_count, 2) invalid_text := `main func() void { - values [1]mut i32 = [10] - pointer *mut i32 = (&values).ptr + values [1]mut i32 := [10] + pointer *mut i32 := (&values).ptr pointer -= 1 } ` @@ -12957,17 +13061,17 @@ 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 { - signed i32 = 24 + signed i32 := 24 signed += 6 signed -= 2 signed *= 3 signed = divtrunc!(signed, 4) - unsigned u32 = 24 + unsigned u32 := 24 unsigned += 6 unsigned -= 2 unsigned *= 3 unsigned = divtrunc!(unsigned, 4) - real f64 = 24.0 + real f64 := 24.0 real += 6.0 real -= 2.0 real *= 3.0 @@ -13027,11 +13131,11 @@ 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 { - narrow i8 = 1 - wide i32 = 2 + narrow i8 := 1 + wide i32 := 2 narrow += wide - signed i32 = 3 - unsigned u32 = 4 + signed i32 := 3 + unsigned u32 := 4 signed += unsigned } ` @@ -13072,8 +13176,8 @@ compound_assignment_compiles_and_runs :: proc(t: ^testing.T) { @(test) binary_arithmetic_rejects_non_numeric_operands :: proc(t: ^testing.T) { text := `main func() i32 { - a i32 = 1 - b u32 = 2 + a i32 := 1 + b u32 := 2 _ = a + b return 0 } @@ -13127,9 +13231,9 @@ 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 { - a i32 = 10 - b i32 = 3 - c i32 = a - b + a i32 := 10 + b i32 := 3 + c i32 := a - b return divtrunc!(c, b) } ` @@ -13161,26 +13265,26 @@ integer_slash_is_rejected_and_float_slash_remains_available :: proc(t: ^testing. Case :: struct {text, want: string} invalid := []Case{ {text=`main func() void { - a i32 = 4 - b i32 = 2 + a i32 := 4 + b i32 := 2 _ = a / b }`, want="integer '/' is not allowed"}, {text=`main func() void { - a u32 = 4 - b u32 = 2 + a u32 := 4 + b u32 := 2 _ = a / b }`, want="integer '/' is not allowed"}, {text=`main func() void { _ = 4 / 2 }`, want="integer '/' is not allowed"}, {text=`main func() void { - values [4 / 2]u8 = undefined + values [4 / 2]u8 := undefined _ = &values }`, want="integer '/' is not allowed"}, {text=`half func($value i32) i32 { return value / 2 } main func() void { _ = $half(4) }`, want="integer '/' is not allowed"}, {text=`main func() void { - value i32 = 8 + value i32 := 8 value /= 2 }`, want="assign through an explicit division builtin"}, } @@ -13204,7 +13308,7 @@ main func() void { _ = $half(4) }`, want="integer '/' is not allowed"}, } text := `main func() void { - value f32 = 5.0 / 2.0 + value f32 := 5.0 / 2.0 value /= 2.0 _ = value } @@ -13481,20 +13585,20 @@ take func(value UserID) UserID { } main func() i32 { id UserID :: UserID(7) - copy UserID = take(id) - maybe ?UserID = copy - pointer @UserID = © + copy UserID := take(id) + maybe ?UserID := copy + pointer @UserID := © point PointID :: PointID(Point { x = 1, y = 2 }) bytes Bytes :: Bytes([3, 4]) wrapped WrappedID :: WrappedID(id) - sum UserID = id + 1 - matches bool = id == 7 - raw u32 = u32(id) - wide usize = usize(id) - real f64 = f64(id) - inner UserID = UserID(wrapped) - terminal u32 = u32(wrapped) - flag_matches bool = Flag(true) == Flag(true) + sum UserID := id + 1 + matches bool := id == 7 + raw u32 := u32(id) + wide usize := usize(id) + real f64 := f64(id) + inner UserID := UserID(wrapped) + terminal u32 := u32(wrapped) + flag_matches bool := Flag(true) == Flag(true) _ = maybe _ = pointer _ = point @@ -13583,13 +13687,13 @@ NO_ID :: maxval!(UserID) Data :: union { id UserID } Record :: struct { data Data = Data{ id = NO_ID } } main func() i32 { - small u8 = 7 - wide usize = 8 - a UserID = UserID(small) - b UserID = UserID(wide) - c UserID = UserID(OtherID(9)) + small u8 := 7 + wide usize := 8 + a UserID := UserID(small) + b UserID := UserID(wide) + c UserID := UserID(OtherID(9)) d UserID :: $UserID(usize(10)) - record Record = {} + record Record := {} _ = record if u32(a) != 7 or u32(b) != 8 or u32(c) != 9 or u32(d) != 10 { return 1 } return 0 @@ -13614,10 +13718,10 @@ BadOpaque :: distinct Opaque 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) - other OtherID = UserID(3) + raw u32 := 1 + id UserID := raw + backing u32 := UserID(2) + other OtherID := UserID(3) _ = UserID() _ = UserID(1, 2) left UserID :: UserID(5) @@ -13725,9 +13829,9 @@ identity c_func(value Nat) Nat { } variadic c_func(marker c_int, ...) c_int main func() i32 { - value Animal = .cat + value Animal := .cat values [2]Animal :: [.dog, Animal.bird] - number Nat = identity(.two) + number Nat := identity(.two) ordinal c_int :: c_int(number) _ = variadic(0, number) if take(value) == Animal.cat and values[0] != values[1] and number == Nat.two and ordinal == 2 { @@ -13812,12 +13916,12 @@ kind func(value bool) TokenKind { return TokenKind.else } main func() i32 { - first TokenKind = kind(true) - second TokenKind = .return - a Token = Token{ if = 1 } - b Token = Token{ else } - c Token = .return{2} - total i32 = a.if + c.return + first TokenKind := kind(true) + second TokenKind := .return + a Token := Token{ if = 1 } + b Token := Token{ else } + c Token := .return{2} + total i32 := a.if + c.return match first { .if: total = total + 1 .else: total = total + 2 @@ -13929,7 +14033,7 @@ Other :: enum { foreign c_func(value Dense) void allowed c_func(value Overflow) Overflow main func() void { - dense Dense = Other.value + dense Dense := Other.value _ = Dense.zero + Dense.one _ = Dense.zero < Dense.one _ = Dense.missing @@ -14405,7 +14509,7 @@ main func() void { contextual_inference_flows_through_compound_assignment :: proc(t: ^testing.T) { text := `main func() void { s :: 5 - v u16 = 0 + v u16 := 0 v += s _ = v } @@ -14436,7 +14540,7 @@ Z :: 40 STEP :: 5 main func() void { take_ci(W) - x int = W - Z + x int := W - Z take_ci(Z) x += STEP take_ci(x) @@ -14500,7 +14604,7 @@ contextual_inference_rejects_local_constant_that_does_not_fit :: proc(t: ^testin contextual_inference_flows_through_numeric_arithmetic :: proc(t: ^testing.T) { text := `take_u16 func(_ u16) void {} take_f32 func(_ f32) void {} -runtime_seed f32 = 0 +runtime_seed f32 := 0 G :: 10 H u16 :: G + 2 GF :: 1.5 @@ -14623,7 +14727,7 @@ missing_qualified_signature_symbol_reports_one_root_error :: proc(t: ^testing.T) token_text := `Token :: struct { start int } ` lexer_text := `scan func(cursor usize) void ! missing.Error { - token Token = Token{start = cursor} + token Token := Token{start = cursor} _ = token } ` @@ -14675,7 +14779,7 @@ poisoned_global_and_local_types_do_not_create_inference_fallbacks :: proc(t: ^te testing.expect(t, os.make_directory(directory) == nil) text := `bad missing.Global :: 1 main func() void { - value absent.Local = 1 + value absent.Local := 1 _ = value } ` @@ -14742,14 +14846,14 @@ Payload :: union { count int } take_usize func(value usize) usize { return value } exercise func(cursor usize, narrow i8, wider i16, count i32) i32 { - token Token = Token{start = cursor} - wide Wide = Wide{value = narrow} + token Token := Token{start = cursor} + wide Wide := Wide{value = narrow} wide.value = wider - small Literal = Literal{value = 1} - large Literal = Literal{value = 1000} - backward Backward = Backward{start = 1} - measurement Measurement = Measurement{ratio = 1.5, span = 0..3} - payload Payload = Payload{count = count} + small Literal := Literal{value = 1} + large Literal := Literal{value = 1000} + backward Backward := Backward{start = 1} + measurement Measurement := Measurement{ratio = 1.5, span = 0..3} + payload Payload := Payload{count = count} _ = token.start _ = wide.value _ = small.value @@ -14802,8 +14906,8 @@ native_record_int_field_compiles_and_runs_as_usize :: proc(t: ^testing.T) { output := "/tmp/brolang-test-record-field-usize-output" text := `Token :: struct { start int } main func() i32 { - cursor usize = 7 - token Token = Token{start = cursor} + cursor usize := 7 + token Token := Token{start = cursor} if (token.start != cursor) return 1 return 0 } @@ -14833,8 +14937,8 @@ main func() void {} { text = `Token :: struct { start int } use func(signed i32, unsigned usize) void { - a Token = Token{start = signed} - b Token = Token{start = unsigned} + a Token := Token{start = signed} + b Token := Token{start = unsigned} _ = a _ = b } @@ -14974,7 +15078,7 @@ Token :: struct { start int } OperationError :: enum { failed } scan func() void { - cursor usize = 0 + cursor usize := 0 _ = Token{start = cursor} } @@ -15071,10 +15175,10 @@ Byte uint :: 255 Word uint :: 256 Dword uint :: 65536 Maximum uint :: 18446744073709551615 -Counter uint = 1 +Counter uint := 1 widen func() uint { - value uint = 1 + value uint := 1 value = 1000 return value } @@ -15141,10 +15245,10 @@ main func() i32 { word_max uint :: 65535 dword uint :: 65536 maximum uint :: 18446744073709551615 - platform usize = 7 - c_value c_uint = c_uint(9) - box Box = make_box(7) - signed isize = -1 + platform usize := 7 + c_value c_uint := c_uint(9) + box Box := make_box(7) + signed isize := -1 if (identity(zero) != 0) return 1 if (identity(byte) != 255) return 2 if (identity(word) != 256) return 3 @@ -15182,7 +15286,7 @@ bad func(signed i32, decimal f64) void { _ = take(signed) _ = take(decimal) negative uint :: -1 - a Conflict = Conflict{value = signed} + a Conflict := Conflict{value = signed} _ = negative _ = a } @@ -15253,10 +15357,10 @@ read func(value Config) i32 { ANSWER :: $read(Config{required = 35}) main func() i32 { - defaults Config = Config{required = 35} - overridden Config = Config{count = 1, enabled = false, name = "x", required = 40} - lists Lists = Lists{} - generated Generated(i32, 9) = Generated(i32, 9){} + defaults Config := Config{required = 35} + overridden Config := Config{count = 1, enabled = false, name = "x", required = 40} + lists Lists := Lists{} + generated Generated(i32, 9) := Generated(i32, 9){} if (ANSWER != 42) return 1 if (defaults.count != 7 or defaults.enabled == false) return 2 if (defaults.name.len != 3 or lists.items.len != 0) return 3 @@ -15338,7 +15442,7 @@ put func( fallible func() void ! (PutError | dependency.AllocError) { return .key_exists } main func() void { - map StringMap(u32) = make() + map StringMap(u32) := make() put(&map, "key") _ = map fallible() catch |_| {} @@ -15430,16 +15534,16 @@ Direct :: alias struct_type!(.auto, {"x", "name"}, {i32, []u8}, {null, "bro"}) CPoint :: alias struct_type!(.c, {"x"}, {c_int}, {null}) ArrayInput :: alias struct_type!(.auto, ["value"], [i32], [7]) Empty :: alias struct_type!(.auto, {}, {}, {}) -direct_position struct_type!(.auto, {"value"}, {i32}, {null}) = {value = 5} +direct_position struct_type!(.auto, {"value"}, {i32}, {null}) := {value = 5} make_direct func() struct_type!(.auto, {"value"}, {i32}, {null}) { return {value = 6} } Generated func($T type) type { - names [1]mut []u8 = undefined - field_types [1]mut type = undefined - defaults [1]mut ?T = undefined + names [1]mut []u8 := undefined + field_types [1]mut type := undefined + defaults [1]mut ?T := undefined names[0] = "value" field_types[0] = T defaults[0] = 42 @@ -15447,7 +15551,7 @@ Generated func($T type) type { } GeneratedInt :: alias Generated(i32) -ordered Names = {} +ordered Names := {} static_none ?i32 :: null static_some ?i32 :: 1 none :: 41 @@ -15463,7 +15567,7 @@ Map func($E, $V type) type { } init func($E, $V type, values meta.EnumFieldStruct(E, ?V, some!(null))) Map(E, V) { - map Map(E, V) = undefined + map Map(E, V) := undefined match typeinfo!(E) { .enum |info|: inline for info.fields |field, index| { map.present[index] = false @@ -15490,7 +15594,7 @@ get func($E, $V type, map @Map(E, V), key E) ?V { } main func() i32 { - other Map(OtherTokenKind, []u8) = init(OtherTokenKind, []u8, {alpha = "other"}) + other Map(OtherTokenKind, []u8) := init(OtherTokenKind, []u8, {alpha = "other"}) if !other.present[0] { return 26 } _ = ordered if none != 41 { return 24 } @@ -15498,25 +15602,25 @@ main func() i32 { $(static_some == null) or $(null == static_some) { return 23 } inferred :: {x = 40, name = "bro"} if inferred.x != 40 or inferred.name.len != 3 { return 1 } - direct Direct = {x = 7} + direct Direct := {x = 7} if direct.x != 7 or direct.name.len != 3 { return 10 } - generated GeneratedInt = {} + generated GeneratedInt := {} if generated.value != 42 { return 11 } - generated_again Generated(i32) = generated + generated_again Generated(i32) := generated if generated_again.value != 42 { return 15 } - array_input ArrayInput = {} + array_input ArrayInput := {} if array_input.value != 7 { return 16 } - empty_record Empty = {} + empty_record Empty := {} _ = empty_record if direct_position.value != 5 or make_direct().value != 6 { return 17 } - c_point CPoint = {x = 9} + c_point CPoint := {x = 9} if c_point.x != 9 { return 12 } - nested ??i32 = some!(null) + nested ??i32 := some!(null) if nested |inner| { if inner |_| { return 13 } } else { return 14 } - names Names = { + names Names := { ident = "identifier", int = "integer", } @@ -15528,12 +15632,12 @@ main func() i32 { } else { return 5 } if field!(names, "eof") |_| { return 6 } - empty Names = {} + empty Names := {} if field!(empty, "ident") |_| { return 7 } - flags Flags = {second = true} + flags Flags := {second = true} if flags.first or !flags.second { return 8 } - map Map(TokenKind, []u8) = init({ + map Map(TokenKind, []u8) := init({ ident = "identifier", int = "integer", }) @@ -15546,7 +15650,7 @@ main func() i32 { } else { return 20 } eof :: get(&map, TokenKind.eof) if eof != null or null != eof { return 21 } - location testing.SourceLocation = {file = "test.bro", line = 1, column = 1} + location testing.SourceLocation := {file = "test.bro", line = 1, column = 1} testing.expect_equal(null, eof, location) catch |_| { return 24 } testing.expect_equal(ident, ident, location) catch |_| { return 25 } if eof |_| { return 22 } @@ -15713,8 +15817,8 @@ fallback :: static_string_map.init(TokenKind, [ {"while", .keyword_while}, ]) empty std.StaticStringMap(TokenKind) :: static_string_map.init([]) -numbers []i32 = ${ - values [3]mut i32 = [7, 8, 9] +numbers []i32 := ${ + values [3]mut i32 := [7, 8, 9] yield values[..] } @@ -15769,7 +15873,7 @@ static_string_map_reports_duplicate_and_malformed_entries :: proc(t: ^testing.T) duplicate_text := `std :: import "@std" static_string_map :: import "@std/static_string_map" TokenKind :: enum { keyword_if, keyword_else } -bad std.StaticStringMap(TokenKind) = static_string_map.init([ +bad std.StaticStringMap(TokenKind) := static_string_map.init([ {"if", .keyword_if}, {"if", .keyword_else}, ]) @@ -15798,10 +15902,10 @@ main func() void {} malformed_text := `std :: import "@std" static_string_map :: import "@std/static_string_map" TokenKind :: enum { keyword_if } -bad std.StaticStringMap(TokenKind) = static_string_map.init([ +bad std.StaticStringMap(TokenKind) := static_string_map.init([ {123, .keyword_if}, ]) -bad_value std.StaticStringMap(TokenKind) = static_string_map.init([ +bad_value std.StaticStringMap(TokenKind) := static_string_map.init([ {"if", "bad"}, ]) main func() void {} @@ -15859,7 +15963,7 @@ reflects_bottom func($T type) bool { } main func() i32 { - callback @func() noreturn = forward + callback @func() noreturn := forward _ = callback if choose(true) != 42 { return 1 } if !reflects_bottom(noreturn) { return 2 } @@ -15931,7 +16035,7 @@ fallthrough func() noreturn {} parameter func(value noreturn) void { _ = value } main func() void { if false { fallthrough() } - stored noreturn = unreachable + stored noreturn := unreachable } ` source_file := source.Source{path="invalid_noreturn.bro", text=text} @@ -15976,21 +16080,21 @@ DuplicateNames :: alias struct_type!(.auto, {"same", "same"}, {i32, i32}, {null, BadLayout :: alias struct_type!(.packed, {"value"}, {i32}, {null}) BadC :: alias struct_type!(.c, {"value"}, {[]u8}, {null}) EmptyC :: alias struct_type!(.c, {}, {}, {}) -unknown Fields = {missing = 1} -duplicate Fields = {value = 1, value = 2} -missing Fields = {} -missing_enum RequiredEnum = {} -not_enum NotEnum = {} -bad_field BadField = {} -bad_comptime_field BadComptimeField = {} -bad_default BadDefault = {} -unstable_default UnstableDefault = {} -bad_lengths BadLengths = {} -bad_names BadNames = {} -duplicate_names DuplicateNames = {} -bad_layout BadLayout = {} -bad_c BadC = {} -empty_c EmptyC = {} +unknown Fields := {missing = 1} +duplicate Fields := {value = 1, value = 2} +missing Fields := {} +missing_enum RequiredEnum := {} +not_enum NotEnum := {} +bad_field BadField := {} +bad_comptime_field BadComptimeField := {} +bad_default BadDefault := {} +unstable_default UnstableDefault := {} +bad_lengths BadLengths := {} +bad_names BadNames := {} +duplicate_names DuplicateNames := {} +bad_layout BadLayout := {} +bad_c BadC := {} +empty_c EmptyC := {} main func() void { _ = some!(1) _ = unknown @@ -16094,8 +16198,8 @@ put func( } main func() i32 { - box StringBox(u32) = {value = 0} - key []mut u8 = undefined + box StringBox(u32) := {value = 0} + key []mut u8 := undefined put(&box, key, 42) return 0 } diff --git a/examples/build/raylib/source/main.bro b/examples/build/raylib/source/main.bro index c2ec6a1..6e7e700 100644 --- a/examples/build/raylib/source/main.bro +++ b/examples/build/raylib/source/main.bro @@ -79,8 +79,8 @@ read_command func() Command { if rl.IsMouseButtonPressed(rl.MOUSE_BUTTON_LEFT) return .spawn{ rl.GetMousePosition() } if rl.IsKeyPressed(rl.KEY_SPACE) return .clear - fx f32 = 0.0 - fy f32 = 0.0 + fx f32 := 0.0 + fy f32 := 0.0 if rl.IsKeyDown(rl.KEY_A) fx -= FORCE if rl.IsKeyDown(rl.KEY_D) fx += FORCE if rl.IsKeyDown(rl.KEY_W) fy -= FORCE @@ -130,14 +130,14 @@ step func(b @mut Ball) void { draw_ball func(b @Ball, highlight bool) void { col :: color_for(b.kind) - center rl.Vector2 = rl.Vector2{ x = b.x, y = b.y } + center rl.Vector2 := rl.Vector2{ x = b.x, y = b.y } match b.kind { .circle: rl.DrawCircleV(center, b.radius, col) .square: rl.DrawPoly(center, 4, b.radius, 45.0, col) .triangle: rl.DrawPoly(center, 3, b.radius, 0.0, col) } if highlight { - ring rl.Color = rl.Color{ r = 250, g = 245, b = 200, a = 255 } + ring rl.Color := rl.Color{ r = 250, g = 245, b = 200, a = 255 } rl.DrawPoly(center, 24, b.radius + RING_PAD, 0.0, ring) } } @@ -152,11 +152,11 @@ main func() i32 { `[click] spawn a shape [WASD/arrows] blow wind `[space] clear - balls [CAP]mut Ball = undefined - count usize = 0 # number of live balls, in slots 0..count - kc Kind = .circle # next kind to spawn - spin f32 = 1.0 # rotates spawn velocity for variety - at_cap bool = false # show the "at capacity" banner + balls [CAP]mut Ball := undefined + count usize := 0 # number of live balls, in slots 0..count + kc Kind := .circle # next kind to spawn + spin f32 := 1.0 # rotates spawn velocity for variety + at_cap bool := false # show the "at capacity" banner bg :: rl.Color{ r = 24, g = 26, b = 34, a = 255 } text :: rl.Color{ r = 225, g = 225, b = 230, a = 255 } @@ -211,7 +211,7 @@ main func() i32 { # --- which shape is under the cursor? (optional via a value-loop) --- mouse :: rl.GetMousePosition() sel :: for 0..(count) |i| hover: { - c rl.Vector2 = rl.Vector2{ x = balls[i].x, y = balls[i].y } + c rl.Vector2 := rl.Vector2{ x = balls[i].x, y = balls[i].y } if rl.CheckCollisionPointCircle(mouse, c, balls[i].radius) yield :hover i yield null } @@ -222,7 +222,7 @@ main func() i32 { for (&balls) |@b, i| { if (i >= count) break - hot bool = false + hot bool := false if sel |s| { if (s == i) hot = true # true only for the hovered ball } diff --git a/examples/interop/records/app/main.bro b/examples/interop/records/app/main.bro index 7eccd96..7177a63 100644 --- a/examples/interop/records/app/main.bro +++ b/examples/interop/records/app/main.bro @@ -19,7 +19,7 @@ native_pair func(value native.Pair) native.Pair { global_pair native.Pair :: native.Pair { left = 1, right = 2 } main func() i32 { - pair native.Pair = native_pair(global_pair) + pair native.Pair := native_pair(global_pair) pair.left = 10 pair = native.echo_pair(pair) pairs [1]native.Pair :: [pair] @@ -33,7 +33,7 @@ main func() i32 { tail = 13, }) arrays native.Arrays :: native.echo_arrays(native.Arrays { values = [14, 15, 16] }) - choice native.Choice = native.Choice { decimal = 1.0 } + choice native.Choice := native.Choice { decimal = 1.0 } choice.integer = 17 choice = native.echo_choice(choice) forward native.Forward :: native.echo_forward(native.Forward { value = 19 }) diff --git a/examples/interop/recursive/app/main.bro b/examples/interop/recursive/app/main.bro index 4fce9ff..0c0c7bb 100644 --- a/examples/interop/recursive/app/main.bro +++ b/examples/interop/recursive/app/main.bro @@ -5,7 +5,7 @@ native :: import "../include/native.h" # self-referential `?*mut Node` field as C-layout-compatible. main func() i32 { - node native.Node = native.Node { next = null, value = 7 } + node native.Node := native.Node { next = null, value = 7 } if node.next |_| { return 1 } diff --git a/examples/packages/hidden_valid/app/a.bro b/examples/packages/hidden_valid/app/a.bro index cdeeda2..0ed8f57 100644 --- a/examples/packages/hidden_valid/app/a.bro +++ b/examples/packages/hidden_valid/app/a.bro @@ -1,5 +1,5 @@ hide helper func() i32 { - thing Thing = Thing { value = value } + thing Thing := Thing { value = value } return thing.value } @@ -20,7 +20,7 @@ hide Local_Distinct :: distinct i32 hide Local_Alias :: alias i32 hide value :: 1 -hide mutable_value i32 = 1 +hide mutable_value i32 := 1 _foreign c_func() i32 { return 1 @@ -39,6 +39,6 @@ hide Local_C_Record :: c_struct { } from_a func() i32 { - record Local_C_Record = Local_C_Record { value = 0 } + record Local_C_Record := Local_C_Record { value = 0 } return helper() + local_foreign() + i32(record.value) } diff --git a/examples/packages/hidden_valid/app/b.bro b/examples/packages/hidden_valid/app/b.bro index e3ab4e9..d88239f 100644 --- a/examples/packages/hidden_valid/app/b.bro +++ b/examples/packages/hidden_valid/app/b.bro @@ -6,8 +6,8 @@ Box :: struct { } from_b func(_input i32) i32 { - _local Box = Box { _value = _input } - record _C_Record = _C_Record { value = 0 } - thing Thing = Thing { value = value } + _local Box := Box { _value = _input } + record _C_Record := _C_Record { value = 0 } + thing Thing := Thing { value = value } return helper() + thing.value + _local._value + _foreign() + i32(record.value) + dep._visible() } diff --git a/examples/packages/problematic_unused/broken/broken.bro b/examples/packages/problematic_unused/broken/broken.bro index 9b98e7f..35b3b8b 100644 --- a/examples/packages/problematic_unused/broken/broken.bro +++ b/examples/packages/problematic_unused/broken/broken.bro @@ -1 +1 @@ -bad = 1 +bad := undefined diff --git a/examples/programs/array_const_size_error/main.bro b/examples/programs/array_const_size_error/main.bro index d8be2b4..45d712b 100644 --- a/examples/programs/array_const_size_error/main.bro +++ b/examples/programs/array_const_size_error/main.bro @@ -1,5 +1,5 @@ main func() i32 { - n usize = 4 - items [n]mut i32 = undefined + n usize := 4 + items [n]mut i32 := undefined return 0 } diff --git a/examples/programs/arraylist/main.bro b/examples/programs/arraylist/main.bro index ce074d3..098decf 100644 --- a/examples/programs/arraylist/main.bro +++ b/examples/programs/arraylist/main.bro @@ -10,7 +10,7 @@ State :: struct { diagnostics std.ArrayList(ScanDiagnostic) } -arrlist_test std.ArrayList(Token) = arraylist.init(mem.c_allocator) +arrlist_test std.ArrayList(Token) := arraylist.init(mem.c_allocator) init func(allocator mem.Allocator) State { return State { @@ -44,11 +44,11 @@ run func() i32 ! mem.AllocError { state State :: init(mem.c_allocator) _ = state - values std.ArrayList(i32) = arraylist.init(mem.c_allocator) + values std.ArrayList(i32) := arraylist.init(mem.c_allocator) defer arraylist.deinit(&values) if (values.items.len != 0 or values.capacity != 0) return 1 - i usize = 0 + i usize := 0 while i < 20 : i += 1 { arraylist.append(&values, i32(i)) catch |_| { return .out_of_memory @@ -71,7 +71,7 @@ run func() i32 ! mem.AllocError { } if (values.items.len != 1 or values.items[0] != 7 or values.capacity != capacity) return 7 - empty_values arraylist.ArrayList([0]u8) = arraylist.init(mem.c_allocator) + empty_values arraylist.ArrayList([0]u8) := arraylist.init(mem.c_allocator) defer arraylist.deinit(&empty_values) zero [0]u8 :: [] arraylist.append(&empty_values, zero) catch |_| { @@ -79,8 +79,8 @@ run func() i32 ! mem.AllocError { } if (empty_values.items.len != 1) return 8 - failed arraylist.ArrayList(i32) = arraylist.init(i32, fail_allocator) - failed_as_expected bool = false + failed arraylist.ArrayList(i32) := arraylist.init(i32, fail_allocator) + failed_as_expected bool := false arraylist.append(&failed, 1) catch |_| { failed_as_expected = true } diff --git a/examples/programs/bitwise/main.bro b/examples/programs/bitwise/main.bro index cc7a274..4ced4e8 100644 --- a/examples/programs/bitwise/main.bro +++ b/examples/programs/bitwise/main.bro @@ -18,7 +18,7 @@ c_count_shift func(value u8, count c_uint) u8 { c_count_fold u8 :: c_count_shift(3, 2) main func() i32 { - buffer Buffer = undefined + buffer Buffer := undefined if (folded != 0) return 1 if (contextual != 255) return 28 if (contextual_shift != 128) return 29 @@ -50,7 +50,7 @@ main func() i32 { if ((c_ushort(240) xor c_ushort(255)) != 15) return 26 if ((c_longlong(64) <<| 60) != maxval!(c_longlong)) return 27 - value u8 = 3 + value u8 := 3 value <<= 2 value |= 1 value xor= 5 diff --git a/examples/programs/break_continue/main.bro b/examples/programs/break_continue/main.bro index 6d913e6..a12e560 100644 --- a/examples/programs/break_continue/main.bro +++ b/examples/programs/break_continue/main.bro @@ -7,8 +7,8 @@ main func() i32 { # 1. `break` out of a `while` once i reaches 5. - i i32 = 0 - a i32 = 0 + i i32 := 0 + a i32 := 0 while i < 100 : i += 1 { if (i == 5) break a += 1 @@ -16,7 +16,7 @@ main func() i32 { if (a != 5) return 101 # 2. `continue` past n == 3 while summing 0..9 (45 - 3 = 42). - b i32 = 0 + b i32 := 0 for 0..10 |n| { if (n == 3) continue b = b + n @@ -25,7 +25,7 @@ main func() i32 { # 3. Nested loops: the inner `break` exits only the inner loop, so the outer # loop still runs all three iterations (each contributing one y == 0 pass). - c i32 = 0 + c i32 := 0 for 0..3 |x| { for 0..3 |y| { if (y == 1) break @@ -38,7 +38,7 @@ main func() i32 { # 4. `continue` on the final element of an inclusive range bounded by the # element type's maximum must exit cleanly, not overflow the increment. hi u8 :: 255 - d i32 = 0 + d i32 := 0 for 0..=hi |v| { if (v == 255) continue d += 1 @@ -47,7 +47,7 @@ main func() i32 { # 5. `while true` is exitable via `break` (so it is not an infinite loop and # the code after it is reachable). - e i32 = 0 + e i32 := 0 while true { e += 1 if (e == 7) break diff --git a/examples/programs/compound_assignment/main.bro b/examples/programs/compound_assignment/main.bro index 0d0ef8a..25cd229 100644 --- a/examples/programs/compound_assignment/main.bro +++ b/examples/programs/compound_assignment/main.bro @@ -1,7 +1,7 @@ # Compound assignment (`+=`, `-=`, `*=`, `/=`) and explicit integer division. check_float func() i32 { - x f64 = 10.0 + x f64 := 10.0 x /= 4.0 # 2.5 x *= 2.0 # 5.0 x -= 1.0 # 4.0 @@ -13,7 +13,7 @@ check_float func() i32 { } check_unsigned func() i32 { - n u32 = 100 + n u32 := 100 n = divtrunc!(n, 7) # 14 n -= 4 # 10 if n == 10 { @@ -23,7 +23,7 @@ check_unsigned func() i32 { } main func() i32 { - total i32 = 0 + total i32 := 0 total += 10 # 10 total -= 3 # 7 total *= 4 # 28 @@ -33,7 +33,7 @@ main func() i32 { total = total + 2 * 3 - 4 # compound assignment as a while-loop update - i i32 = 0 + i i32 := 0 while i < 5 : i += 1 { total += 1 # +5 => 21 } diff --git a/examples/programs/comptime_eval/main.bro b/examples/programs/comptime_eval/main.bro index d569630..e496ac6 100644 --- a/examples/programs/comptime_eval/main.bro +++ b/examples/programs/comptime_eval/main.bro @@ -15,7 +15,7 @@ nested func(value int) int { } make_array func($N usize) [N]u8 { - data [N]u8 = undefined + data [N]u8 := undefined return data } diff --git a/examples/programs/comptime_type_params/main.bro b/examples/programs/comptime_type_params/main.bro index 4899e83..088c9fe 100644 --- a/examples/programs/comptime_type_params/main.bro +++ b/examples/programs/comptime_type_params/main.bro @@ -14,13 +14,13 @@ id func($T type, value T) T { } buffer func($T type, $N usize, value T) [N]T { - data [N]T = undefined + data [N]T := undefined _ = value return data } zero func($T type) T { - value T = undefined + value T := undefined return value } @@ -86,12 +86,12 @@ main func() i32 { if fixed_len(&fixed) != 3 { return 7 } - assigned i32 = 1 + assigned i32 := 1 assigned = zero() _ = assigned _ = take_i32(zero()) _ = return_zero() - optional ?u32 = null + optional ?u32 := null if !same_type(?u32, optional) { return 8 } diff --git a/examples/programs/comptime_v1/main.bro b/examples/programs/comptime_v1/main.bro index a512b2f..1ae2b58 100644 --- a/examples/programs/comptime_v1/main.bro +++ b/examples/programs/comptime_v1/main.bro @@ -32,8 +32,8 @@ make_point func() Point { } sum_loop func(limit i32) i32 { - total i32 = 0 - i i32 = 0 + total i32 := 0 + i i32 := 0 while i < limit { i += 1 if i == 2 { @@ -45,8 +45,8 @@ sum_loop func(limit i32) i32 { } sum_for func() i32 { - total i32 = 0 - values [_]i32 = [1, 2, 3] + total i32 := 0 + values [_]i32 := [1, 2, 3] for values |value, index| { total += value + index } @@ -54,7 +54,7 @@ sum_for func() i32 { } defer_value func() i32 { - value i32 = 1 + value i32 := 1 { defer value += 10 value += 1 @@ -140,7 +140,7 @@ use_try func() i32 ! Error { } ct_errdefer func(fail bool) i32 ! Error { - trace i32 = 0 + trace i32 := 0 defer trace = trace * 10 + 1 errdefer |err| { if (err == .bad) trace = trace * 10 + 2 @@ -151,7 +151,7 @@ ct_errdefer func(fail bool) i32 ! Error { } ct_try_errdefer func() i32 ! Error { - trace i32 = 0 + trace i32 := 0 defer trace = trace * 10 + 4 errdefer |err| { if (err == .bad) trace = trace * 10 + 5 @@ -185,20 +185,20 @@ alias_add func(left @mut i32, right @mut i32) void { } storage_mutation func() i32 { - values [3]mut i32 = [1, 2, 3] + values [3]mut i32 := [1, 2, 3] values[0] += 1 bump_ptr(&values[1]) - view []mut i32 = values[..] + view []mut i32 := values[..] for view |@item| { item^ += 1 } - pointer *mut i32 = view.ptr + pointer *mut i32 := view.ptr pointer[2] += 1 alias_add(&values[0], &view[0]) - box Box = Box { point = Point { x = 2, y = 3 } } + box Box := Box { point = Point { x = 2, y = 3 } } match box { .point |@p|: p.x += values[1] .empty: values[0] = values[0] diff --git a/examples/programs/comptime_value_params/main.bro b/examples/programs/comptime_value_params/main.bro index d9f133b..bd56348 100644 --- a/examples/programs/comptime_value_params/main.bro +++ b/examples/programs/comptime_value_params/main.bro @@ -1,5 +1,5 @@ make_array func($N usize) [N]u8 { - data [N]u8 = undefined + data [N]u8 := undefined return data } diff --git a/examples/programs/conditional_unwrap/main.bro b/examples/programs/conditional_unwrap/main.bro index 4ba3c78..5b1aabf 100644 --- a/examples/programs/conditional_unwrap/main.bro +++ b/examples/programs/conditional_unwrap/main.bro @@ -6,10 +6,10 @@ observe func(counter @mut i32, value ?i32) ?i32 { } main func() i32 { - total i32 = 0 + total i32 := 0 # present optional scalar -> binds v to the unwrapped value - a ?i32 = 40 + a ?i32 := 40 if a |v| { total = total + v # 40 } else { @@ -17,7 +17,7 @@ main func() i32 { } # null -> else branch taken; the binding is not in scope there - b ?i32 = null + b ?i32 := null if b |v| { total = total + v } else { @@ -25,20 +25,20 @@ main func() i32 { } # optional pointer present -> binds q to a non-null @i32; deref proves it - n i32 = 0 - p ?@i32 = &n + n i32 := 0 + p ?@i32 := &n if p |q| { total = total + q^ # +0 } # optional pointer null -> skipped - z ?@i32 = null + z ?@i32 := null if z |_| { total = total + 1000 } # guarded multi-unwrap exposes every capture to the guard and then-block - age ?i32 = 2 + age ?i32 := 2 if a and age |value, years : value + years == 42| { total = total } else { @@ -46,7 +46,7 @@ main func() i32 { } # parenthesized chains and three-value unwraps are equivalent - bonus ?i32 = 0 + bonus ?i32 := 0 if (a and age and bonus) |value, years, extra : value + years + extra == 42| { total = total } else { @@ -64,7 +64,7 @@ main func() i32 { } # a failed unwrap prevents later expressions from being evaluated - calls i32 = 0 + calls i32 := 0 if b and observe(&calls, age) |missing, observed| { total = total + missing + observed } diff --git a/examples/programs/control_flow/main.bro b/examples/programs/control_flow/main.bro index 77bbba4..d2b4482 100644 --- a/examples/programs/control_flow/main.bro +++ b/examples/programs/control_flow/main.bro @@ -23,7 +23,7 @@ noisy func() bool { } main func() i32 { - total i32 = 0 + total i32 := 0 # comparisons drive if / else if / else total = total + classify(-5) # 1 @@ -45,9 +45,9 @@ main func() i32 { } # block scoping: inner bindings do not escape the block - x i32 = 1 + x i32 := 1 if x == 1 { - inner_x i32 = 100 + inner_x i32 := 100 if inner_x == 100 { total = total + 5 # 40 } diff --git a/examples/programs/defer/main.bro b/examples/programs/defer/main.bro index ae1d042..241dd40 100644 --- a/examples/programs/defer/main.bro +++ b/examples/programs/defer/main.bro @@ -7,7 +7,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 { - x i32 = 5 + x i32 := 5 defer x = 999 return x } @@ -15,7 +15,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 { - v i32 = 0 + v i32 := 0 defer v = v + 100 for 0..3 |i| { defer v = v + 1 @@ -89,7 +89,7 @@ main func() i32 { if (spill_check() != 5) return 101 # 2. LIFO ordering, run at end of each loop iteration. - r i32 = 0 + r i32 := 0 for 0..1 |i| { defer r = r * 2 + 1 # registered first -> runs last defer r = r * 2 # registered second -> runs first @@ -99,16 +99,16 @@ main func() i32 { # 3. scoped bare block + scoped defer (defer fires at the closing brace, and # the block-local is not visible afterwards). - a i32 = 1 + a i32 := 1 { defer a = 4 - c i32 = 3 + c i32 := 3 _ = c } if (a != 4) return 103 # 4. `defer { ... }` block: all its statements run (in order) at scope close. - s i32 = 0 + s i32 := 0 { defer { s = s + 1 @@ -119,7 +119,7 @@ main func() i32 { if (s != 60) return 104 # 5 -> 6 -> 60 # 5. `break` flushes the loop-body defer. - bc i32 = 0 + bc i32 := 0 for 0..5 |i| { defer bc = bc + 1 if (i == 2) break @@ -127,7 +127,7 @@ main func() i32 { if (bc != 3) return 105 # i=0,1 fall-through + i=2 break # 6. `continue` flushes the loop-body defer. - cc i32 = 0 + cc i32 := 0 for 0..3 |i| { defer cc = cc + 1 if (i == 1) continue @@ -139,7 +139,7 @@ main func() i32 { if (enclosing_defer_check() != 2) return 107 # 8. errdefer is skipped on success; ordinary defers stay interleaved. - trace i32 = 0 + trace i32 := 0 if ((explicit_cleanup(false, &trace) catch 0) != 7 or trace != 31) return 108 # 9. Explicit errors run errdefer and expose the captured error. diff --git a/examples/programs/distinct_types/main.bro b/examples/programs/distinct_types/main.bro index 0eceb2c..4707213 100644 --- a/examples/programs/distinct_types/main.bro +++ b/examples/programs/distinct_types/main.bro @@ -24,9 +24,9 @@ take func(value LocalID) LocalID { main func() i32 { id LocalID :: LocalID(7) - copy LocalID = take(id) - maybe ?LocalID = copy - pointer @LocalID = © + copy LocalID := take(id) + maybe ?LocalID := copy + pointer @LocalID := © point PointID :: PointID(Point { x = 1, y = 2 }) bytes Bytes :: Bytes([3, 4]) wrapped WrappedID :: WrappedID(id) @@ -64,15 +64,15 @@ main func() i32 { return 8 } - arithmetic Signed = Signed(4) + arithmetic Signed := Signed(4) arithmetic += 3 arithmetic -= 2 arithmetic *= 5 - fraction Real = Real(3.0) + fraction Real := Real(3.0) fraction /= 2.0 if arithmetic != 25 or fraction != 1.5 { return 9 } - bits Mask = Mask(3) + bits Mask := Mask(3) bits |= 8 bits xor= 2 bits &= 9 @@ -81,18 +81,18 @@ main func() i32 { bits <<|= u8(5) if bits != 255 { return 10 } - values [10]u8 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] + values [10]u8 := [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] if values[LocalID(4)] != 4 { return 11 } - section []u8 = values[LocalID(2)..LocalID(5)] + section []u8 := values[LocalID(2)..LocalID(5)] if section.len != 3 or section[usize(0)] != 2 or section[usize(2)] != 4 { return 12 } if u32(id) != 7 or usize(id) != 7 or f64(id) != 7.0 { return 13 } - extracted LocalID = LocalID(wrapped) + extracted LocalID := LocalID(wrapped) if extracted != id { return 14 } - minimum Signed = minval!(Signed) - maximum Mask = maxval!(Mask) - nested_max WrappedID = maxval!(WrappedID) + minimum Signed := minval!(Signed) + maximum Mask := maxval!(Mask) + nested_max WrappedID := maxval!(WrappedID) if i32(minimum) != minval!(i32) or u8(maximum) != 255 or u32(nested_max) != maxval!(u32) { return 15 } diff --git a/examples/programs/enums/main.bro b/examples/programs/enums/main.bro index 28e82d8..e70dd07 100644 --- a/examples/programs/enums/main.bro +++ b/examples/programs/enums/main.bro @@ -17,7 +17,7 @@ identity c_func(value State) State { } main func() i32 { - state State = identity(.running) + state State := identity(.running) values [2]State :: [.started, State.stopped] animal animals.Animal :: animals.Animal.dog if same(state, .running) and diff --git a/examples/programs/errors/main.bro b/examples/programs/errors/main.bro index dde83df..ac869c0 100644 --- a/examples/programs/errors/main.bro +++ b/examples/programs/errors/main.bro @@ -125,7 +125,7 @@ inline_detail func(value i32) i32 ! union(enum) { } main func() i32 { - acc i32 = 0 + acc i32 := 0 a :: maybe(0) catch 7 b :: maybe(4) catch 99 @@ -166,11 +166,11 @@ main func() i32 { acc = acc + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p acc = acc + pick(.left) - r Right = .right + r Right := .right acc = acc + pick(r) - box BoxA = .a{8} + box BoxA := .a{8} acc = acc + payload(box) - empty BoxB = .b + empty BoxB := .b acc = acc + payload(empty) acc = acc + payload(.a{9}) diff --git a/examples/programs/for_loop/main.bro b/examples/programs/for_loop/main.bro index 989a515..907aa27 100644 --- a/examples/programs/for_loop/main.bro +++ b/examples/programs/for_loop/main.bro @@ -5,9 +5,9 @@ pass func(value range) range { } main func() i32 { - total i32 = 0 + total i32 := 0 - items [3]mut i32 = [1, 2, 3] + items [3]mut i32 := [1, 2, 3] for items |item, index| { total = total + item _ = index @@ -17,7 +17,7 @@ main func() i32 { item^ = item^ + 1 } - view []mut i32 = items[..] + view []mut i32 := items[..] for view |@item, index| { item^ = item^ + 1 _ = index diff --git a/examples/programs/for_loop_edges/main.bro b/examples/programs/for_loop_edges/main.bro index 5ad5717..987f7d7 100644 --- a/examples/programs/for_loop_edges/main.bro +++ b/examples/programs/for_loop_edges/main.bro @@ -6,23 +6,23 @@ make_range func(calls @mut i32, end usize) range { global_range :: 0..1 main func() i32 { - total i32 = 0 + total i32 := 0 - first u8 = 254 - last u8 = 255 + first u8 := 254 + last u8 := 255 for first..=last |value| { _ = value total = total + 1 } - signed_start i8 = -2 - signed_end i8 = 1 + signed_start i8 := -2 + signed_end i8 := 1 for signed_start..signed_end |value| { _ = value total = total + 1 } - limit usize = 3 + limit usize := 3 for 0..(limit + 1) |value| { _ = value total = total + 1 @@ -41,19 +41,19 @@ main func() i32 { total = total + 100 } - empty [0]i32 = [] + empty [0]i32 := [] for empty |value| { _ = value total = total + 100 } - pointed i32 = 3 - pointers [1]@mut i32 = [&pointed] + pointed i32 := 3 + pointers [1]@mut i32 := [&pointed] for pointers |pointer| { total = total + pointer^ } - calls i32 = 0 + calls i32 := 0 for make_range(&calls, 2) |value| { _ = value total = total + 1 diff --git a/examples/programs/index_int_constraint_error/main.bro b/examples/programs/index_int_constraint_error/main.bro index 50324a9..156191e 100644 --- a/examples/programs/index_int_constraint_error/main.bro +++ b/examples/programs/index_int_constraint_error/main.bro @@ -1,6 +1,6 @@ main func() i32 { - items [3]mut i32 = undefined - i int = 1 + items [3]mut i32 := undefined + i int := 1 items[i] = 42 return 0 } diff --git a/examples/programs/index_signed_error/main.bro b/examples/programs/index_signed_error/main.bro index 290d241..43addea 100644 --- a/examples/programs/index_signed_error/main.bro +++ b/examples/programs/index_signed_error/main.bro @@ -1,6 +1,6 @@ main func() i32 { - items [3]mut i32 = undefined - i i32 = 1 + items [3]mut i32 := undefined + i i32 := 1 items[i] = 42 return 0 } diff --git a/examples/programs/inline/main.bro b/examples/programs/inline/main.bro index be2725f..ace058e 100644 --- a/examples/programs/inline/main.bro +++ b/examples/programs/inline/main.bro @@ -68,8 +68,8 @@ main func() i32 { return 2 } - a Value = .number{41} - b Value = .number{41} + a Value := .number{41} + b Value := .number{41} if !equal_value(a, b) or equal_value(a, .pair{left = 41, right = 0}) { return 3 } @@ -78,8 +78,8 @@ main func() i32 { return 4 } - pair_a Value = .pair{left = 2, right = 3} - pair_b Value = .pair{left = 2, right = 3} + pair_a Value := .pair{left = 2, right = 3} + pair_b Value := .pair{left = 2, right = 3} if !equal_value(pair_a, pair_b) or !equal_value(.empty, .empty) { return 5 } @@ -88,7 +88,7 @@ main func() i32 { return 6 } - empty Value = .empty + empty Value := .empty increment(&empty) return 0 } diff --git a/examples/programs/invalid_transitive_used_global/main.bro b/examples/programs/invalid_transitive_used_global/main.bro index 8732ee6..c814dbf 100644 --- a/examples/programs/invalid_transitive_used_global/main.bro +++ b/examples/programs/invalid_transitive_used_global/main.bro @@ -1,4 +1,4 @@ -bad int = 4 +bad int := 4 read_bad func() int { return bad diff --git a/examples/programs/io/main.bro b/examples/programs/io/main.bro index a8b0b25..5e3ac35 100644 --- a/examples/programs/io/main.bro +++ b/examples/programs/io/main.bro @@ -85,7 +85,7 @@ bad_writer func() io.Writer { } rejects_bad_read func() bool { - buffer [1]mut u8 = [0] + buffer [1]mut u8 := [0] _ = io.read(bad_reader(), buffer[..]) catch |err| { return err == .read_failed } @@ -108,7 +108,7 @@ rejects_bad_write func() bool { main func(init process.Init) i32 { system io.Io :: init.io - buffer [2]mut u8 = [0, 0] + buffer [2]mut u8 := [0, 0] count usize :: io.read(ok_reader(), buffer[..]) catch 0 if count != 2 or buffer[0] != 'o' or buffer[1] != 'k' { return 1 diff --git a/examples/programs/match/main.bro b/examples/programs/match/main.bro index 57fff20..6074a71 100644 --- a/examples/programs/match/main.bro +++ b/examples/programs/match/main.bro @@ -63,18 +63,18 @@ make_box func() Box { } main func() i32 { - acc i32 = 0 + acc i32 := 0 - dog Data = Data{ dog = 9 } - bird Data = Data{ bird = 38 } + dog Data := Data{ dog = 9 } + bird Data := Data{ bird = 38 } acc = acc + describe(dog) + describe(bird) # 10 + 40 = 50 # same-type multi-pattern capture acc = acc + payload_of(dog) + payload_of(bird) # 9 + 38 = 47 # enum statement match, exhaustive, with a multi-pattern arm - a Animal = .bird - rank i32 = 0 + a Animal := .bird + rank i32 := 0 match a { .dog, .cat: rank = 1 .bird: rank = 3 @@ -89,7 +89,7 @@ main func() i32 { acc = acc + legs # +2 # scalar match: a range arm, a multi-literal arm, and a mandatory else - bucket i32 = 0 + bucket i32 := 0 match rank { 0..3: bucket = 1 # exclusive 0,1,2 — does not include 3 3, 4: bucket = 5 # rank is 3 @@ -98,8 +98,8 @@ main func() i32 { acc = acc + bucket # +5 # void-payload variant: contextual construction (`.empty` coerces to Box) + no-capture arm - e Box = .empty - hit i32 = 0 + e Box := .empty + hit i32 := 0 match e { .point |pt|: hit = pt.x .empty: hit = 7 @@ -107,7 +107,7 @@ main func() i32 { acc = acc + hit # +7 # pointer capture mutates the subject's payload in place - b Box = Box{ point = Point{ x = 1, y = 2 } } + b Box := Box{ point = Point{ x = 1, y = 2 } } match b { .point |@p|: p.x = 10 .empty: hit = hit diff --git a/examples/programs/mem_allocator/raw_alloc.bro b/examples/programs/mem_allocator/raw_alloc.bro index abbbcb0..54d7d2d 100644 --- a/examples/programs/mem_allocator/raw_alloc.bro +++ b/examples/programs/mem_allocator/raw_alloc.bro @@ -1,7 +1,7 @@ mem :: import "@std/mem" raw_allocator_test func() i32 { - resized ?*mut u8 = mem.raw_realloc(mem.c_allocator, null, 0, 4, 1) + resized ?*mut u8 := mem.raw_realloc(mem.c_allocator, null, 0, 4, 1) if resized |bytes| { bytes[0] = 10 bytes[1] = 20 @@ -11,7 +11,7 @@ raw_allocator_test func() i32 { return 20 } - grown ?*mut u8 = mem.raw_realloc(mem.c_allocator, resized, 4, 8, 1) + grown ?*mut u8 := mem.raw_realloc(mem.c_allocator, resized, 4, 8, 1) if grown |bytes| { resized = grown if bytes[0] != 10 or bytes[1] != 20 or bytes[2] != 30 or bytes[3] != 40 { @@ -23,7 +23,7 @@ raw_allocator_test func() i32 { return 22 } - shrunk ?*mut u8 = mem.raw_realloc(mem.c_allocator, resized, 8, 2, 1) + shrunk ?*mut u8 := mem.raw_realloc(mem.c_allocator, resized, 8, 2, 1) if shrunk |bytes| { resized = shrunk if bytes[0] != 10 or bytes[1] != 20 { @@ -35,7 +35,7 @@ raw_allocator_test func() i32 { return 24 } - invalid ?*mut u8 = mem.raw_realloc(mem.c_allocator, resized, 2, 4, 24) + invalid ?*mut u8 := mem.raw_realloc(mem.c_allocator, resized, 2, 4, 24) if invalid |memory| { mem.raw_free(mem.c_allocator, memory, 4, 24) mem.raw_free(mem.c_allocator, resized, 2, 1) @@ -54,14 +54,14 @@ raw_allocator_test func() i32 { return 27 } - over_aligned ?*mut u8 = mem.raw_alloc(mem.c_allocator, 4, 32) + over_aligned ?*mut u8 := mem.raw_alloc(mem.c_allocator, 4, 32) if over_aligned |bytes| { bytes[0] = 11 bytes[1] = 22 } else { return 28 } - over_aligned_grown ?*mut u8 = mem.raw_realloc(mem.c_allocator, over_aligned, 4, 8, 32) + over_aligned_grown ?*mut u8 := mem.raw_realloc(mem.c_allocator, over_aligned, 4, 8, 32) if over_aligned_grown |bytes| { if bytes[0] != 11 or bytes[1] != 22 { mem.raw_free(mem.c_allocator, over_aligned_grown, 8, 32) @@ -73,19 +73,19 @@ raw_allocator_test func() i32 { return 30 } - zero_alignment ?*mut u8 = mem.raw_alloc(mem.c_allocator, 8, 0) + zero_alignment ?*mut u8 := mem.raw_alloc(mem.c_allocator, 8, 0) if zero_alignment |memory| { mem.raw_free(mem.c_allocator, memory, 8, 0) return 1 } - bad_alignment ?*mut u8 = mem.raw_alloc(mem.c_allocator, 8, 24) + bad_alignment ?*mut u8 := mem.raw_alloc(mem.c_allocator, 8, 24) if bad_alignment |memory| { mem.raw_free(mem.c_allocator, memory, 8, 24) return 2 } - aligned ?*mut u8 = mem.raw_alloc(mem.c_allocator, 64, 32) + aligned ?*mut u8 := mem.raw_alloc(mem.c_allocator, 64, 32) defer mem.raw_free(mem.c_allocator, aligned, 64, 32) if aligned |bytes| { bytes[0] = 1 diff --git a/examples/programs/mem_allocator/task_list.bro b/examples/programs/mem_allocator/task_list.bro index c63e9ed..05a8063 100644 --- a/examples/programs/mem_allocator/task_list.bro +++ b/examples/programs/mem_allocator/task_list.bro @@ -21,9 +21,9 @@ task_list_init func(allocator mem.Allocator) TaskList { } alloc_i32s func(allocator mem.Allocator, count usize) ?[]mut i32 { - fallback [1]mut i32 = undefined - failed bool = false - values []mut i32 = mem.alloc(allocator, count) catch |_| { + fallback [1]mut i32 := undefined + failed bool := false + values []mut i32 := mem.alloc(allocator, count) catch |_| { failed = true yield (&fallback).ptr[..0] } @@ -42,14 +42,14 @@ task_list_reserve func(list @mut TaskList, capacity usize) bool { return true } - new_ids ?[]mut i32 = alloc_i32s(list.allocator, capacity) - new_priorities ?[]mut i32 = alloc_i32s(list.allocator, capacity) - new_durations ?[]mut i32 = alloc_i32s(list.allocator, capacity) + new_ids ?[]mut i32 := alloc_i32s(list.allocator, capacity) + new_priorities ?[]mut i32 := alloc_i32s(list.allocator, capacity) + new_durations ?[]mut i32 := alloc_i32s(list.allocator, capacity) if (new_ids and new_priorities and new_durations) |ids, priorities, durations| { if list.len > 0 { if (list.ids and list.priorities and list.durations) |old_ids, old_priorities, old_durations| { - i usize = 0 + i usize := 0 while i < list.len : i += 1 { ids[i] = old_ids[i] priorities[i] = old_priorities[i] @@ -82,7 +82,7 @@ task_list_reserve func(list @mut TaskList, capacity usize) bool { task_list_push func(list @mut TaskList, id i32, priority i32, duration i32) bool { if list.len == list.capacity { - new_capacity usize = 2 + new_capacity usize := 2 if list.capacity != 0 { new_capacity = list.capacity * 2 } @@ -92,7 +92,7 @@ task_list_push func(list @mut TaskList, id i32, priority i32, duration i32) bool } if (list.ids and list.priorities and list.durations) |ids, priorities, durations| { - index usize = list.len + index usize := list.len ids[index] = id priorities[index] = priority durations[index] = duration @@ -113,11 +113,11 @@ task_list_best_id func(list @mut TaskList) i32 { } if (list.ids and list.priorities and list.durations) |ids, priorities, durations| { - best_index usize = 0 - best_score i32 = task_score(priorities[0], durations[0]) - i usize = 1 + best_index usize := 0 + best_score i32 := task_score(priorities[0], durations[0]) + i usize := 1 while i < list.len : i += 1 { - score i32 = task_score(priorities[i], durations[i]) + score i32 := task_score(priorities[i], durations[i]) if score > best_score { best_score = score best_index = i @@ -130,9 +130,9 @@ task_list_best_id func(list @mut TaskList) i32 { } task_list_total_duration func(list @mut TaskList) i32 { - total i32 = 0 + total i32 := 0 if list.durations |durations| { - i usize = 0 + i usize := 0 while i < list.len : i += 1 { total += durations[i] } @@ -152,7 +152,7 @@ task_list_deinit func(list @mut TaskList) void { } task_list_test func() i32 { - tasks TaskList = task_list_init(mem.c_allocator) + tasks TaskList := task_list_init(mem.c_allocator) defer task_list_deinit(&tasks) if task_list_push(&tasks, 101, 3, 5) == false { diff --git a/examples/programs/mem_allocator/typed_alloc.bro b/examples/programs/mem_allocator/typed_alloc.bro index 0dbd05f..5a6aedc 100644 --- a/examples/programs/mem_allocator/typed_alloc.bro +++ b/examples/programs/mem_allocator/typed_alloc.bro @@ -30,8 +30,8 @@ hide probe_vtable mem.AllocatorVTable :: mem.AllocatorVTable { typed_allocator_test func() i32 { if (sizeof!(mem.Allocator) != 16) return 31 - first_calls [1]mut usize = [0] - second_calls [1]mut usize = [0] + first_calls [1]mut usize := [0] + second_calls [1]mut usize := [0] first_allocator mem.Allocator :: mem.Allocator { context = &first_calls, vtable = &probe_vtable, @@ -47,9 +47,9 @@ typed_allocator_test func() i32 { _ = mem.raw_alloc(second_allocator, 1, 1) if (first_calls[0] != 3 or second_calls[0] != 1) return 32 - i32_fallback [1]mut i32 = undefined - empty_failed bool = false - empty []mut i32 = mem.alloc(first_allocator, 0) catch |_| { + i32_fallback [1]mut i32 := undefined + empty_failed bool := false + empty []mut i32 := mem.alloc(first_allocator, 0) catch |_| { empty_failed = true yield (&i32_fallback).ptr[..0] } @@ -57,9 +57,9 @@ typed_allocator_test func() i32 { mem.free(first_allocator, empty) if (first_calls[0] != 3) return 33 - zero_sized_fallback [1]mut [0]u8 = undefined - zero_sized_failed bool = false - zero_sized []mut [0]u8 = mem.alloc([0]u8, first_allocator, 3) catch |_| { + zero_sized_fallback [1]mut [0]u8 := undefined + zero_sized_failed bool := false + zero_sized []mut [0]u8 := mem.alloc([0]u8, first_allocator, 3) catch |_| { zero_sized_failed = true yield (&zero_sized_fallback).ptr[..0] } @@ -68,22 +68,22 @@ typed_allocator_test func() i32 { mem.free([0]u8, first_allocator, zero_sized) if (first_calls[0] != 3) return 35 - u64_fallback [1]mut u64 = undefined - overflow_fallback_failed bool = false - overflow_fallback []mut u64 = mem.alloc(first_allocator, 0) catch |_| { + u64_fallback [1]mut u64 := undefined + overflow_fallback_failed bool := false + overflow_fallback []mut u64 := mem.alloc(first_allocator, 0) catch |_| { overflow_fallback_failed = true yield (&u64_fallback).ptr[..0] } if (overflow_fallback_failed) return 37 - overflow_failed bool = false + overflow_failed bool := false _ = mem.alloc(u64, first_allocator, maxval!(usize)) catch |_| { overflow_failed = true yield overflow_fallback } if (overflow_failed == false or first_calls[0] != 3) return 40 - typed_failed bool = false - typed []mut i32 = mem.alloc(mem.c_allocator, 4) catch |_| { + typed_failed bool := false + typed []mut i32 := mem.alloc(mem.c_allocator, 4) catch |_| { typed_failed = true yield (&i32_fallback).ptr[..0] } diff --git a/examples/programs/milestone_24/main.bro b/examples/programs/milestone_24/main.bro index ac06836..9e70e10 100644 --- a/examples/programs/milestone_24/main.bro +++ b/examples/programs/milestone_24/main.bro @@ -48,26 +48,26 @@ score_for func(k Kind) i32 { } main func() i32 { - items [LEN]mut i32 = undefined + items [LEN]mut i32 := undefined items[0] = 10 items[1] = 20 - idx u8 = 2 + idx u8 := 2 items[idx] = items[0] + items[1] if (items[2] != 30) return 1 - native_i i32 = 12 + native_i i32 := 12 if (take_c_int(native_i) != 12) return 2 - native_u u8 = 7 + native_u u8 := 7 if (take_c_uchar(native_u) != 7) return 3 - native_f f32 = 3.25 + native_f f32 := 3.25 cf :: take_c_float(native_f) if (cf < 3.0 or cf > 4.0) return 4 if (cf == 0.0) return 5 - native_d f64 = 5.0 + native_d f64 := 5.0 cd :: take_c_double(native_d) if (cd != 5.0) return 6 diff --git a/examples/programs/milestone_39/main.bro b/examples/programs/milestone_39/main.bro index 91bc888..e33759d 100644 --- a/examples/programs/milestone_39/main.bro +++ b/examples/programs/milestone_39/main.bro @@ -86,8 +86,8 @@ main func(init process.Init) i32 { } writer io.Writer :: io.stdout(init.io) - positive f64 = 1.0 - zero f64 = 0.0 + positive f64 := 1.0 + zero f64 := 0.0 infinity f64 :: positive / zero nan f64 :: zero / zero io.print(writer, "{} {} {} {} {s} {d} {b} {o} {x} {X} {c} {e} {{}} {d} {b} {} {} {e}\n", { diff --git a/examples/programs/mutable_global/main.bro b/examples/programs/mutable_global/main.bro index ee2960e..d549fde 100644 --- a/examples/programs/mutable_global/main.bro +++ b/examples/programs/mutable_global/main.bro @@ -2,11 +2,11 @@ Point :: struct { x i32 } -counter int = 0 -ratio float = 1 -span range = 0..2 -point Point = Point { x = 1 } -values [_]mut i32 = [10, 20] +counter := i32(0) +ratio := 1.0 +span := 0..2 +point Point := Point { x = 1 } +values [_]mut i32 := [10, 20] bump func(value @mut i32) void { value^ += 1 @@ -19,7 +19,7 @@ main func() i32 { point.x += counter values[1] = point.x - total i32 = counter + point.x + values[1] + total i32 := counter + point.x + values[1] for span |i| { total += i } diff --git a/examples/programs/mutable_local/main.bro b/examples/programs/mutable_local/main.bro index 1b41ce7..71f81be 100644 --- a/examples/programs/mutable_local/main.bro +++ b/examples/programs/mutable_local/main.bro @@ -1,5 +1,5 @@ main func() i32 { - value i32 = 1 + value := i32(1) value = value + 2 return value } diff --git a/examples/programs/overflow/main.bro b/examples/programs/overflow/main.bro index e75cc8a..93405b4 100644 --- a/examples/programs/overflow/main.bro +++ b/examples/programs/overflow/main.bro @@ -1,4 +1,4 @@ main func() void { - value i8 = 127 + value i8 := 127 _ = value + 1 } diff --git a/examples/programs/prototype/main.bro b/examples/programs/prototype/main.bro index c0a9679..0b446df 100644 --- a/examples/programs/prototype/main.bro +++ b/examples/programs/prototype/main.bro @@ -11,7 +11,7 @@ sum_brolang func(a, b int) int { } main func() void { - y int = 4 + y int := 4 a_add_b_c :: sum_c(1, 2) a_add_b_brolang :: sum_brolang(1, 2) _ = y diff --git a/examples/programs/scalar_cast_error/main.bro b/examples/programs/scalar_cast_error/main.bro index 7972747..f7478fd 100644 --- a/examples/programs/scalar_cast_error/main.bro +++ b/examples/programs/scalar_cast_error/main.bro @@ -1,5 +1,5 @@ main func() i32 { - flag bool = true + flag bool := true value :: i32(flag) return value } diff --git a/examples/programs/tagged_union/main.bro b/examples/programs/tagged_union/main.bro index 9661485..6cafdcf 100644 --- a/examples/programs/tagged_union/main.bro +++ b/examples/programs/tagged_union/main.bro @@ -16,7 +16,7 @@ Thing :: union(enum) { } main func() i32 { - x Data = Data{ bird = 37 } - y Thing = Thing{ a = 5 } + x Data := Data{ bird = 37 } + y Thing := Thing{ a = 5 } return x.bird + y.a } diff --git a/examples/programs/tuples/main.bro b/examples/programs/tuples/main.bro index 1b7b442..c865a53 100644 --- a/examples/programs/tuples/main.bro +++ b/examples/programs/tuples/main.bro @@ -9,7 +9,7 @@ format func() []u8 { } sum func($T type, value T) i32 { - total i32 = 0 + total i32 := 0 match typeinfo!(T) { .record |record|: inline for record.fields |field| { total += i32(field!(value, field.name)) @@ -20,7 +20,7 @@ sum func($T type, value T) i32 { } static_control func($T type, value T) i32 { - total i32 = 0 + total i32 := 0 match typeinfo!(T) { .record |record|: inline for record.fields |field| { { @@ -49,7 +49,7 @@ row_value func(row Row) i32 { } static_aggregates func() i32 { - total i32 = 0 + total i32 := 0 inline for {Row {value = 2}, Row {value = 40}} |row| { total += row_value(row) } @@ -57,7 +57,7 @@ static_aggregates func() i32 { } main func() i32 { - numbers Numbers = Numbers {1, 2, 39} + numbers Numbers := Numbers {1, 2, 39} singleton :: {42,} empty :: {} block_value :: { diff --git a/examples/programs/unions/main.bro b/examples/programs/unions/main.bro index 5628a1c..9b8457d 100644 --- a/examples/programs/unions/main.bro +++ b/examples/programs/unions/main.bro @@ -4,6 +4,6 @@ Val :: union { } main func() i32 { - x Val = Val{ n = 42 } + x Val := Val{ n = 42 } return x.n } diff --git a/examples/programs/unused_locals/main.bro b/examples/programs/unused_locals/main.bro index 966570f..a34102c 100644 --- a/examples/programs/unused_locals/main.bro +++ b/examples/programs/unused_locals/main.bro @@ -1,8 +1,8 @@ warn_only func(value i32, unused i32) i32 { - local i32 = 1 - write_only i32 = 2 + local i32 := 1 + write_only i32 := 2 write_only = 3 - consumed i32 = value + consumed i32 := value _ = consumed return value } diff --git a/examples/programs/while_loop/main.bro b/examples/programs/while_loop/main.bro index 277a52a..92cba7e 100644 --- a/examples/programs/while_loop/main.bro +++ b/examples/programs/while_loop/main.bro @@ -1,31 +1,31 @@ # Milestone 5: boolean while loops with optional post-iteration updates. return_before_update func() i32 { - i i32 = 0 + i i32 := 0 while true : i = i + 1 { return i } } main func() i32 { - total i32 = 0 + total i32 := 0 # ordinary condition and update - i u32 = 0 + i u32 := 0 while i < 5 : i = i + 1 { total = total + 2 } # equivalent parenthesized header - j u32 = 0 + j u32 := 0 while (j < 4) : (j = j + 1) { total = total + 3 } # nested loops and body-local storage - outer u32 = 0 + outer u32 := 0 while outer < 2 : outer = outer + 1 { - inner u32 = 0 + inner u32 := 0 while inner < 3 : inner = inner + 1 { total = total + 2 } @@ -33,9 +33,9 @@ main func() i32 { # Body-local storage stays scoped to the body. The update still targets # the mutable k declared before the loop. - k u32 = 0 + k u32 := 0 while k < 4 : k = k + 1 { - body_k u32 = 100 + body_k u32 := 100 if body_k == 100 { total = total + 2 } diff --git a/examples/programs/yield/main.bro b/examples/programs/yield/main.bro index eee69d6..a79dac3 100644 --- a/examples/programs/yield/main.bro +++ b/examples/programs/yield/main.bro @@ -19,7 +19,7 @@ basic func() i32 { # Typed `T =`: the yield coerces to the annotation. typed func() i64 { - x i64 = { + x i64 := { yield 100 } return x @@ -29,7 +29,7 @@ typed func() i64 { # local, but the captured value is unchanged. spill func() i32 { v :: { - n i32 = 5 + n i32 := 5 defer n = 999 yield n } @@ -38,7 +38,7 @@ spill func() i32 { # Reassignment into an existing mutable local. reassign func() i32 { - r i32 = 0 + r i32 := 0 r = { yield 7 } @@ -61,13 +61,13 @@ vif_untyped func(sel i32) i32 { # Typed `T =`: every branch coerces to the annotation. vif_typed func(sel i32) i32 { - r i32 = if (sel == 0) { yield 100 } else { yield 200 } + r i32 := if (sel == 0) { yield 100 } else { yield 200 } return r } # Assigned into an existing local. vif_reassign func(sel i32) i32 { - r i32 = 0 + r i32 := 0 r = if (sel == 0) { yield 7 } else { yield 9 } return r } @@ -76,7 +76,7 @@ vif_reassign func(sel i32) i32 { # the yield. vif_defer func() i32 { r :: if (true) { - n i32 = 5 + n i32 := 5 defer n = 999 yield n } else { @@ -123,7 +123,7 @@ loop_none func() i32 { # Labeled `while` value loop (label follows the `: update` clause). loop_while func() i32 { - n i32 = 0 + n i32 := 0 found :: while n < 100 : n += 1 blk: { if (n == 8) yield :blk n yield null @@ -199,7 +199,7 @@ lblock func(sel i32) i32 { # the block's defer runs. lblock_defer func() i32 { r :: blk: { - n i32 = 5 + n i32 := 5 defer n = 999 if (true) yield :blk n yield :blk 0 @@ -235,7 +235,7 @@ yield_outer func(target i32) i32 { # Plain `break :outer` exits an outer loop from an inner loop. break_outer func() i32 { - count i32 = 0 + count i32 := 0 for 0..3 |a| outer: { for 0..3 |b| { count += 1 @@ -247,7 +247,7 @@ break_outer func() i32 { # A labeled block *statement* (not a value source): `break :blk` exits it early. stmt_block func(early i32) i32 { - x i32 = 0 + x i32 := 0 blk: { x = 1 if (early == 1) break :blk @@ -259,7 +259,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 { - hits i32 = 0 + hits i32 := 0 search: { defer hits += 1000 for 0..10 |i| { @@ -273,7 +273,7 @@ stmt_block_escape func() i32 { # A labeled block can also be exited through an ordinary nested block. stmt_block_nested func() i32 { - hits i32 = 0 + hits i32 := 0 outer: { { hits = 1 diff --git a/std/arraylist/arraylist.hon b/std/arraylist/arraylist.hon index 4eb28d1..12664d5 100644 --- a/std/arraylist/arraylist.hon +++ b/std/arraylist/arraylist.hon @@ -28,7 +28,7 @@ reserve func($T type, list @mut ArrayList(T), min_capacity usize) void ! mem.All return } - new_capacity usize = 8 + new_capacity usize := 8 if list.capacity >= 8 { half usize :: divtrunc!(list.capacity, 2) if list.capacity > maxval!(usize) - half { diff --git a/std/arraylist/arraylist.test.hon b/std/arraylist/arraylist.test.hon index ae64e8d..e99a499 100644 --- a/std/arraylist/arraylist.test.hon +++ b/std/arraylist/arraylist.test.hon @@ -2,7 +2,7 @@ import "@std/mem" import "@std/testing" handles_append test { - list ArrayList(i32) = init(mem.c_allocator) + list ArrayList(i32) := init(mem.c_allocator) defer deinit(&list) try append(&list, 42) @@ -12,7 +12,7 @@ handles_append test { } handles_clear test { - list ArrayList(i32) = init(mem.c_allocator) + list ArrayList(i32) := init(mem.c_allocator) defer deinit(&list) try append(&list, 42) @@ -22,7 +22,7 @@ handles_clear test { } handles_reserve test { - list ArrayList(i32) = init(mem.c_allocator) + list ArrayList(i32) := init(mem.c_allocator) defer deinit(&list) try reserve(&list, 10) diff --git a/std/debug/debug.hon b/std/debug/debug.hon index fa1f863..78ddacb 100644 --- a/std/debug/debug.hon +++ b/std/debug/debug.hon @@ -11,7 +11,7 @@ print func($format []u8, $Args type, args Args) void { } hide write func(_ ?@mut anyopaque, handle io.Handle, bytes []u8) usize ! io.WriteError { - request usize = bytes.len + request usize := bytes.len maximum usize :: usize(maxval!(c_long)) if request > maximum { request = maximum diff --git a/std/enums/enums.hon b/std/enums/enums.hon index b4927c1..dd45f72 100644 --- a/std/enums/enums.hon +++ b/std/enums/enums.hon @@ -14,7 +14,7 @@ init func( $E, $V type, values meta.EnumFieldStruct(E, ?V, some!(null)), ) EnumMap(E, V) { - map EnumMap(E, V) = undefined + map EnumMap(E, V) := undefined match typeinfo!(E) { .enum |info|: inline for info.fields |field, i| { diff --git a/std/enums/enums.test.hon b/std/enums/enums.test.hon index d50441a..9937d61 100644 --- a/std/enums/enums.test.hon +++ b/std/enums/enums.test.hon @@ -8,7 +8,7 @@ TestEnum :: enum(u8) { } handles_sparse_enum_get test { - names EnumMap(TestEnum, []u8) = init({ + names EnumMap(TestEnum, []u8) := init({ ident = "identifier", int = "integer", }) diff --git a/std/hashmap/hashmap.hon b/std/hashmap/hashmap.hon index 0080d05..635b150 100644 --- a/std/hashmap/hashmap.hon +++ b/std/hashmap/hashmap.hon @@ -59,7 +59,7 @@ get func( if (map.count == 0) return null hash :: normalize(hash_key(key)) - idx usize = hash & (map.entries.len - 1) + idx usize := hash & (map.entries.len - 1) while true { entry :: map.entries[idx] @@ -98,7 +98,7 @@ put func( if (entry.hash == 0) continue # find an empty slot - idx usize = entry.hash & (new_entries.len - 1) + idx usize := entry.hash & (new_entries.len - 1) while new_entries[idx].hash != 0 { idx = (idx + 1) & (new_entries.len - 1) } @@ -112,7 +112,7 @@ put func( # put new entry hash :: normalize(hash_key(key)) - idx usize = hash & (map.entries.len - 1) + idx usize := hash & (map.entries.len - 1) while true { entry :: map.entries[idx] @@ -144,8 +144,8 @@ hide normalize func(hash usize) usize { #! FNV-1a hash implementation. #! note: vulnerable to collision attacks. hide str_hash func(key []u8) usize { - hash u32 = 2166136261 # offset basis - prime u32 = 16777619 + hash u32 := 2166136261 # offset basis + prime u32 := 16777619 for key |byte| { product u64 :: u64(hash xor u32(byte)) * prime diff --git a/std/hashmap/hashmap.test.hon b/std/hashmap/hashmap.test.hon index 57ff8a4..2b10e7e 100644 --- a/std/hashmap/hashmap.test.hon +++ b/std/hashmap/hashmap.test.hon @@ -2,7 +2,7 @@ import "@std/mem" import "@std/testing" handles_put_and_get test { - map StringHashMap(u32) = init(mem.c_allocator) + map StringHashMap(u32) := init(mem.c_allocator) defer deinit(&map) try put(&map, "key", 42) diff --git a/std/io/file.hon b/std/io/file.hon index e1a37aa..7ba39ef 100644 --- a/std/io/file.hon +++ b/std/io/file.hon @@ -47,7 +47,7 @@ writer func(file File) Writer { } hide system_read func(_ ?@mut anyopaque, handle Handle, buffer []mut u8) usize ! ReadError { - request usize = buffer.len + request usize := buffer.len maximum usize :: usize(maxval!(c_long)) if request > maximum { request = maximum @@ -69,7 +69,7 @@ hide system_read func(_ ?@mut anyopaque, handle Handle, buffer []mut u8) usize ! } hide system_write func(_ ?@mut anyopaque, handle Handle, bytes []u8) usize ! WriteError { - request usize = bytes.len + request usize := bytes.len maximum usize :: usize(maxval!(c_long)) if request > maximum { request = maximum @@ -91,7 +91,7 @@ hide system_write func(_ ?@mut anyopaque, handle Handle, bytes []u8) usize ! Wri } hide system_open func(_ ?@mut anyopaque, path [;0]u8, mode FileMode) Handle ! OpenError { - flags c_int = c.O_RDONLY + flags c_int := c.O_RDONLY match mode { .read_only: flags = c.O_RDONLY .write_only: flags = c.O_WRONLY diff --git a/std/io/io.hon b/std/io/io.hon index d016e7f..6fbb40c 100644 --- a/std/io/io.hon +++ b/std/io/io.hon @@ -73,7 +73,7 @@ write func(output Writer, bytes []u8) usize ! WriteError { } write_all func(output Writer, bytes []u8) void ! WriteError { - offset usize = 0 + offset usize := 0 while offset < bytes.len { count usize :: write(output, bytes[offset..]) catch |err| { return err @@ -129,12 +129,12 @@ print func(output Writer, $format []u8, $Args type, args Args) void ! WriteError } hide write_integer_signed func(output Writer, value i64, base u64, uppercase bool) void ! WriteError { - buffer [65]mut u8 = undefined - end usize = buffer.len - current i64 = value + buffer [65]mut u8 := undefined + end usize := buffer.len + current i64 := value while true { digit_value i64 :: rem!(current, i64(base)) - digit u8 = 0 + digit u8 := 0 if digit_value < 0 { digit = u8(-digit_value) } else { @@ -162,9 +162,9 @@ hide write_integer_signed func(output Writer, value i64, base u64, uppercase boo } hide write_integer_unsigned func(output Writer, value u64, base u64, uppercase bool) void ! WriteError { - buffer [65]mut u8 = undefined - end usize = buffer.len - current u64 = value + buffer [65]mut u8 := undefined + end usize := buffer.len + current u64 := value while true { digit u8 :: u8(rem!(current, base)) end -= 1 @@ -206,11 +206,11 @@ hide FormatToken :: struct { } hide parse_format func($N usize, $format []u8, $Args type) [N]mut FormatToken { - tokens [N]mut FormatToken = undefined + tokens [N]mut FormatToken := undefined for (usize(0))..format.len |index| { tokens[index] = FormatToken {kind = .unused, start = 0, end = 0, field = ""} } - field_count usize = 0 + field_count usize := 0 match typeinfo!(Args) { .record |record|: { if !record.is_tuple { @@ -221,10 +221,10 @@ hide parse_format func($N usize, $format []u8, $Args type) [N]mut FormatToken { else: compile_error!("io.print arguments must be a tuple") } - token_count usize = 0 - argument_count usize = 0 - literal_start usize = 0 - cursor usize = 0 + token_count usize := 0 + argument_count usize := 0 + literal_start usize := 0 + cursor usize := 0 while cursor < format.len { byte :: format[cursor] if byte == '{' { @@ -243,8 +243,8 @@ hide parse_format func($N usize, $format []u8, $Args type) [N]mut FormatToken { literal_start = cursor continue } - kind FormatTokenKind = .default - width usize = 2 + kind FormatTokenKind := .default + width usize := 2 if next != '}' { if cursor + 2 >= format.len or format[cursor + 2] != '}' { compile_error!("io.print format expects a one-character specifier") @@ -353,8 +353,8 @@ hide write_integer func(output Writer, $T type, value T, base u64, uppercase boo hide write_float func(output Writer, $T type, value T, scientific bool) void ! WriteError { match typeinfo!(T) { .float: { - buffer [64]mut u8 = undefined - count c_int = 0 + buffer [64]mut u8 := undefined + count c_int := 0 if sizeof!(T) == 4 { if scientific { count = c.snprintf(ptrcast!(c_char, (&buffer).ptr), c_ulong(buffer.len), "%.8e", value) @@ -401,7 +401,7 @@ hide write_character func(output Writer, $T type, value T) void ! WriteError { if minval!(T) < 0 or maxval!(T) > 255 { compile_error!("io.print '{c}' requires an unsigned integer that fits in u8") } - buffer [1]u8 = [u8(value)] + buffer [1]u8 := [u8(value)] try write_all(output, buffer[..]) } .distinct |backing|: if scalar_or_distinct_type(backing) { diff --git a/std/mem/mem.hon b/std/mem/mem.hon index 555065c..a474caf 100644 --- a/std/mem/mem.hon +++ b/std/mem/mem.hon @@ -46,7 +46,7 @@ alloc func($T type, allocator Allocator, count usize) []mut T ! AllocError { return .out_of_memory } - memory ?*mut u8 = raw_alloc(allocator, count * element_size, alignof!(T)) + memory ?*mut u8 := raw_alloc(allocator, count * element_size, alignof!(T)) if memory |bytes| { pointer *mut T :: ptrcast!(T, bytes) return pointer[..count] @@ -75,13 +75,13 @@ realloc func($T type, allocator Allocator, memory []mut T, new_count usize) []mu return .out_of_memory } - old_memory ?*mut u8 = null - old_size usize = 0 + old_memory ?*mut u8 := null + old_size usize := 0 if memory.len != 0 { old_memory = ptrcast!(u8, memory.ptr) old_size = memory.len * element_size } - resized ?*mut u8 = raw_realloc( + resized ?*mut u8 := raw_realloc( allocator, old_memory, old_size, @@ -119,15 +119,15 @@ empty func($T type) []mut T { return empty_slice(T, 0) } -hide empty_storage [1]mut u64 = [0] +hide empty_storage [1]mut u64 := [0] hide malloc_alignment usize :: 16 # ponytail: aarch64-macos libc malloc alignment assumption. hide power_of_two func(value usize) bool { if (value == 0) return false - current usize = value + current usize := value while current > 1 { - half usize = divtrunc!(current, 2) + half usize := divtrunc!(current, 2) if (half * 2 != current) return false current = half } @@ -141,8 +141,8 @@ hide c_alloc func(_ ?@mut anyopaque, size usize, alignment usize) ?*mut u8 { return ptrcast!(u8, c.malloc(c_ulong(size))) } - memory [1]mut ?*mut anyopaque = [null] - status c_int = c.posix_memalign((&memory).ptr, c_ulong(alignment), c_ulong(size)) + memory [1]mut ?*mut anyopaque := [null] + status c_int := c.posix_memalign((&memory).ptr, c_ulong(alignment), c_ulong(size)) if (status != 0) return null return ptrcast!(u8, memory[0]) @@ -161,9 +161,9 @@ hide c_realloc func(_ ?@mut anyopaque, memory ?*mut u8, old_size usize, new_size return ptrcast!(u8, c.realloc(old_memory, c_ulong(new_size))) } - new_memory ?*mut u8 = c_alloc(null, new_size, alignment) + new_memory ?*mut u8 := c_alloc(null, new_size, alignment) if new_memory |new_bytes| { - copy_size usize = old_size + copy_size usize := old_size if (new_size < copy_size) copy_size = new_size memcopy!(new_bytes[..copy_size], old_memory[..copy_size]) c.free(old_memory) diff --git a/std/meta/meta.hon b/std/meta/meta.hon index 73fbd48..7ab9788 100644 --- a/std/meta/meta.hon +++ b/std/meta/meta.hon @@ -46,9 +46,9 @@ TypeInfo :: union(enum) { EnumFieldStruct func($E, $Field type, $default ?Field) type { match typeinfo!(E) { .enum |info|: { - names [info.fields.len]mut []u8 = undefined - field_types [info.fields.len]mut type = undefined - defaults [info.fields.len]mut ?Field = undefined + names [info.fields.len]mut []u8 := undefined + field_types [info.fields.len]mut type := undefined + defaults [info.fields.len]mut ?Field := undefined inline for info.fields |field, index| { names[index] = field.name field_types[index] = Field diff --git a/std/meta/meta.test.hon b/std/meta/meta.test.hon index 0a59cae..0d45e02 100644 --- a/std/meta/meta.test.hon +++ b/std/meta/meta.test.hon @@ -42,7 +42,7 @@ distinct_reflection_exposes_immediate_backing test { enum_field_struct_defaults test { - names TestNames = { + names TestNames := { ident = "identifier", int = "integer", } @@ -60,7 +60,7 @@ enum_field_struct_defaults test { try testing.expect(false) } - empty TestNames = {} + empty TestNames := {} if field!(empty, "ident") |_| { try testing.expect(false) } diff --git a/std/static_string_map/static_string_map.hon b/std/static_string_map/static_string_map.hon index 119f60d..0b0868d 100644 --- a/std/static_string_map/static_string_map.hon +++ b/std/static_string_map/static_string_map.hon @@ -19,8 +19,8 @@ init func($V type, $N usize, $entries [N]Pair(V)) StaticStringMap(V) { compile_error!("static string map has too many entries") } - keys [N]mut []u8 = undefined - values [N]mut V = undefined + keys [N]mut []u8 := undefined + values [N]mut V := undefined # assert no duplicate keys for entries |entry, i| { @@ -37,7 +37,7 @@ init func($V type, $N usize, $entries [N]Pair(V)) StaticStringMap(V) { } if N == 0 { - len_indexes [0]u32 = undefined + len_indexes [0]u32 := undefined return StaticStringMap(V){ keys = keys[..], values = values[..], @@ -51,7 +51,7 @@ init func($V type, $N usize, $entries [N]Pair(V)) StaticStringMap(V) { for 1..N |i| { key :: keys[i] value :: values[i] - j usize = i + j usize := i while j > 0 and keys[j - 1].len > key.len : j -= 1 { keys[j] = keys[j - 1] values[j] = values[j - 1] @@ -62,8 +62,8 @@ init func($V type, $N usize, $entries [N]Pair(V)) StaticStringMap(V) { min_len u32 :: u32(keys[0].len) max_len u32 :: u32(keys[N - 1].len) - len_indexes [usize(max_len) + 1]mut u32 = undefined - entry_index usize = 0 + len_indexes [usize(max_len) + 1]mut u32 := undefined + entry_index usize := 0 for 0..=usize(max_len) |length| { while entry_index < N and keys[entry_index].len < length : entry_index += 1 {} len_indexes[length] = u32(entry_index) @@ -81,10 +81,10 @@ init func($V type, $N usize, $entries [N]Pair(V)) StaticStringMap(V) { get func($V type, map @StaticStringMap(V), key []u8) ?V { if (map.keys.len == 0 or key.len > maxval!(u32)) return null - length u32 = u32(key.len) + length u32 := u32(key.len) if (length < map.min_len or length > map.max_len) return null - idx usize = usize(map.len_indexes[usize(length)]) + idx usize := usize(map.len_indexes[usize(length)]) while idx < map.keys.len : idx += 1 { candidate :: map.keys[idx] if (candidate.len != key.len) return null diff --git a/testbed/game/main.bro b/testbed/game/main.bro index 06c014d..fbbd171 100644 --- a/testbed/game/main.bro +++ b/testbed/game/main.bro @@ -77,8 +77,8 @@ read_command func() Command { if IsMouseButtonPressed(MOUSE_BUTTON_LEFT) return .spawn{ GetMousePosition() } if IsKeyPressed(KEY_SPACE) return .clear - fx f32 = 0.0 - fy f32 = 0.0 + fx f32 := 0.0 + fy f32 := 0.0 if IsKeyDown(KEY_A) fx -= FORCE if IsKeyDown(KEY_D) fx += FORCE if IsKeyDown(KEY_W) fy -= FORCE @@ -128,14 +128,14 @@ step func(b @mut Ball) void { draw_ball func(b @Ball, highlight bool) void { col :: color_for(b.kind) - center Vector2 = Vector2{ x = b.x, y = b.y } + center Vector2 := Vector2{ x = b.x, y = b.y } match b.kind { .circle: DrawCircleV(center, b.radius, col) .square: DrawPoly(center, 4, b.radius, 45.0, col) .triangle: DrawPoly(center, 3, b.radius, 0.0, col) } if highlight { - ring Color = Color{ r = 250, g = 245, b = 200, a = 255 } + ring Color := Color{ r = 250, g = 245, b = 200, a = 255 } DrawPoly(center, 24, b.radius + RING_PAD, 0.0, ring) } } @@ -150,11 +150,11 @@ main func() i32 { `[click] spawn a shape [WASD/arrows] blow wind `[space] clear - balls [CAP]mut Ball = undefined - count usize = 0 # number of live balls, in slots 0..count - kc Kind = .circle # next kind to spawn - spin f32 = 1.0 # rotates spawn velocity for variety - at_cap bool = false # show the "at capacity" banner + balls [CAP]mut Ball := undefined + count usize := 0 # number of live balls, in slots 0..count + kc Kind := .circle # next kind to spawn + spin f32 := 1.0 # rotates spawn velocity for variety + at_cap bool := false # show the "at capacity" banner bg :: Color{ r = 24, g = 26, b = 34, a = 255 } text :: Color{ r = 225, g = 225, b = 230, a = 255 } @@ -209,7 +209,7 @@ main func() i32 { # --- which shape is under the cursor? (optional via a value-loop) --- mouse :: GetMousePosition() sel :: for 0..(count) |i| blk: { - c Vector2 = Vector2{ x = balls[i].x, y = balls[i].y } + c Vector2 := Vector2{ x = balls[i].x, y = balls[i].y } if CheckCollisionPointCircle(mouse, c, balls[i].radius) yield :blk i yield null } @@ -220,7 +220,7 @@ main func() i32 { for (&balls) |@b, i| { if (i >= count) break - hot bool = false + hot bool := false if sel |s| { if (s == i) hot = true # true only for the hovered ball } diff --git a/testbed/lexer/main.bro b/testbed/lexer/main.bro index 8a4da60..0648bde 100644 --- a/testbed/lexer/main.bro +++ b/testbed/lexer/main.bro @@ -48,7 +48,7 @@ hide append_token func(tokens @mut std.ArrayList(Token), kind Kind, start, end u } lex func(source []u8, tokens @mut std.ArrayList(Token)) void ! mem.AllocError { - cursor usize = 0 + cursor usize := 0 while cursor < source.len { value u8 :: source[cursor] if value == ' ' or value == '\t' or value == '\r' { @@ -112,7 +112,7 @@ hide print_token func(source []u8, token Token) void { _ = c.printf("%-11s", kind_name(token.kind)) if token.length != 0 { _ = c.printf(" `") - i usize = 0 + i usize := 0 while i < token.length : i += 1 { value u8 :: source[token.start + i] if value == '\n' { @@ -132,7 +132,7 @@ main func() i32 { ` hello() `} - tokens std.ArrayList(Token) = arraylist.init(mem.c_allocator) + tokens std.ArrayList(Token) := arraylist.init(mem.c_allocator) defer arraylist.deinit(&tokens) lex(source, &tokens) catch |_| { diff --git a/testbed/lexer/std/arraylist/arraylist.bro b/testbed/lexer/std/arraylist/arraylist.bro index 93a9cc7..6efb3d8 100644 --- a/testbed/lexer/std/arraylist/arraylist.bro +++ b/testbed/lexer/std/arraylist/arraylist.bro @@ -28,7 +28,7 @@ reserve func($T type, list @mut ArrayList(T), minimum_capacity usize) void ! mem return } - new_capacity usize = 8 + new_capacity usize := 8 if list.capacity >= 8 { half usize :: divtrunc!(list.capacity, 2) if list.capacity > maxval!(usize) - half { diff --git a/testbed/lexer/std/io/io.bro b/testbed/lexer/std/io/io.bro index 68f609c..a38ef13 100644 --- a/testbed/lexer/std/io/io.bro +++ b/testbed/lexer/std/io/io.bro @@ -61,7 +61,7 @@ write func(writer Writer, bytes []u8) usize ! WriteError { } write_all func(writer Writer, bytes []u8) void ! WriteError { - offset usize = 0 + offset usize := 0 while offset < bytes.len { count usize :: write(writer, bytes[offset..]) catch |err| { return err @@ -75,7 +75,7 @@ write_all func(writer Writer, bytes []u8) void ! WriteError { } hide system_read func(_ ?*mut anyopaque, stream ReadStream, buffer []mut u8) usize ! ReadError { - request usize = buffer.len + request usize := buffer.len maximum usize :: usize(maxval!(c_long)) if request > maximum { request = maximum @@ -93,7 +93,7 @@ hide system_read func(_ ?*mut anyopaque, stream ReadStream, buffer []mut u8) usi hide system_write func(_ ?*mut anyopaque, stream WriteStream, bytes []u8) usize ! WriteError { fd c_int :: c_int(stream) - request usize = bytes.len + request usize := bytes.len maximum usize :: usize(maxval!(c_long)) if request > maximum { request = maximum diff --git a/testbed/lexer/std/mem/mem.bro b/testbed/lexer/std/mem/mem.bro index 84bf107..2d91785 100644 --- a/testbed/lexer/std/mem/mem.bro +++ b/testbed/lexer/std/mem/mem.bro @@ -32,7 +32,7 @@ eql func($T type, left, right []T) bool { return false } - i usize = 0 + i usize := 0 while i < left.len : i += 1 { if left[i] != right[i] { return false @@ -41,7 +41,7 @@ eql func($T type, left, right []T) bool { return true } -hide empty_storage [1]mut u64 = [0] +hide empty_storage [1]mut u64 := [0] hide empty_slice func($T type, count usize) []mut T { pointer *mut T :: ptrcast!(T, (&empty_storage).ptr) @@ -65,7 +65,7 @@ alloc func($T type, allocator Allocator, count usize) []mut T ! AllocError { return .out_of_memory } - memory ?*mut u8 = raw_alloc(allocator, count * element_size, alignof!(T)) + memory ?*mut u8 := raw_alloc(allocator, count * element_size, alignof!(T)) if memory |bytes| { pointer *mut T :: ptrcast!(T, bytes) return pointer[..count] @@ -90,13 +90,13 @@ realloc func($T type, allocator Allocator, memory []mut T, new_count usize) []mu return .out_of_memory } - old_memory ?*mut u8 = null - old_size usize = 0 + old_memory ?*mut u8 := null + old_size usize := 0 if memory.len != 0 { old_memory = ptrcast!(u8, memory.ptr) old_size = memory.len * element_size } - resized ?*mut u8 = raw_realloc( + resized ?*mut u8 := raw_realloc( allocator, old_memory, old_size, @@ -123,9 +123,9 @@ hide power_of_two func(value usize) bool { return false } - current usize = value + current usize := value while current > 1 { - half usize = divtrunc!(current, 2) + half usize := divtrunc!(current, 2) if half * 2 != current { return false } @@ -144,8 +144,8 @@ hide c_alloc func(_ ?*mut anyopaque, size usize, alignment usize) ?*mut u8 { return ptrcast!(u8, c.malloc(c_ulong(size))) } - memory [1]mut ?*mut anyopaque = [null] - status c_int = c.posix_memalign((&memory).ptr, c_ulong(alignment), c_ulong(size)) + memory [1]mut ?*mut anyopaque := [null] + status c_int := c.posix_memalign((&memory).ptr, c_ulong(alignment), c_ulong(size)) if status != 0 { return null } @@ -168,13 +168,13 @@ hide c_realloc func(_ ?*mut anyopaque, memory ?*mut u8, old_size usize, new_size return ptrcast!(u8, c.realloc(old_memory, c_ulong(new_size))) } - new_memory ?*mut u8 = c_alloc(null, new_size, alignment) + new_memory ?*mut u8 := c_alloc(null, new_size, alignment) if new_memory |new_bytes| { - copy_size usize = old_size + copy_size usize := old_size if new_size < copy_size { copy_size = new_size } - i usize = 0 + i usize := 0 while i < copy_size : i += 1 { new_bytes[i] = old_memory[i] } diff --git a/testbed/main.bro b/testbed/main.bro index 2f38c86..5c86f71 100644 --- a/testbed/main.bro +++ b/testbed/main.bro @@ -25,7 +25,7 @@ tier_bonus func(tier Tier) i32 { } projected_score func(player Player) i32 { - total i32 = player.score + total i32 := player.score total += tier_bonus(player.tier) if player.active and player.streak > 2 { total += player.streak * 3 @@ -42,8 +42,8 @@ apply_decay func(players []mut Player) void { } best_player func(players []mut Player) ?@mut Player { - best ?@mut Player = null - best_score i32 = 0 + best ?@mut Player := null + best_score i32 := 0 for players |@player| { score :: projected_score(player^) @@ -62,7 +62,7 @@ best_player func(players []mut Player) ?@mut Player { } main func() i32 { - players [4]mut Player = [ + 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 }, Player { id = PlayerID(3), name = "Edsger", tier = .bronze, score = 64, streak = 0, active = false }, diff --git a/testbed/mem_alloc/std/mem/mem.bro b/testbed/mem_alloc/std/mem/mem.bro index de3632f..11fdeaa 100644 --- a/testbed/mem_alloc/std/mem/mem.bro +++ b/testbed/mem_alloc/std/mem/mem.bro @@ -27,7 +27,7 @@ raw_free func(allocator Allocator, memory ?*mut u8, size usize, alignment usize) allocator.vtable.free(allocator.context, memory, size, alignment) } -hide empty_storage [1]mut u64 = [0] +hide empty_storage [1]mut u64 := [0] hide empty_slice func($T type, count usize) []mut T { pointer *mut T :: ptrcast!(T, (&empty_storage).ptr) @@ -47,7 +47,7 @@ alloc func($T type, allocator Allocator, count usize) []mut T ! AllocError { return .out_of_memory } - memory ?*mut u8 = raw_alloc(allocator, count * element_size, alignof!(T)) + memory ?*mut u8 := raw_alloc(allocator, count * element_size, alignof!(T)) if memory |bytes| { pointer *mut T :: ptrcast!(T, bytes) return pointer[..count] @@ -68,9 +68,9 @@ hide power_of_two func(value usize) bool { return false } - current usize = value + current usize := value while current > 1 { - half usize = current / 2 + half usize := current / 2 if half * 2 != current { return false } @@ -89,8 +89,8 @@ hide c_alloc func(_ ?*mut anyopaque, size usize, alignment usize) ?*mut u8 { return ptrcast!(u8, c.malloc(c_ulong(size))) } - memory [1]mut ?*mut anyopaque = [null] - status c_int = c.posix_memalign((&memory).ptr, c_ulong(alignment), c_ulong(size)) + memory [1]mut ?*mut anyopaque := [null] + status c_int := c.posix_memalign((&memory).ptr, c_ulong(alignment), c_ulong(size)) if status != 0 { return null } @@ -113,13 +113,13 @@ hide c_realloc func(_ ?*mut anyopaque, memory ?*mut u8, old_size usize, new_size return ptrcast!(u8, c.realloc(old_memory, c_ulong(new_size))) } - new_memory ?*mut u8 = c_alloc(null, new_size, alignment) + new_memory ?*mut u8 := c_alloc(null, new_size, alignment) if new_memory |new_bytes| { - copy_size usize = old_size + copy_size usize := old_size if new_size < copy_size { copy_size = new_size } - i usize = 0 + i usize := 0 while i < copy_size : i += 1 { new_bytes[i] = old_memory[i] }