# language features This file is the compact current-state ledger. `TODO.md` remains the detailed roadmap and milestone history. ## IMPLEMENTED ### source, declarations, and packages - newline-terminated statements and `#` comments - immutable `::` bindings, typed mutable `=` locals/globals, and `_` sinks - immutable package globals, mutable runtime globals, function-local mutable locals, and mutable local declarations initialized with `undefined` - package-level functions, globals, native type declarations, and `Name :: alias T` - directory packages with merged declarations - file-local relative imports, import aliases, and qualified member access - transparent declaration aliases with `Name :: alias package.Member`; functions/type factories, named types, and globals retain their original declaration or storage identity - native top-level declarations beginning with `_` are visible only within their source file; locals, fields, parameters, and C declarations are unaffected - relative `.h` imports as synthetic C header package namespaces - root `main` validation with trap executable recovery for missing or unusable entry points ### scalar, aggregate, and pointer types - exact-width integers, `isize`, `usize`, `f32`, `f64`, `bool`, `void`, `anyopaque`, and contextual `int`, `float`, and `range` constraints - target-dependent C scalar primitives from `c_char` through `c_longdouble`, kept semantically distinct from native scalars - contextual integer/float/character literals, backward type-demand inference through names and arithmetic, and compile-time folding for numeric constant expressions - strict numeric conversion by default, widening where valid, C scalar coercions at C boundaries, and explicit scalar keyword casts such as `i32(x)` / `c_float(x)` - compile-time `min_value(T)` and `max_value(T)` bounds for concrete native and C integer scalar types - arrays `[N]T`, inferred-count arrays `[_]T`, sentinel arrays `[N;S]T`, compile-time expression array counts, slices `[]T` / `[;S]T`, single-item pointers `@T`, many-item pointers `*T`, and sentinel many-item pointers `[*;S]T` - pointer mutability via `mut`, optional pointers as nullable pointers, pointer arithmetic for many-item pointers, postfix dereference `^`, and trapping optional unwrap `?` - pointer-to-array `.len`, indexing, slicing, `.ptr` on slices and pointers-to-arrays, implicit address-taking for array-variable slices, and pointer/slice sentinel weakening - `ptr_cast(T, ptr)` as a first-pass pointer-child retype that preserves optionality, pointer kind, mutability, and sentinel shape - UTF-8 string literals as immutable pointers to static zero-terminated byte arrays, plus raw backtick multiline strings - narrow immutable zero-terminated byte pointer/slice conversion to `*c_char` / `?*c_char` without general `u8`/`c_char` interchange - optionals with `none`, `orelse`, postfix `?`, conditional unwraps, guarded unwraps, and left-to-right short-circuiting multi-unwraps - nominal distinct types with exact backing construction, native enums with optional explicit integer backing and explicit backing-to-scalar casts, contextual enum literals, and imported C enums as target-backed integer aliases - source-order native structs, opaque nominal records with `Name :: opaque`, complete `c_struct { ... }`, keyed record literals, native untagged unions, and native tagged unions `union(Enum)` / `union(enum)` - void-payload tagged-union variants, anonymous struct payloads, contextual `.variant`, `.variant{payload}`, and `.variant{field = value}` construction - native sum composition with `A | B` for unbacked enums and tagged unions, using program-global `u16` variant ids - fallible channel types `T ! E`, where `E` is a native enum/tagged union or supported sum composition ### expressions and control flow - checked integer `+ - *`, unary `-`, float-only `/`, IEEE float arithmetic, comparisons, `!`, `and`, and `or` - assignments and compound assignments `+= -= *= /=` with single evaluation of complex lvalues; `/=` is float-only - field access through struct values and pointers, index/slice bounds contextually coerced to `usize`, and unsigned narrower index support - boolean `if` / `else if` / `else`, braceless single-statement branches, and optional parenthesized conditions - `while` loops with optional post-iteration update clauses - `for` loops over ranges, arrays, slices, and pointers-to-arrays with copy captures, pointer captures `|@item|`, and optional `usize` index captures - `break`, `continue`, labeled `break :label`, labeled `continue :label`, and labeled plain blocks - bare block scopes and `defer`, including LIFO flushing on fall-through, `return`, `break`, and `continue` - value blocks, value `if`, value loops, value `match`, `yield`, and labeled `yield :label value` - `match` statements/expressions over enums, tagged unions, and scalars, including exhaustiveness checks, payload captures, pointer payload captures, multi-pattern arms, and scalar range patterns - fallible `try`, fallback `catch`, and `catch |e| { ... }` handler blocks - direct `return match ...` and `yield match ...` value-control-flow operands #### division `/` and `/=` accept only floating-point operands. Integer division must state its rounding and remainder convention with one of these unqualified builtins: | Builtin | Result | | --- | --- | | `div_trunc(a, b)` | quotient rounded toward zero | | `div_floor(a, b)` | quotient rounded toward negative infinity | | `div_exact(a, b)` | truncated quotient; traps unless it divides exactly | | `div_ceil(a, b)` | quotient rounded toward positive infinity | | `rem(a, b)` | remainder paired with `div_trunc`; sign follows `a` | | `mod(a, b)` | modulus paired with `div_floor`; sign follows `b` | The operands may be compatible concrete integer or float scalars. Existing literal coercion and numeric widening rules apply, the result has the common operand type, and float quotients are integral-valued floats. These identities hold when representable: ```bro div_trunc(a, b) * b + rem(a, b) == a div_floor(a, b) * b + mod(a, b) == a ``` Negative operands distinguish the operations: ```bro div_trunc(-5, 3) == -1 div_floor(-5, 3) == -2 div_ceil(-5, 3) == -1 rem(-5, 3) == -2 mod(-5, 3) == 1 mod(5, -3) == -1 ``` All six builtins diagnose a zero denominator at comptime and trap at runtime, including float zero. Quotient operations also trap for signed `min_value(T), -1`; `rem` and `mod` return zero for that pair. `div_exact` traps when `div_trunc(a, b) * b == a` is false in the operand type, so float exactness follows floating-point equality. Other float NaN and infinity behavior follows the underlying IEEE operations. Ordinary float `/` remains unchecked and therefore preserves IEEE infinity/NaN behavior. The six spellings are reserved only as direct unqualified calls. A qualified call such as `math.div_floor(a, b)` resolves to an ordinary package function. ### functions, C interop, and linking - demand-monomorphized Brolang and C-ABI functions - integer comptime value parameters such as `make_array func($N usize) [N]u8`, specialized by value and omitted from the runtime ABI - explicit comptime type parameters such as `max func($T type, a, b T) T`, specialized by type and omitted from the runtime ABI - leading comptime type/integer parameters may be omitted when uniquely recoverable from runtime argument types or the immediate expected result; explicit calls remain valid - comptime parameters must form one leading prefix before all runtime parameters - forced typed comptime expressions such as `$sum(1, 2)`, `$Point { x = 1, y = 2 }`, and comptime value blocks such as `${ yield 4 }` - comptime execution for bodyful Brolang functions with mutable locals, loops, `defer`, `match`, `try`/`catch`, pointer/slice storage mutation, pointer captures, and calls through comptime-known function values - comptime type factories such as `Box func($T type) type { return struct { value T } }`; calls like `Box(i32)` are concrete nominal types and may appear anywhere a type is expected - bodyful `c_func` definitions and bodyless `c_func` declarations with exact external symbol names - concrete-only C signatures, C variadic declarations/calls, and C default argument promotions - native function pointer values and types with `@func(...) R`, fallible `@func(...) R ! E`, optional `?@func(...) R`, and non-variadic native indirect calls - Apple Silicon C ABI lowering for scalars, pointers, fixed-signature plain records/unions, small aggregates, homogeneous float aggregates, and indirect aggregate returns - imported C typedefs, scalar constants, enum constants, fixed arrays, complete plain structs/unions, C `void*` as nullable `anyopaque` pointers, and pointers to opaque records - imported external C object variables, including mutable variables and immutable object globals - object-like scalar and plain record/union macro constants - supported static inline C functions through generated external wrappers - C function pointer types, imported nullable callback typedefs, concrete `c_func` callback values, and postfix calls through non-null function pointers - `brolang translate-c ` for native `.bro` bindings from supported C declarations - `brolang --translate-c stdio.h` for offline bindings from Zig-bundled standard C headers - ordered linking of additional C sources, objects, archives, library paths, and libraries through compiler CLI options ### standard packages - root `std` re-exports `ArrayList(T)` while its operations remain in `std/arraylist` - `std/mem` generic slice equality, allocator contract with raw byte operations, typed `empty` / `alloc` / `realloc` / `free`, overflow checks, zero-sized-type support, and failure-preserving reallocation - `std/arraylist` generic `ArrayList(T)` with direct `items` slice access, explicit capacity, allocator ownership, fallible reserve/append, clear, and deinit - `std/io` explicit `Io` capabilities, `Reader`/`Writer` stream values, one-shot `read`/`write`, and allocation-free `write_all` ### compiler behavior - error-tolerant compilation with diagnostics and runtime traps where recovery is possible - lazy semantic checking of demanded function specializations - static, eager runtime, mutable runtime, and deferred problematic globals with cycle diagnostics - demand-driven LLVM declarations for referenced foreign functions - root `main` may be parameterless or accept the canonical `@std/io Io`; the injected form is called through a synthesized no-argument C entry point - replaceable dynamically loaded libclang C-import backend - C-header import caching by canonical path, target, include paths, and defines ## PLANNED / DEFERRED - aggregate comptime parameters and stable aggregate specialization keys - tuples and native Brolang variadic functions - exporting Brolang functions to C and broader target-specific C ABI lowering - non-plain C record layouts such as bitfields, packed records, flexible arrays, qualified fields, and C variadic record arguments - arenas, pools, build-mode heap policy, and escaping-allocation diagnostics - recursive type factories, type reflection, and type-producing unions/enums - broader Zig-style pointer/result casts beyond V1 `ptr_cast(T, ptr)` - sum-type ABI/layout polish, including dynamic tag-width shrinking, all-void channel collapse, and cross-module global-id determinism - backed/C enum composition and must-consume fallible linting - result-to-argument type-demand propagation through function call boundaries - distinct-type backing operators and reverse explicit conversions - string concatenation operator