Expressions
This chapter describes the expression grammar designed for Fiducia and the subset that todayβs parser actually accepts. Expressions appear as:
- the right-hand side of assignments inside event bodies and the constructor block;
- the payload of a channel send (
c!e); - the body of a guard (
[b]); - arguments to sub-process calls and computation-event references.
The grammar is divided into four sub-languages: arithmetic (integer- valued), logical (boolean / relational), boolean (lifted), and call expressions. Only call expressions are fully implemented today. The others are flagged π§ below.
Expr ::= AExpr | LExpr | BExpr | CExpr
Call expressions (CExpr)
CExpr ::= ident '.' ident '(' (Expr (',' Expr)*)? ')'
A call expression invokes a function defined in an imported .c /
.rs file, prefixed with the import alias chosen at the
import declaration. The alias
is required β there are no local callables in Fiducia, only
externally-implemented functions reached through an alias.
The first ident is the alias; the second is the function name. No
whitespace is permitted around the . or before the (:
eth.send_frame() // OK
drv.start() // OK
drv .start() // rejected β whitespace before '.'
drv. start() // rejected β whitespace after '.'
drv.start () // rejected β whitespace before '('
Argument lists
Argument parsing is currently a stub: the parser accepts an empty (...)
argument list and stores Vec::new() for the args. Once the rest of the
expression grammar lands, arguments will be Vec<Expr> and the call site
shape (eth.send_frame(pkt)) will parse as expected.
π§ Argument parsing for call expressions is gated on the broader expression grammar β see #105. Today, only
()is accepted; calls with arguments parse only inside places that do their own identifier-list handling (sub-process calls, computation-event carriers).
Arithmetic expressions (AExpr)
π§ Not yet implemented β see #105.
The designed grammar covers integer literals, variables, unary negation, and the standard binary arithmetic operators (
+,-,*,/,%). Until the grammar lands, integer values appear in source only as literals at fixed positions (IRQ numbers, page sizes, sizes / phys-addrs inMemoryRegion).
Logical expressions (LExpr)
π§ Not yet implemented β see #105.
The designed grammar covers comparison (
==,!=,<,<=,>,>=) and boolean composition (&&,||,!). Until the grammar lands, guards accept only[var]and[!var].
Boolean expressions (BExpr)
π§ Not yet implemented β see #105.
A lifted boolean form for use as a payload type, distinct from
LExprwhich composes other relations. Likely to merge intoLExprin the final grammar β tracked under #105.
Stand-ins for unimplemented forms
Where the grammar currently lacks a construct, the surrounding parser accepts a narrow stand-in so existing fixtures continue to parse:
| Position | Stand-in accepted |
|---|---|
MemoryRegion size / page / phys | hex literal only |
Mapping vaddr | hex literal only |
c!e send payload | identifier |
irq?N / irq!N IRQ number | integer literal |
| Computation-event carrier args | identifier |
| Sub-process call args | identifier |
| Constructor RHS | mapping.field or opaque text to ; |
| Guard expression | var or !var |
These accept-narrow / reject-everything-else windows keep the parser
honest: every position where an expression should go either has a
fully-typed Expr (via CExpr) today, or accepts a clearly-restricted
shape that surfaces an error if you reach for an un-implemented form.