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’sinit()function (see Boot Initialisation).
Scopes
Variables can appear in three positions inside a .fi file:
- Global — at the top level of the file, alongside
Mappingandimportdeclarations. Globals are visible everywhere in the PD, read/write inside event bodies. - Event local — inside a computation event body, from its declaration to the end of the event (the next top-level item, since there is no explicit terminator keyword).
- Process variable — inside a process body: a
parameter (
proc Drain(pkt: Slot), read-only, in scope for the whole body), a declarationx: T;(in scope for the rest of its sequence), or a receive binderc?x(in scope for the rest of its prefix).
A name in a body is looked up among that body’s own variables first, then the program’s globals, then the system’s constants:
body variable → global → constant
Event and process variables never see each other: a process value reaches an event only as a carrier. Shadowing a global, a mapping or a constant is a warning; declaring a name twice in one body while the first is still in scope is an error. Carriers are read-only — see Event Declarations.
Primitive types
The primitive types accepted in declarations are:
| Group | Tokens |
|---|---|
| Signed integers | int, int8, int16, int32, int64 |
| Unsigned integers | uint, uint8, uint16, uint32, uint64 |
| Boolean | bool |
| Byte alias | byte (8-bit) |
| Address | Address |
int and uint are aliases of int64 and uint64 on every target.
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 body variable may shadow a global, with a warning).
- The type must be a recognised primitive,
Address, a fixed-size array of one, or a struct name that resolves to a real.fisstruct declaration.