aranya_policy_module/
instructions.rs

1extern crate alloc;
2
3use alloc::string::String;
4use core::fmt::{self, Display};
5
6use serde::{Deserialize, Serialize};
7
8mod meta;
9
10pub use meta::*;
11
12use crate::{data::Value, Label};
13
14/// Reason for ending execution.
15#[must_use]
16#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
17pub enum ExitReason {
18    /// Execution completed without errors.
19    Normal,
20    /// Execution is paused to return a result, which is at the top of the stack. Call `RunState::run()` again to resume.
21    Yield,
22    /// Execution was aborted gracefully, due an error.
23    Check,
24    /// Execution was aborted due to an unhandled error.
25    Panic,
26}
27
28impl ExitReason {
29    /// Asserts that the reason is `ExitReason::Normal`.
30    #[cfg(feature = "testing")]
31    pub fn success(self) {
32        assert_eq!(self, Self::Normal);
33    }
34}
35
36impl Display for ExitReason {
37    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
38        match self {
39            Self::Normal => f.write_str("normal"),
40            Self::Yield => f.write_str("yield"),
41            Self::Check => f.write_str("check"),
42            Self::Panic => f.write_str("panic"),
43        }
44    }
45}
46
47/// The target of a branch
48#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
49pub enum Target {
50    /// An unresolved target with a symbolic name
51    Unresolved(Label),
52    /// A resolved target referring to an address
53    Resolved(usize),
54}
55
56impl Target {
57    /// Get the resolved address or None if it has not been resolved.
58    pub fn resolved(&self) -> Option<usize> {
59        match self {
60            Target::Resolved(i) => Some(*i),
61            _ => None,
62        }
63    }
64}
65
66impl Display for Target {
67    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
68        match self {
69            Self::Unresolved(label) => write!(f, "<{label}>"),
70            Self::Resolved(addr) => write!(f, "{addr}"),
71        }
72    }
73}
74
75/// An identifier for a type, field, assignment, etc.
76pub type Identifier = String;
77
78/// The machine instruction types
79#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
80pub enum Instruction {
81    // data
82    /// Push a value onto the stack
83    Const(Value),
84    /// Define a local value by name
85    Def(Identifier),
86    /// Get a local value by name
87    Get(Identifier),
88    /// Swap value at depth d with the top of the stack
89    Swap(usize), // TODO(chip): remove this or limit the argument to small values
90    /// Duplicate the value at depth d onto the top of the stack
91    Dup(usize),
92    /// Remove a value from the top of the stack
93    Pop,
94    // control flow
95    /// Define the beginning of a block
96    Block,
97    /// Define the end of a block
98    End,
99    /// Jump forward to the target in the current block
100    Jump(Target),
101    /// Jump if top of stack is true
102    Branch(Target),
103    /// Jump to the beginning of the block
104    Next,
105    /// Jump to the end of the block
106    Last,
107    /// Call regular function at target
108    Call(Target),
109    /// Call external function (FFI), specified by module, procedure indices. The FFI modules should be added to the MachineIO.
110    ExtCall(usize, usize),
111    /// Return to the last address on the control flow stack
112    Return,
113    /// End execution non-fatally
114    Exit(ExitReason),
115    // arithmetic/logic
116    /// Add two numbers
117    Add,
118    /// Subtract two numbers
119    Sub,
120    /// Logical negation
121    Not,
122    /// Logical and
123    And,
124    /// Logical or
125    Or,
126    /// Greater than
127    Gt,
128    /// Less than
129    Lt,
130    /// Equality
131    Eq,
132    // facts
133    /// Create a fact object by name
134    FactNew(Identifier),
135    /// Set a key member
136    FactKeySet(Identifier),
137    /// Set a value member
138    FactValueSet(Identifier),
139    // structs
140    /// Create a struct object by name
141    StructNew(Identifier),
142    /// Add a member to the struct
143    StructSet(Identifier),
144    /// Get a member from the struct
145    StructGet(Identifier),
146    // context-specific
147    /// Publish a struct as a command
148    Publish,
149    /// Create a fact
150    Create,
151    /// Delete a fact
152    Delete,
153    /// Update a fact
154    Update,
155    /// Emit an effect
156    Emit,
157    /// Query for a fact
158    Query,
159    /// Count facts, up to a given limit
160    FactCount(i64),
161    /// Execute a fact query, and retain results so they can be consumed with `QueryNext`.
162    QueryStart,
163    /// Fetches the next result, and pushes it onto the stack
164    QueryNext(Identifier),
165    /// Serialize a command struct
166    Serialize,
167    /// Deserialize a command struct
168    Deserialize,
169    /// Metadata for tracing
170    Meta(Meta),
171}
172
173impl Display for Instruction {
174    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
175        match self {
176            Instruction::Const(v) => write!(f, "const {v}"),
177            Instruction::Def(ident) => write!(f, "def {ident}"),
178            Instruction::Get(ident) => write!(f, "get {ident}"),
179            Instruction::Swap(d) => write!(f, "swap {d}"),
180            Instruction::Dup(d) => write!(f, "dup {d}"),
181            Instruction::Pop => write!(f, "pop"),
182            Instruction::Block => write!(f, "block"),
183            Instruction::End => write!(f, "end"),
184            Instruction::Jump(t) => write!(f, "jump {t}"),
185            Instruction::Branch(t) => write!(f, "branch {t}"),
186            Instruction::Next => write!(f, "next"),
187            Instruction::Last => write!(f, "last"),
188            Instruction::Call(t) => write!(f, "call {t}"),
189            Instruction::ExtCall(module, proc) => write!(f, "extcall {module} {proc}"),
190            Instruction::Return => write!(f, "return"),
191            Instruction::Exit(reason) => write!(f, "exit {reason}"),
192            Instruction::Add => write!(f, "add"),
193            Instruction::Sub => write!(f, "sub"),
194            Instruction::Not => write!(f, "not"),
195            Instruction::And => write!(f, "and"),
196            Instruction::Or => write!(f, "or"),
197            Instruction::Gt => write!(f, "gt"),
198            Instruction::Lt => write!(f, "lt"),
199            Instruction::Eq => write!(f, "eq"),
200            Instruction::FactNew(ident) => write!(f, "fact.new {ident}"),
201            Instruction::FactKeySet(ident) => write!(f, "fact.kset {ident}"),
202            Instruction::FactValueSet(ident) => write!(f, "fact.vset {ident}"),
203            Instruction::StructNew(ident) => write!(f, "struct.new {ident}"),
204            Instruction::StructSet(ident) => write!(f, "struct.set {ident}"),
205            Instruction::StructGet(ident) => write!(f, "struct.get {ident}"),
206            Instruction::Publish => write!(f, "publish"),
207            Instruction::Create => write!(f, "create"),
208            Instruction::Delete => write!(f, "delete"),
209            Instruction::Update => write!(f, "update"),
210            Instruction::Emit => write!(f, "emit"),
211            Instruction::Query => write!(f, "query"),
212            Instruction::FactCount(limit) => write!(f, "fact.count {limit}"),
213            Instruction::QueryStart => write!(f, "query.start"),
214            Instruction::QueryNext(ident) => write!(f, "query.next {ident}"),
215            Instruction::Serialize => write!(f, "serialize"),
216            Instruction::Deserialize => write!(f, "deserialize"),
217            Instruction::Meta(m) => write!(f, "meta: {m}"),
218        }
219    }
220}