Skip to main content

stak_vm/
error.rs

1use crate::exception::Exception;
2use core::{
3    error,
4    fmt::{self, Debug, Display, Formatter},
5};
6
7/// An error of a virtual machine.
8#[derive(Clone, Debug, Eq, PartialEq)]
9pub enum Error {
10    /// Mismatched numbers of call arguments and procedure parameters.
11    ArgumentCount,
12    /// A cons expected.
13    ConsExpected,
14    /// A division by zero.
15    DivisionByZero,
16    /// An unexpected end of bytecode.
17    BytecodeEnd,
18    /// A format error.
19    Format(fmt::Error),
20    /// Invalid memory access.
21    InvalidMemoryAccess,
22    /// An illegal instruction detected.
23    IllegalInstruction,
24    /// An illegal primitive detected.
25    IllegalPrimitive,
26    /// A number expected.
27    NumberExpected,
28    /// Out of memory.
29    OutOfMemory,
30    /// A procedure expected.
31    ProcedureExpected,
32}
33
34impl Exception for Error {
35    fn is_critical(&self) -> bool {
36        match self {
37            Self::ArgumentCount
38            | Self::InvalidMemoryAccess
39            | Self::IllegalPrimitive
40            | Self::NumberExpected
41            | Self::ConsExpected
42            | Self::DivisionByZero
43            | Self::ProcedureExpected => false,
44            Self::BytecodeEnd | Self::Format(_) | Self::IllegalInstruction | Self::OutOfMemory => {
45                true
46            }
47        }
48    }
49}
50
51impl error::Error for Error {}
52
53impl Display for Error {
54    fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
55        match self {
56            Self::ArgumentCount => write!(formatter, "invalid argument count"),
57            Self::BytecodeEnd => write!(formatter, "unexpected end of bytecode"),
58            Self::ConsExpected => write!(formatter, "cons expected"),
59            Self::DivisionByZero => write!(formatter, "division by zero"),
60            Self::Format(error) => write!(formatter, "{error}"),
61            Self::InvalidMemoryAccess => write!(formatter, "invalid memory access"),
62            Self::IllegalInstruction => write!(formatter, "illegal instruction"),
63            Self::IllegalPrimitive => write!(formatter, "illegal primitive"),
64            Self::NumberExpected => write!(formatter, "number expected"),
65            Self::OutOfMemory => write!(formatter, "out of memory"),
66            Self::ProcedureExpected => write!(formatter, "procedure expected"),
67        }
68    }
69}
70
71impl From<fmt::Error> for Error {
72    fn from(error: fmt::Error) -> Self {
73        Self::Format(error)
74    }
75}