layout
This commit is contained in:
40
specs.md
40
specs.md
@@ -148,6 +148,18 @@ if s == {
|
||||
}
|
||||
```
|
||||
|
||||
#### Payload Capture
|
||||
Match arms can capture the variant's payload into a local variable:
|
||||
```sx
|
||||
if s == {
|
||||
case .circle: (radius) { print("radius: {}\n", radius); }
|
||||
case .rect: (size) => print("size: {}\n", size);
|
||||
}
|
||||
```
|
||||
The `(name)` after the colon binds the payload. Two forms:
|
||||
- Block: `case .variant: (name) { body }`
|
||||
- Short: `case .variant: (name) => expr;`
|
||||
|
||||
#### Enum Interpolation
|
||||
Payload-less enums print as `.variant`. Enums with payloads print as `.variant(value)` or `<TypeName tag=N>`:
|
||||
```sx
|
||||
@@ -568,6 +580,33 @@ Syntax: `Name :: enum [flags] [type] { ... }`
|
||||
|
||||
The backing type must be an integer type (`u8`, `u16`, `u32`, `s8`, `s16`, `s32`, `s64`, etc.). When omitted, the default is `s64`. This is useful for C interop (matching C enum sizes) and memory efficiency.
|
||||
|
||||
### Enum Layout Struct
|
||||
|
||||
For C interop with tagged unions (e.g. SDL_Event), a struct can be used as the backing type to specify the exact memory layout:
|
||||
|
||||
```sx
|
||||
// Inline layout
|
||||
SDL_Event :: enum struct { tag: u32; _: u32; payload: [30]u32; } {
|
||||
quit :: 0x100;
|
||||
key_down :: 0x300: SDL_KeyData;
|
||||
key_up :: 0x301: SDL_KeyData;
|
||||
}
|
||||
|
||||
// Named layout
|
||||
EventLayout :: struct { tag: u32; _: u32; payload: [30]u32; }
|
||||
SDL_Event :: enum EventLayout {
|
||||
quit :: 0x100;
|
||||
key_down :: 0x300: SDL_KeyData;
|
||||
}
|
||||
```
|
||||
|
||||
The layout struct must have:
|
||||
- A field named `tag` — integer type, the discriminant. Its type becomes the enum's backing type.
|
||||
- A field named `payload` — array type, the variant data area. Its size determines the maximum payload capacity.
|
||||
- Any other fields are treated as padding/reserved and positioned by the struct layout.
|
||||
|
||||
This gives explicit control over the memory layout instead of relying on automatic alignment. The total size equals the struct size. Without a layout struct, tagged enums use `{ tag, [max_payload_size x i8] }` with no padding.
|
||||
|
||||
### Enum Flags
|
||||
|
||||
```sx
|
||||
@@ -882,6 +921,7 @@ Built-in functions are declared in `std.sx` with the `#builtin` suffix, which te
|
||||
- `field_count($T: Type) -> s64` — returns the number of fields (struct), variants (enum), or elements (vector) in type `T`
|
||||
- `field_name($T: Type, idx: s64) -> string` — returns the name of the `idx`-th field (struct) or variant (enum) of type `T`
|
||||
- `field_value(s: $T, idx: s64) -> Any` — returns the `idx`-th field (struct) or element (vector) of `s`, boxed as `Any`
|
||||
- `field_index($T: Type, val: T) -> s64` — returns the sequential variant index for an explicit enum value (reverse of `field_value_int`). Returns `-1` if no variant matches.
|
||||
|
||||
### Type Conversion
|
||||
- `cast(Type) expr` — prefix operator that converts `expr` to `Type`. Examples: `cast(s32) 3.14`, `cast(f64) n`. When `Type` is a runtime `Type` value inside a type-category match arm, the compiler generates a dispatch switch over all types in the category, monomorphizing the callee for each concrete type.
|
||||
|
||||
Reference in New Issue
Block a user