Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Variable Declarations

VarDecl ::= ident ':' Type ';'
Type    ::= BaseType ('[' ArrayLen ']')?
BaseType ::= PrimitiveType | StructName

A variable declaration introduces one named value at PD-global scope or inside an event body. The ident: Type; form is the only shape supported today; an initialiser (ident: Type = expr;) is reserved but not yet parsed.

🚧 Initialiser syntax (= expr) is reserved but unparsed — see #105. For now, initialise locals from inside the body, and globals from the imported source’s init() function (see Boot Initialisation).

Scopes

Variables can appear in two positions inside a .fi file:

  • Global — at the top level of the file, alongside Mapping and import declarations. Globals are visible everywhere in the PD, read/write inside event bodies.
  • Local — inside a computation event body. Locals shadow globals of the same name. Their scope ends where the enclosing event’s body ends — implicitly, at the next top-level item (evt, proc, import, Mapping), since there is no explicit terminator keyword.

Process bodies cannot declare variables; any state needed by guards or process expressions must be promoted to a global.

The full scope-resolution order inside an event body is:

local → carrier → global

Carriers are the read-only inputs declared in the event header — see Event Declarations.

Primitive types

The primitive types accepted in declarations are:

GroupTokens
Signed integersint, int8, int16, int32, int64
Unsigned integersuint, uint8, uint16, uint32, uint64
Booleanbool
Byte aliasbyte (8-bit)
AddressAddress

int and uint without a width default to 32-bit. byte is an alias for uint8. There is no void type — every declared variable has a concrete, storable type.

Struct types and arrays

pkt: Slot           // user-defined struct — declared in the .fis data layer
buf: uint8[16]       // fixed-size array — length is a literal or const name

Any identifier that isn’t a recognised primitive keyword is treated as a struct type name, resolved against the .fis struct declarations during name resolution (unknown names are rejected there, not at parse time). Fiducia has no pointer types — there is no ptr<T> syntax.

Examples

// Global declarations, top of a .fi file.
counter: int;
ready: bool;
last_irq_ts: uint64;

// Local declarations inside an event body.
evt handle_packet.|size: int|:
    local_buf: uint8[64];     // local
    ok: bool;                 // local
    local_buf = eth.alloc();  // assignment uses globals/locals/carriers

Validation

  • A variable name is unique within its enclosing scope (multiple globals with the same name are rejected; a local may legally shadow a global).
  • The type must be a recognised primitive, Address, a fixed-size array of one, or a struct name that resolves to a real .fis struct declaration.