Froth, and this site, are pre-alpha. This site is largely OSAI-generated documentation from the Froth repo.

This example shows the intended project shape: one narrow binding in C, one [ffi] declaration in froth.toml, and ordinary Froth code above it.

Project Layout

my-project/
  froth.toml
  src/
    main.froth
    ffi/
      bindings.c

Manifest

[project]
name = "ffi-demo"
entry = "src/main.froth"

[target]
board = "posix"
platform = "posix"

[ffi]
sources = ["src/ffi/bindings.c"]
includes = ["src/ffi"]
defines = { SCALE = "2" }

src/ffi/bindings.c

#include "froth_ffi.h"

#ifndef SCALE
#define SCALE 2
#endif

static const froth_ffi_param_t scale_twice_params[] = {
    FROTH_FFI_PARAM_INT("value"),
};

static froth_error_t scale_twice(froth_runtime_t *runtime,
                                 const void *context,
                                 const froth_value_t *args,
                                 size_t arg_count,
                                 froth_value_t *out) {
  int32_t value = 0;

  (void)runtime;
  (void)context;
  (void)arg_count;
  FROTH_TRY(froth_ffi_expect_int(args, 0, &value));
  return froth_ffi_return_int(value * SCALE, out);
}

const froth_ffi_entry_t froth_project_bindings[] = {
    {
        .name = "scale.twice",
        .params = scale_twice_params,
        .param_count = FROTH_FFI_PARAM_COUNT(scale_twice_params),
        .arity = 1,
        .result_type = FROTH_FFI_VALUE_INT,
        .help = "Multiply a value by the configured SCALE factor.",
        .flags = FROTH_FFI_FLAG_NONE,
        .callback = scale_twice,
        .stack_effect = "( value -- value )",
    },
    {0},
};

src/main.froth

to clipped-sensor with n
  set scaled = scale.twice: n
  if scaled < 0 [ 0 ]
  else if scaled > 100 [ 100 ]
  else [ scaled ]
end

to boot
  clipped-sensor: 60
end

Build the firmware after changing C:

froth build

Send Froth source after changing only the high-level program:

froth send

That split is the point of project FFI: C is for the narrow binary edge; Froth is where the program stays live and reshapeable.