1#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
5pub enum CompileError {
6 #[error("unsupported expression: {0}")]
8 Unsupported(String),
9 #[error("missing AST node: {0}")]
11 MissingNode(String),
12 #[error("constant pool overflow (>{max} constants)", max = u16::MAX)]
14 ConstantPoolOverflow,
15 #[error("jump offset overflow")]
17 JumpOverflow,
18 #[error("too many local variables")]
20 TooManyLocals,
21 #[error("parse error: {0}")]
23 ParseError(String),
24}
25
26#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
28pub enum VMError {
29 #[error("type error in {context}: expected {expected}, got {got}")]
31 TypeError {
32 expected: &'static str,
33 got: &'static str,
34 context: String,
35 },
36 #[error("division by zero")]
38 DivisionByZero,
39 #[error("assertion failed")]
41 AssertionFailed,
42 #[error("stack underflow")]
44 StackUnderflow,
45 #[error("invalid opcode: {0}")]
47 InvalidOpcode(u8),
48 #[error("not a function: {0}")]
50 NotCallable(String),
51 #[error("undefined variable: {0}")]
53 UndefinedVariable(String),
54 #[error("attribute not found: {0}")]
56 AttrNotFound(String),
57 #[error("internal error: {0}")]
59 Internal(String),
60 #[error("stack overflow: call depth exceeded")]
62 StackOverflow,
63 #[error("{0}")]
65 Throw(String),
66 #[error("unknown builtin: {0}")]
68 UnknownBuiltin(String),
69 #[error("infinite recursion detected")]
71 InfiniteRecursion,
72 #[error("import error: {0}")]
74 ImportError(String),
75}
76
77#[cfg(test)]
78mod tests {
79 use super::*;
80
81 #[test]
82 fn compile_error_display() {
83 let e = CompileError::Unsupported("with".to_string());
84 assert!(e.to_string().contains("with"));
85 }
86
87 #[test]
88 fn vm_error_display() {
89 let e = VMError::DivisionByZero;
90 assert!(e.to_string().contains("division by zero"));
91 }
92
93 #[test]
94 fn type_error_display() {
95 let e = VMError::TypeError {
96 expected: "int",
97 got: "string",
98 context: "addition".to_string(),
99 };
100 let msg = e.to_string();
101 assert!(msg.contains("int"));
102 assert!(msg.contains("string"));
103 assert!(msg.contains("addition"));
104 }
105}