osiris_process/operation/error.rs
1use osiris_data::memory::{MemoryError, MemoryResult};
2
3use crate::operation::Instruction;
4use crate::operation::scheme::ArgumentType;
5
6#[derive(Debug)]
7pub enum OperationError {
8 /// The processor should HALT,
9 HaltError,
10 /// The processor should HALT and an error message should be displayed,
11 Panic(String),
12 /// An invalid argument has been provided to an operation call,
13 InvalidArgumentType { expected: ArgumentType, provided: ArgumentType },
14 /// A memory error occurred during a memory operation,
15 MemoryError(MemoryError),
16 /// The stack is empty but a pop() had been required,
17 CannotReturnFromEmptyStack,
18 /// The specified instruction matches no operation.
19 MismatchedInstruction(Instruction),
20}
21
22pub type OperationResult<T> = Result<T, OperationError>;
23
24/// Some sugar to wrap a [MemoryError] in a [OperationError::MemoryError] or to return a `Ok` value as is :
25///
26/// ```
27/// use osiris_data::memory::{Memory, MemoryError, MemoryResult};
28/// use osiris_process::operation::error::{OperationError, promote};
29///
30/// let mut mem = Memory::with_size(1);
31/// let m: MemoryResult<()> = mem.free(2);
32/// let o = promote(m);
33/// if let Err(OperationError::MemoryError(MemoryError::CannotFree {trying_to_free: 2,memory_len: 1})) = o {
34/// assert!(true)
35/// } else { assert!(false) }
36///
37/// let m: MemoryResult<()> = mem.free(1);
38/// let o = promote(m);
39/// if let Ok(()) = o { assert!(true) } else { assert!(false) }
40/// assert!(mem.is_empty());
41/// ```
42pub fn promote<T>(memory_result: MemoryResult<T>) -> OperationResult<T> {
43 match memory_result {
44 Ok(ok_value) => Ok(ok_value),
45 Err(e) => Err(OperationError::MemoryError(e))
46 }
47}