FFI
Frothy’s FFI is intentionally narrow. It exists to expose hardware and native services without collapsing the language into raw C.
Boundary Shape
foreign bindings as top-level Code values (FFI)
Layer: FFI
Behavior: Foreign bindings are exposed as ordinary top-level base-image Code
values and are called with normal Frothy syntax.
Example:
gpio.write: LED_BUILTIN, 1
ms: 250
adc.read: A0
allowed value classes (FFI)
Layer: FFI
Behavior: The first boundary is defined around Int, Bool, Nil, and
Text, with cells handles allowed where the shim stays clear. Raw pointers and
general foreign handles are not user-facing language values.
Example:
An FFI call may return an integer uptime, a boolean pin state, nil, or a text value. It must not expose a raw pointer as an ordinary Frothy value.
Project and Board Paths
project FFI via froth.toml (FFI)
Layer: FFI
Behavior: Project-local native extensions are declared in froth.toml and
compiled into the selected build.
Example:
[ffi]
sources = ["src/ffi/bindings.c"]
includes = ["src/ffi"]
board FFI (FFI)
Layer: FFI
Behavior: Board directories define the native board surface and the board base
library. Frothy then filters and publishes the subset that becomes part of the
maintained public surface.
Example:
`boards/<board>/ffi.c`, `ffi.h`, `board.json`, and `lib/base.frothy` together define the board path.
Persistence Boundary
native runtime state does not persist (FFI)
Layer: FFI
Behavior: Frothy persists the overlay image, not the native runtime state
behind FFI calls. This is a hard part of the boundary, not an implementation
accident.
Example:
Saving the image preserves your top-level overlay, not the internal C state of a device driver.