Skip to main content

telltale_machine/
instr.rs

1//! Bytecode instruction set.
2//!
3//! Matches the Lean `Instr γ ε` type from `lean/Runtime/ProtocolMachine/Model/Core.lean`.
4//! Registers are `u16` indices, PC is `usize`.
5
6use serde::{Deserialize, Serialize};
7
8use crate::session::SessionId;
9
10/// Register index.
11pub type Reg = u16;
12
13/// Program counter.
14pub type PC = usize;
15
16/// Effect action descriptor carried by `Invoke`.
17#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
18#[serde(untagged)]
19pub enum InvokeAction {
20    /// Named action descriptor (Lean-aligned shape).
21    Named(String),
22    /// Register-carried action descriptor.
23    Reg(Reg),
24}
25
26/// Structured endpoint: identifies a role within a session.
27///
28/// Matches the Lean `Endpoint` which carries `{ sid, role }`.
29/// The session store uses this as the key for local type state.
30#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
31pub struct Endpoint {
32    /// Session this endpoint belongs to.
33    pub sid: SessionId,
34    /// Role name within the session.
35    pub role: String,
36}
37
38/// Bytecode instruction.
39///
40/// The initial instruction set covers communication, session lifecycle,
41/// effects, and control flow. Guard/speculation/ownership instructions
42/// are deferred.
43#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
44pub enum Instr {
45    // -- Communication --
46    /// Send value in `val` register to channel in `chan` register.
47    Send {
48        /// Channel register.
49        chan: Reg,
50        /// Value register to send.
51        val: Reg,
52    },
53    /// Receive from channel in `chan` register, store in `dst` register.
54    Receive {
55        /// Channel register.
56        chan: Reg,
57        /// Destination register for the received value.
58        dst: Reg,
59    },
60    /// Offer a label on channel.
61    Offer {
62        /// Channel register.
63        chan: Reg,
64        /// Label to select.
65        label: String,
66    },
67    /// Choose from a branch table using a received label.
68    Choose {
69        /// Channel register.
70        chan: Reg,
71        /// Label-to-PC jump table.
72        table: Vec<(String, PC)>,
73    },
74
75    // -- Session lifecycle --
76    /// Open a new session with the given roles and endpoint destinations.
77    Open {
78        /// Role names for the session.
79        roles: Vec<String>,
80        /// Role-to-local-type mappings for session initialization.
81        local_types: Vec<(String, telltale_types::LocalTypeR)>,
82        /// Edge-to-handler mappings as `((sender, receiver), handler_id)`.
83        handlers: Vec<((String, String), String)>,
84        /// Role-to-register endpoint mappings.
85        dsts: Vec<(String, Reg)>,
86    },
87    /// Close the session referenced by the register.
88    Close {
89        /// Register holding the session reference.
90        session: Reg,
91    },
92
93    // -- Effects --
94    /// Invoke an effect handler action.
95    Invoke {
96        /// Action descriptor.
97        action: InvokeAction,
98    },
99    /// Acquire a guard layer and store evidence in a register.
100    Acquire {
101        /// Guard layer identifier.
102        layer: String,
103        /// Destination register for evidence.
104        dst: Reg,
105    },
106    /// Release a guard layer using evidence from a register.
107    Release {
108        /// Guard layer identifier.
109        layer: String,
110        /// Register holding evidence.
111        evidence: Reg,
112    },
113
114    // -- Speculation --
115    /// Enter speculation using a ghost session id.
116    Fork {
117        /// Register holding the ghost session id.
118        ghost: Reg,
119    },
120    /// Join speculative execution.
121    Join,
122    /// Abort speculative execution.
123    Abort,
124
125    // -- Ownership and knowledge --
126    /// Transfer an endpoint to another coroutine.
127    Transfer {
128        /// Register holding the endpoint.
129        endpoint: Reg,
130        /// Register holding the target coroutine id.
131        target: Reg,
132        /// Register holding a bundle descriptor.
133        bundle: Reg,
134    },
135    /// Tag a knowledge fact and return success.
136    Tag {
137        /// Register holding the fact.
138        fact: Reg,
139        /// Destination register for the result.
140        dst: Reg,
141    },
142    /// Check a knowledge fact against the flow policy.
143    Check {
144        /// Register holding the knowledge fact.
145        knowledge: Reg,
146        /// Register holding the target role.
147        target: Reg,
148        /// Destination register for the result.
149        dst: Reg,
150    },
151
152    // -- Control --
153    /// Set a register to an immediate value.
154    Set {
155        /// Destination register.
156        dst: Reg,
157        /// Immediate value to load.
158        val: ImmValue,
159    },
160    /// Copy register src to dst.
161    Move {
162        /// Destination register.
163        dst: Reg,
164        /// Source register.
165        src: Reg,
166    },
167    /// Unconditional jump.
168    Jump {
169        /// Target program counter.
170        target: PC,
171    },
172    /// Spawn a new coroutine at target PC with argument registers.
173    Spawn {
174        /// Target program counter for the spawned coroutine.
175        target: PC,
176        /// Registers to copy into the spawned coroutine argument area.
177        args: Vec<Reg>,
178    },
179    /// Yield execution to the scheduler.
180    Yield,
181    /// Halt this coroutine (normal termination).
182    Halt,
183}
184
185/// Immediate values that can be loaded into registers.
186#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
187pub enum ImmValue {
188    /// Unit value.
189    Unit,
190    /// Natural-number value (Lean-compatible).
191    Nat(u64),
192    /// Boolean value.
193    Bool(bool),
194    /// String value.
195    Str(String),
196}
197
198impl Eq for ImmValue {}