Files
brolang/README.md
T
2026-06-23 18:24:35 +02:00

112 lines
4.3 KiB
Markdown

# brolang
Prototype error-tolerant Brolang compiler written in Odin.
```sh
mkdir -p build
odin build . -out:build/brolang
./build/brolang examples/programs/prototype -o build/prototype
./build/prototype
```
Bodyless `c_func` declarations bind exact external symbols and require concrete
types. C primitives use atomic target-dependent names and remain semantically
distinct from exact-width Brolang primitives:
```bro
strlen :: c_func(value *c_char) c_ulong
```
Additional native inputs and libraries are passed to the final `zig cc`
invocation in command-line order:
```sh
./build/brolang examples/interop/manual -o build/manual \
--c-link examples/interop/manual/native.c
```
`--c-link` accepts C sources, object files, archives, and direct library paths.
`--c-library-path <dir>` becomes `-L<dir>`, and `--c-library <name>` becomes
`-l<name>`. `--c-include-path <dir>` and `--c-define <name[=value]>` configure
C preprocessing.
Relative `.h` imports create synthetic package namespaces backed by libclang:
```bro
native :: import "../include/native.h"
main :: func() void {
_ = native.imported_add(20, 22)
}
```
Header imports expose supported external functions, typedefs, C scalars, and
pointers to opaque records. They never add linker inputs; implementations must
still be supplied explicitly with the C-prefixed linking options. Set
`BROLANG_LIBCLANG_PATH` when libclang is not installed in a standard location.
Bodyless manual and imported C functions may be variadic:
```bro
log_values :: c_func(tag c_int, ...) c_int
```
Arguments after `...` accept concrete scalars, pointers, and nullable pointers.
Narrow integers are promoted to the target C `int` or `unsigned int`, and
`f32`/`c_float` are promoted to `c_double`. Arrays, slices, structs, and other
compound values must be converted to an explicit C-compatible representation
before the call.
Compilation phases are isolated under `compiler/`:
```text
package loader -> per-file lexer/parser/AST -> checker/HIR -> lower/IR -> opt -> LLVM -> zig cc
```
Source diagnostics do not block executable generation. When recovery is
possible, invalid code lowers to runtime diagnostic traps and the compiler
returns status `1`. Infrastructure or backend failures return status `2`.
Top-level function bodies are semantically checked lazily when a concrete
specialization is demanded.
Every immediate `.bro` file in the input directory belongs to the root
package. Imports are relative directory paths and are local to the file that
declares them:
```bro
import "../math"
other_math :: import "../math"
value :: math.sum(other_math.value, 1)
```
Current prototype features:
- Newline-terminated, multiline statements; `}` may terminate a block's final statement
- `#` comments
- Immutable `::` bindings, mutable function-local `=` bindings, and `_` sinks
- Exact-width signed/unsigned integers, `f32`, `f64`, `isize`, `usize`, and loose integer-constrained `int`
- Target-dependent atomic `c_*` primitive types, `c_func`, and pointer-only `c_struct`
- Arrays, sentinel arrays, pointers, slices, sentinel slices, strings, character literals, optionals, and native structs
- Explicit `.ptr`/`.len`, slicing, postfix pointer dereference and optional unwrap, and keyed struct literals
- Contextual integer constants and compile-time folding of addition and unary negation trees
- Directory packages with merged declarations and file-local relative imports
- Relative C header imports as synthetic package namespaces
- Qualified imported globals and functions with package-aware symbol mangling
- Demand-monomorphized Brolang and C-ABI functions
- Bodyless concrete C function declarations with exact external symbol names
- Bodyless manual and imported C variadic declarations with default argument promotions
- Ordered linking of additional C sources, objects, archives, and libraries
- Checked signed addition and unary negation
- Static, eager runtime, and deferred problematic globals
- Runtime diagnostics followed by `llvm.trap`
See [LANGUAGE.md](LANGUAGE.md) for the concise implemented and planned language
feature ledger, and [TODO.md](TODO.md) for the implementation roadmap.
Compiler exit statuses:
- `0`: executable produced without source diagnostics
- `1`: executable produced with source diagnostics and embedded traps
- `2`: executable could not be produced