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