1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71

use std::fmt;
use std::error::Error;


pub type ParseResult<T> = Result<T, ParseError>;

#[derive(Debug, PartialEq, Clone)]
pub struct ParseError {
    pub kind: ParseErrorKind,
    pub token_type: String,
    pub token_value: String,
    pub message: String,
    pub line: String,
    pub line_no: usize,
    pub column_no: usize,
}

enum_from_primitive! {
    #[derive(Debug, PartialEq, Clone)]
    pub enum ParseErrorKind {
        Unknown,
        Syntax,
        Token,
        Numeric,
        Symtab,
        Lexer,
        Helper
    }
}

impl fmt::Display for ParseError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        if self.line_no > 0 || self.column_no > 0 {
            write!(
                f,
                "Parse error at line {}, column {} ({}): {}",
                self.line_no,
                self.column_no,
                self.token_value,
                self.message
            )
        } else {
            write!(f, "Parse error at {}: {}", self.token_value, self.message)
        }
    }
}

impl Error for ParseError {
    fn description(&self) -> &str {
        "expression parsing error"
    }
}



#[derive(Debug, PartialEq)]
pub struct InvalidName(pub String);


impl fmt::Display for InvalidName {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Invalid variable name: '{}'", self.0)
    }
}

impl Error for InvalidName {
    fn description(&self) -> &str {
        "invalid variable name"
    }
}