jetcrab\vm/
error.rs

1use crate::ast::Position;
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
5pub enum VmError {
6    ExecutionError {
7        message: String,
8        instruction: Option<String>,
9        position: Option<Position>,
10    },
11
12    StackUnderflow {
13        message: String,
14        position: Option<Position>,
15    },
16
17    StackOverflow {
18        message: String,
19        position: Option<Position>,
20    },
21
22    InvalidInstruction {
23        instruction: String,
24        message: String,
25        position: Option<Position>,
26    },
27
28    TypeMismatch {
29        expected: String,
30        found: String,
31        position: Option<Position>,
32    },
33
34    UndefinedVariable {
35        name: String,
36        position: Option<Position>,
37    },
38
39    UndefinedFunction {
40        name: String,
41        position: Option<Position>,
42    },
43
44    DivisionByZero {
45        position: Option<Position>,
46    },
47
48    OutOfMemory {
49        message: String,
50        position: Option<Position>,
51    },
52
53    RuntimeError {
54        message: String,
55        position: Option<Position>,
56    },
57}
58
59impl std::fmt::Display for VmError {
60    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
61        match self {
62            VmError::ExecutionError {
63                message,
64                instruction,
65                position,
66            } => {
67                write!(f, "VM execution error: {message}")?;
68                if let Some(instr) = instruction {
69                    write!(f, " (instruction: {instr})")?;
70                }
71                if let Some(pos) = position {
72                    write!(f, " at line {}, column {}", pos.line, pos.column)?;
73                }
74                Ok(())
75            }
76            VmError::StackUnderflow { message, position } => {
77                write!(f, "Stack underflow: {message}")?;
78                if let Some(pos) = position {
79                    write!(f, " at line {}, column {}", pos.line, pos.column)?;
80                }
81                Ok(())
82            }
83            VmError::StackOverflow { message, position } => {
84                write!(f, "Stack overflow: {message}")?;
85                if let Some(pos) = position {
86                    write!(f, " at line {}, column {}", pos.line, pos.column)?;
87                }
88                Ok(())
89            }
90            VmError::InvalidInstruction {
91                instruction,
92                message,
93                position,
94            } => {
95                write!(f, "Invalid instruction '{instruction}': {message}")?;
96                if let Some(pos) = position {
97                    write!(f, " at line {}, column {}", pos.line, pos.column)?;
98                }
99                Ok(())
100            }
101            VmError::TypeMismatch {
102                expected,
103                found,
104                position,
105            } => {
106                write!(f, "Type mismatch: expected {expected}, found {found}")?;
107                if let Some(pos) = position {
108                    write!(f, " at line {}, column {}", pos.line, pos.column)?;
109                }
110                Ok(())
111            }
112            VmError::UndefinedVariable { name, position } => {
113                write!(f, "Undefined variable '{name}'")?;
114                if let Some(pos) = position {
115                    write!(f, " at line {}, column {}", pos.line, pos.column)?;
116                }
117                Ok(())
118            }
119            VmError::UndefinedFunction { name, position } => {
120                write!(f, "Undefined function '{name}'")?;
121                if let Some(pos) = position {
122                    write!(f, " at line {}, column {}", pos.line, pos.column)?;
123                }
124                Ok(())
125            }
126            VmError::DivisionByZero { position } => {
127                write!(f, "Division by zero")?;
128                if let Some(pos) = position {
129                    write!(f, " at line {}, column {}", pos.line, pos.column)?;
130                }
131                Ok(())
132            }
133            VmError::OutOfMemory { message, position } => {
134                write!(f, "Out of memory: {message}")?;
135                if let Some(pos) = position {
136                    write!(f, " at line {}, column {}", pos.line, pos.column)?;
137                }
138                Ok(())
139            }
140            VmError::RuntimeError { message, position } => {
141                write!(f, "Runtime error: {message}")?;
142                if let Some(pos) = position {
143                    write!(f, " at line {}, column {}", pos.line, pos.column)?;
144                }
145                Ok(())
146            }
147        }
148    }
149}
150
151impl std::error::Error for VmError {}