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 {}