baby_emulator/assembler/parser/
errors.rs

1//! # Parse Errors 
2//! 
3//! This module includes all the possible errors that can be thrown 
4//! during parsing, all error types implement [ParseError][crate::assembler::parser::errors::ParseError].
5//! 
6//! The main type in this module is [LineParseError][crate::assembler::parser::errors::LineParseError]
7//! whcih is an enum that has a branch for each possible error that can be thrown 
8//! with each branch wrapping the corresponding error type that contains metadata 
9//! on that error. 
10//! 
11//! Any new error types and object should be added to this enum. 
12//! 
13
14use super::Instruction;
15
16
17/// Defines common behaviour for all errors thrown whilst parsing Baby asm. 
18pub trait ParseError {
19    /// Returns a string describing an error thrown. 
20    /// 
21    /// # Parameters
22    /// * `line_breaks` - Add in line breaks between each embedded error. 
23    /// 
24    fn describe(&self, line_breaks: bool) -> String;
25}
26
27/// Thrown when an invalid value is encountered. 
28#[derive(PartialEq, Debug)]
29pub enum ValueParseError {
30    /// No discernable value detected where one is expected. 
31    InvalidValue(String),
32    /// Invalid hex value. 
33    InvalidHex(String),
34    /// Invalid decimal value. 
35    InvalidDecimal(String),
36    /// Invalid octal value. 
37    InvalidOctal(String),
38    /// Invalid binary value. 
39    InvalidBinary(String),
40    /// Invalid tag name. 
41    InvalidTagName(String),
42}
43
44impl ParseError for ValueParseError {
45    fn describe(&self, _line_breaks: bool) -> String {
46        match self {
47            ValueParseError::InvalidValue(v) => format!("The value: {}; is an invalid value. ", v),
48            ValueParseError::InvalidHex(v) => format!("The value: {}; is invalid hex value. ", v),
49            ValueParseError::InvalidDecimal(v) => format!("The value: {}; is invalid decimal value. ", v),
50            ValueParseError::InvalidOctal(v) => format!("The value: {}; is invalid octal value. ", v),
51            ValueParseError::InvalidBinary(v) => format!("The value: {}; is invalid binary value. ", v),
52            ValueParseError::InvalidTagName(v) => format!("The value: {}; is invalid tag name. ", v),
53        }
54    }
55}
56
57/// Thrown when errors are found parsing Baby asm instructions. 
58#[derive(PartialEq, Debug)]
59pub enum InstructionError {
60    /// A given instruction isn't correct. 
61    UnkownInstruction(String),
62    /// Attempting to parse a instructions operand threw an error. 
63    OperandValueParseError(Instruction, ValueParseError)
64}
65
66impl ParseError for InstructionError {
67    fn describe(&self, line_breaks: bool) -> String { 
68        let line_break = if line_breaks { "\n" } else { "" };
69        match self {
70            InstructionError::UnkownInstruction(v) => format!("The specified instruction {} is not known. ", v),
71            InstructionError::OperandValueParseError(c, v) => format!("Failed to parse operand for {}. {line_break} {}", c.describe(), v.describe(line_breaks))
72        }
73    }
74}
75
76/// Thrown when an error was encountered parsing an absolute value. 
77#[derive(PartialEq, Debug)]
78pub enum AbsoluteError {
79    /// Attempt to parse a value to an absolute value encountered an error. 
80    ValueError(ValueParseError)
81}
82
83impl ParseError for AbsoluteError {
84    fn describe(&self, line_breaks: bool) -> String {
85        let line_break = if line_breaks { "\n" } else { "" };
86        match self {
87            AbsoluteError::ValueError(v) => format!("Failed to parse value for absolute value declaration. {line_break} {}", v.describe(line_breaks))
88        }
89    }
90}
91
92/// Thrown when an error is encountered trying to parse a tag declaration. 
93#[derive(PartialEq, Debug)]
94pub enum TagError {
95    /// Thrown when a delcared tag name has whitespace. 
96    TagNameWhitespace(String)
97}
98
99impl ParseError for TagError {
100    fn describe(&self, _line_breaks: bool) -> String {
101        match self {
102            TagError::TagNameWhitespace(v) => format!("The tag name `{}` is invalid. ", v)
103        }
104    }
105}
106
107/// Thrown when an error is encountered parsing a Baby asm line. 
108#[derive(PartialEq, Debug)]
109pub enum LineParseError {
110    /// Thrown when an error is encountered parsing a tag declaration. 
111    TagError(TagError),
112    /// Thrown when an error is encountered parsing an absolute value declaration. 
113    AbsoluteError(AbsoluteError),
114    /// Thrown when an error is encountered parsing a instruction use. 
115    InstructionError(InstructionError),
116}
117
118impl ParseError for LineParseError {
119    fn describe(&self, line_breaks: bool) -> String {
120        let line_break = if line_breaks { "\n" } else { "" };
121        match self {
122            LineParseError::TagError(v) => format!("Error parsing a tag line, {}", v.describe(line_breaks)),
123            LineParseError::AbsoluteError(v) => format!("Error parsing an absolute value line. {line_break} {}", v.describe(line_breaks)),
124            LineParseError::InstructionError(v) => format!("Error parsing a instruction line. {line_break} {}", v.describe(line_breaks)),
125        }
126    }
127}