trueno_ptx_debug/parser/
error.rs1use super::ast::SourceLocation;
4
5#[derive(Debug, Clone, thiserror::Error)]
7pub enum ParseError {
8 #[error("Unexpected token at {location}: expected {expected}, found {found}")]
10 UnexpectedToken {
11 expected: String,
13 found: String,
15 location: SourceLocation,
17 },
18
19 #[error("Unexpected end of file at {location}")]
21 UnexpectedEof {
22 location: SourceLocation,
24 },
25
26 #[error("Invalid directive '{directive}' at {location}")]
28 InvalidDirective {
29 directive: String,
31 location: SourceLocation,
33 },
34
35 #[error("Invalid instruction at {location}: {message}")]
37 InvalidInstruction {
38 message: String,
40 location: SourceLocation,
42 },
43
44 #[error("Invalid operand '{operand}' at {location}")]
46 InvalidOperand {
47 operand: String,
49 location: SourceLocation,
51 },
52
53 #[error("Invalid type '{ty}' at {location}")]
55 InvalidType {
56 ty: String,
58 location: SourceLocation,
60 },
61
62 #[error("Duplicate label '{label}' at {location}")]
64 DuplicateLabel {
65 label: String,
67 location: SourceLocation,
69 },
70
71 #[error("Undefined label '{label}' at {location}")]
73 UndefinedLabel {
74 label: String,
76 location: SourceLocation,
78 },
79
80 #[error("Lexer error at {location}: {message}")]
82 LexerError {
83 message: String,
85 location: SourceLocation,
87 },
88}
89
90impl ParseError {
91 pub fn location(&self) -> &SourceLocation {
93 match self {
94 ParseError::UnexpectedToken { location, .. } => location,
95 ParseError::UnexpectedEof { location, .. } => location,
96 ParseError::InvalidDirective { location, .. } => location,
97 ParseError::InvalidInstruction { location, .. } => location,
98 ParseError::InvalidOperand { location, .. } => location,
99 ParseError::InvalidType { location, .. } => location,
100 ParseError::DuplicateLabel { location, .. } => location,
101 ParseError::UndefinedLabel { location, .. } => location,
102 ParseError::LexerError { location, .. } => location,
103 }
104 }
105}
106
107#[cfg(test)]
108mod tests {
109 use super::*;
110
111 #[test]
112 fn test_error_display() {
113 let err = ParseError::UnexpectedToken {
114 expected: "identifier".into(),
115 found: "number".into(),
116 location: SourceLocation {
117 line: 10,
118 column: 5,
119 file: None,
120 },
121 };
122 let msg = format!("{}", err);
123 assert!(msg.contains("Unexpected token"));
124 assert!(msg.contains("10:5"));
125 }
126
127 #[test]
128 fn test_error_location() {
129 let loc = SourceLocation {
130 line: 42,
131 column: 10,
132 file: None,
133 };
134 let err = ParseError::InvalidDirective {
135 directive: ".foo".into(),
136 location: loc.clone(),
137 };
138 assert_eq!(err.location().line, 42);
139 assert_eq!(err.location().column, 10);
140 }
141}