Type System

Eä is statically typed with no implicit conversions. Every variable, parameter, and expression has a concrete type known at compile time.

Scalar Types

TypeSizeDescription
i81 byteSigned 8-bit integer
u81 byteUnsigned 8-bit integer
i162 bytesSigned 16-bit integer
u162 bytesUnsigned 16-bit integer
i324 bytesSigned 32-bit integer
u324 bytesUnsigned 32-bit integer
i648 bytesSigned 64-bit integer
u648 bytesUnsigned 64-bit integer
f324 bytes32-bit float (IEEE 754)
f648 bytes64-bit float (IEEE 754)
bool1 byteBoolean (true or false)

Integer literals default to i32. Float literals default to f32. Use explicit casts (to_f64(x), to_i64(x)) to convert between types.

Vector Types

Vector types hold multiple lanes of the same scalar type. Element-wise operations use dot-operators (.+, .-, .*, ./, etc.).

128-bit Vectors -- SSE (x86) / NEON (ARM)

TypeLanesElementSize
f32x44f3216 bytes
f64x22f6416 bytes
i32x44i3216 bytes
u32x44u3216 bytes
i16x88i1616 bytes
u16x88u1616 bytes
i8x1616i816 bytes
u8x1616u816 bytes
u64x22u6416 bytes

256-bit Vectors -- AVX2 (x86 only)

TypeLanesElementSize
f32x88f3232 bytes
f64x44f6432 bytes
i32x88i3232 bytes
i16x1616i1632 bytes
u16x1616u1632 bytes
i8x3232i832 bytes
u8x3232u832 bytes
u64x44u6432 bytes

These types produce a compile error on ARM targets.

512-bit Vectors -- AVX-512 (x86, --avx512 flag required)

f32x16, f64x8, i32x16, and u64x8 lower to AVX-512F instructions. i8x64, u8x64, i16x32, and u16x32 additionally require AVX-512BW (byte/word SIMD), which is present on Skylake-SP, Ice Lake, Zen 4, and later. Eä emits both feature flags when --avx512 is set.

TypeLanesElementSizeFeature
f32x1616f3264 bytesAVX-512F
f64x88f6464 bytesAVX-512F
i32x1616i3264 bytesAVX-512F
u64x88u6464 bytesAVX-512F
i16x3232i1664 bytesAVX-512BW
u16x3232u1664 bytesAVX-512BW
i8x6464i864 bytesAVX-512BW
u8x6464u864 bytesAVX-512BW

Using these types without --avx512 produces a compile error.

Half-precision and sub-128-bit narrow widths

The lexer also accepts f16x4 / f16x8 (half-precision float vectors) and sub-128-bit narrow widths used by ARM NEON widening intrinsics: i8x4, i8x8, u8x8, i16x4, u16x4, i32x2. These have target-specific constraints (f16 requires --fp16 on aarch64 and is unavailable on plain x86; the narrow widths exist primarily as inputs to widening multiplies like wmul_i32(i16x4, i16x4) -> i32x4) that are documented alongside the intrinsics that consume them rather than as standalone table rows. See ARM / NEON reference for f16 and All Intrinsics for the narrow-width consumers.

Pointer Types

Pointers represent caller-provided memory. Eä never allocates -- all memory comes from the host language.

SyntaxDescription
*TImmutable pointer to T
*mut TMutable pointer to T
*restrict TImmutable pointer, no-alias guarantee
*restrict mut TMutable pointer, no-alias guarantee

The restrict qualifier tells the compiler that the pointer does not alias other pointers, enabling stronger optimizations. Use it when you can guarantee non-overlapping memory.

Struct Types

User-defined value types declared with struct:

struct Pixel {
    r: f32,
    g: f32,
    b: f32,
    a: f32,
}

Structs are passed by value. Access fields with dot syntax: pixel.r. Structs can contain scalar types, vector types, and other structs.

Type Rules

  • No implicit conversions between types. Use to_f32(), to_i32(), etc.
  • No generics or polymorphism. Write separate functions for each type.
  • Vector dot-operators require both operands to have the same vector type.
  • Comparisons on vectors (.==, .<, .>) produce boolean vectors, not scalar bools.