Memory block
pyrung.core.memory_block
Block-based memory regions and indirect addressing.
Block provides factory methods for creating Tags from typed memory regions. IndirectRef enables pointer/indirect addressing resolved at runtime. BlockRange represents contiguous ranges for block operations.
SlotConfig
dataclass
Effective runtime policy for one block slot.
Block
dataclass
Factory for creating Tags from a typed memory region.
Block defines a named, 1-indexed memory region where every address shares
the same TagType. Indexing a Block returns a cached LiveTag. The block
holds no runtime values — all values live in SystemState.tags.
Address bounds are inclusive on both ends: Block("DS", INT, 1, 100)
defines addresses 1–100 (100 tags). Indexing outside this range raises
IndexError. Slice syntax (block[1:10]) is rejected — use
.select(start, end) instead.
For sparse blocks (e.g. Click X/Y banks with non-contiguous valid addresses),
pass valid_ranges to restrict which addresses within [start, end] are
legal.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Block prefix used to generate tag names (e.g. |
required |
type
|
TagType
|
|
required |
start
|
int
|
Inclusive lower bound address (must be ≥ 0). |
required |
end
|
int
|
Inclusive upper bound address (must be ≥ start). |
required |
retentive
|
bool
|
Whether tags in this block survive power cycles.
Default |
False
|
valid_ranges
|
tuple[tuple[int, int], ...] | None
|
Optional tuple of |
None
|
address_formatter
|
Callable[[str, int], str] | None
|
Optional callable |
None
|
Example
DS = Block("DS", TagType.INT, 1, 100)
DS[1] # → LiveTag("DS1", TagType.INT)
DS[101] # → IndexError
# Range for block operations:
DS.select(1, 10) # → BlockRange, tags DS1..DS10
# Indirect (pointer) addressing:
idx = Int("Idx")
DS[idx] # → IndirectRef, resolved at scan time
DS[idx + 1] # → IndirectExprRef
rename_slot
Set the first-class logical name for one slot before materialization.
clear_slot_name
Clear a first-class slot name override for one address.
configure_slot
Set per-slot runtime policy before this slot is materialized.
configure_range
configure_range(
start: int,
end: int,
*,
retentive: bool | None = None,
default: object = UNSET,
) -> None
Set per-slot policy for all valid addresses in the inclusive window.
clear_slot_config
Clear per-slot policy overrides for one address.
clear_range_config
Clear per-slot policy overrides for all valid addresses in a window.
slot_config
Return the effective runtime slot policy without materializing a Tag.
select
Select an inclusive range of addresses for block operations.
Both start and end are inclusive: DS.select(1, 10) yields
10 tags (1, 2, … 10). This mirrors the block constructor convention and
avoids the off-by-one confusion of Python's half-open slices.
For sparse blocks (valid_ranges set), returns only the valid addresses
within the window — gaps are silently skipped.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
start
|
int | Tag | Any
|
Start address. |
required |
end
|
int | Tag | Any
|
End address. |
required |
Returns:
| Type | Description |
|---|---|
BlockRange | IndirectBlockRange
|
|
BlockRange | IndirectBlockRange
|
definition time). |
BlockRange | IndirectBlockRange
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
IndexError
|
If either bound is outside the block's |
Example
# Static range
DS.select(1, 100) # BlockRange, DS1..DS100
# Sparse window (Click X bank)
x.select(1, 21) # valid tags only: X001..X016, X021
# Dynamic range (resolved each scan)
DS.select(start_tag, end_tag) # IndirectBlockRange
# Use with bulk instructions:
fill(0, DS.select(1, 10))
blockcopy(DS.select(1, 10), DD.select(1, 10))
search(">=", 100, DS.select(1, 100), result=Found, found=FoundFlag)
InputBlock
dataclass
Bases: Block
Factory for creating InputTag instances from a physical input memory region.
InputBlock is identical to Block except:
- Indexing returns
LiveInputTag(notLiveTag), so elements have.immediate. - Always non-retentive — physical inputs do not survive power cycles.
Use InputBlock when the tags represent real hardware inputs (sensors,
switches, etc.). In simulation, values are supplied via runner.patch() or
runner.add_force() during the Read Inputs scan phase.
Example
OutputBlock
dataclass
Bases: Block
Factory for creating OutputTag instances from a physical output memory region.
OutputBlock is identical to Block except:
- Indexing returns
LiveOutputTag(notLiveTag), so elements have.immediate. - Always non-retentive — physical outputs do not survive power cycles.
Writes to OutputTag elements are immediately visible to subsequent rungs
within the same scan (standard PLC behavior). The actual hardware write
happens at the Write Outputs scan phase (phase 6).
Example
BlockRange
dataclass
Contiguous range of addresses for block operations.
Attributes:
| Name | Type | Description |
|---|---|---|
block |
Block
|
Source Block. |
start |
int
|
Starting address (inclusive). |
end |
int
|
Ending address (inclusive). |
addresses
property
Return addresses in this block window, filtered by block rules.
IndirectBlockRange
dataclass
Memory block with runtime-resolved bounds.
Wraps a Block with start/end that may be Tags or Expressions, resolved at scan time.
Attributes:
| Name | Type | Description |
|---|---|---|
block |
Block
|
Source Block. |
start_expr |
int | Tag | Any
|
Start address (int, Tag, or Expression). |
end_expr |
int | Tag | Any
|
End address (int, Tag, or Expression). |
resolve_ctx
Resolve expressions to concrete BlockRange using ScanContext.
reverse
Return this same dynamic window with address iteration reversed.
IndirectRef
dataclass
Tag with runtime-resolved address via pointer.
IndirectRef wraps a Block and pointer Tag. The actual address is resolved from the pointer's value at scan time.
Attributes:
| Name | Type | Description |
|---|---|---|
block |
Block
|
Block to index into. |
pointer |
Tag
|
Tag whose value determines the address. |
resolve
Resolve pointer value to concrete Tag.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state
|
SystemState
|
Current system state to read pointer value from. |
required |
Returns:
| Type | Description |
|---|---|
Tag
|
Concrete Tag at the resolved address. |
Raises:
| Type | Description |
|---|---|
IndexError
|
If resolved address is out of range. |
resolve_ctx
Resolve pointer value to concrete Tag using ScanContext.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ctx
|
ScanContext
|
ScanContext to read pointer value from. |
required |
Returns:
| Type | Description |
|---|---|
Tag
|
Concrete Tag at the resolved address. |
Raises:
| Type | Description |
|---|---|
IndexError
|
If resolved address is out of range. |
IndirectExprRef
dataclass
Tag with runtime-resolved address via expression.
IndirectExprRef wraps a Block and an Expression. The actual address is computed from the expression at scan time.
This enables pointer arithmetic like DS[idx + 1] where idx is a Tag.
Attributes:
| Name | Type | Description |
|---|---|---|
block |
Block
|
Block to index into. |
expr |
Any
|
Expression whose value determines the address. |
resolve_ctx
Resolve expression value to concrete Tag using ScanContext.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ctx
|
ScanContext
|
ScanContext to evaluate expression against. |
required |
Returns:
| Type | Description |
|---|---|
Tag
|
Concrete Tag at the computed address. |
Raises:
| Type | Description |
|---|---|
IndexError
|
If resolved address is out of range. |