Circuits, Holds, Routes, Emits
The building blocks of a Sanguis program.
circuit
A circuit is a body - a named scope containing holds and routes. A program is one or more circuits.
circuit Name {
// holds and routes
}All holds declared inside a circuit are globally accessible by name. Circuits are organizational scope, not isolation.
hold
A hold is a named value. Every hold has a type:
hold name : memory scalar = 0.0 // floating-point number hold name : memory text = "value" // text string hold name : memory scalar // defaults to 0.0 hold name : memory text // defaults to ""
Scalars are stored as floating-point. Text is stored as variable-length strings. There are no other types.
when
A when block defines a route. The route fires every tick if all its but conditions pass. If a route has no but conditions, it fires every tick.
when trigger_name {
but condition
emit value to target
}A route with no conditions always fires. A route with conditions fires only when all conditions are simultaneously true at the start of the tick.
but
A but condition gates a route. Multiple but conditions are ANDed - all must pass for the route to fire.
when process {
but state < 10.0
but active = 1.0
emit state + 1.0 to state
}emit
emit sends a value to a target. When the target is a hold, emit replaces the hold's current value:
emit 42.0 to state // write to a hold (replaces) emit "text" to screen // print to terminal
Multiple emits in a route execute in order within the route. Emits are applied immediately, subsequent emits in the same route see updated values.
| Target | Behavior |
|---|---|
| screen | Print the value to terminal output |
| Hold name | Write the value to the named hold (replace) |
append
append accumulates text into a text hold. Unlike emit (which replaces), append concatenates after existing content:
append "Hello, " to out // out = "Hello, " append "World!" to out // out = "Hello, World!" append "\n" to out // out = "Hello, World!\n"
Strings build incrementally across routes this way.
through
through iterates through a text hold, one character per tick. Each tick the route fires, the char hold is set to the next character in the text, and the position advances.
circuit Reader {
hold src : memory text = "Hello"
hold state : memory scalar = 0.0
when scan {
but state = 0.0
through src
emit char to screen
}
}This prints each character of src one per tick: H, e, l, l, o.
The char hold is automatically created and managed by the engine. The through position is internal to the route and advances each tick the route fires.
memory
memory is the layer type for holds. Every hold uses memory to declare that it persists its value across ticks:
hold name : memory scalar = 0.0 // persistent scalar hold name : memory text = "value" // persistent text
All holds are memory layer. The hold retains its value from tick to tick until a route emits or appends a new value to it.
wire
wire connects a hold in one circuit to a hold in another, creating a connectome link:
wire Body.sense to Brain.think
Wires can be declared at the top level or inside a circuit. A wire routes data from the source hold to the target hold every tick. Circuits communicate this way. The organism is a network of circuits wired together.