translate-c file emission

This commit is contained in:
2026-06-24 22:53:20 +02:00
parent f6fc25a899
commit 4cb0ad7f25
7 changed files with 512 additions and 4 deletions
+19 -4
View File
@@ -151,11 +151,26 @@
- array rvalues (e.g. a by-value array return) are materialized into a
temporary before slicing, matching the for-loop iterable lowering
11. c header imports and automatic native brolang bindings (implemented)
- `brolang translate-c <header.h> [--target ...] [--c-include-path ...] [--c-define ...]`
prints native `.bro` bindings for a C header to stdout (the offline counterpart of the
in-memory `native :: import "x.h"`); reuses the libclang `cimport.Result`
- emitter lives in `compiler/translatec`; `render_type` mirrors `loader.translate_c_type`
one-to-one so emitted source re-parses to identical types (guarded by a round-trip test)
- added a native type-alias declaration `Name :: alias T` (parser/lexer/token surface; the
`types.define_alias` / `.Alias` machinery already existed) so C typedefs and callback
typedefs round-trip
- emits functions, complete/opaque structs (collapsing `typedef struct {...} Foo`),
typedef aliases, and scalar/aggregate/enum-member constants
- C unions, external variables, static-inline functions, and unsupported declarations have
no hand-writable spelling and are emitted as `# unsupported in bindings:` comments
(functions that reference an un-spellable union therefore keep a dangling reference)
## A word on multi-unwrap
Unwrap multiple optionals with `and`. This **short-circuits**: if the first optional is none, subsequent expressions are not evaluated.
```honey
```
name: ?[]u8 = get_name()
age: ?u8 = get_age()
if name and age |n, a| {
@@ -166,7 +181,7 @@ if name and age |n, a| {
**With guard clause on multiple values:**
```honey
```
if name and hat |n, h : n == "Huginn" and h.brand == .gucci| {
print("{s}'s got that drip\n", {n})
}
@@ -174,7 +189,7 @@ if name and hat |n, h : n == "Huginn" and h.brand == .gucci| {
Parentheses around the expression are optional, but can aid readability when combined with guards:
```honey
```
# without parentheses
if name and hat |n, h : guard| { ... }
@@ -186,7 +201,7 @@ if (name and hat) |n, h : guard| { ... }
The `and` in multi-unwrap short-circuits left-to-right:
```honey
```
if get_name() and get_hat() |n, h| {
# get_hat() is only called if get_name() returned non-none
}