kodept_parse/lexer/
traits.rs

1use crate::lexer::{
2    BitOperator, ComparisonOperator, Keyword, LogicOperator, MathOperator, Operator, Symbol,
3};
4
5pub trait ToRepresentation
6where
7    Self: 'static,
8{
9    fn representation(&self) -> &'static str;
10}
11
12impl ToRepresentation for Operator {
13    fn representation(&self) -> &'static str {
14        match self {
15            Operator::Dot => ".",
16            Operator::Flow => "=>",
17            Operator::Math(x) => match x {
18                MathOperator::Plus => "+",
19                MathOperator::Sub => "-",
20                MathOperator::Div => "/",
21                MathOperator::Mod => "%",
22                MathOperator::Pow => "**",
23                MathOperator::Times => "*",
24            },
25            Operator::Comparison(x) => match x {
26                ComparisonOperator::Equals => "=",
27                ComparisonOperator::Equiv => "==",
28                ComparisonOperator::NotEquiv => "!=",
29                ComparisonOperator::Less => "<",
30                ComparisonOperator::LessEquals => "<=",
31                ComparisonOperator::Greater => ">",
32                ComparisonOperator::GreaterEquals => ">=",
33                ComparisonOperator::Spaceship => "<=>",
34            },
35            Operator::Logic(x) => match x {
36                LogicOperator::OrLogic => "||",
37                LogicOperator::AndLogic => "&&",
38                LogicOperator::NotLogic => "!",
39            },
40            Operator::Bit(x) => match x {
41                BitOperator::OrBit => "|",
42                BitOperator::AndBit => "&",
43                BitOperator::XorBit => "^",
44                BitOperator::NotBit => "~",
45            },
46        }
47    }
48}
49
50impl ToRepresentation for Symbol {
51    fn representation(&self) -> &'static str {
52        match self {
53            Symbol::Comma => ",",
54            Symbol::Semicolon => ";",
55            Symbol::LBrace => "{",
56            Symbol::RBrace => "}",
57            Symbol::LBracket => "[",
58            Symbol::RBracket => "]",
59            Symbol::LParen => "(",
60            Symbol::RParen => ")",
61            Symbol::TypeGap => "_",
62            Symbol::DoubleColon => "::",
63            Symbol::Colon => ":",
64        }
65    }
66}
67
68impl ToRepresentation for Keyword {
69    fn representation(&self) -> &'static str {
70        match self {
71            Keyword::Fun => "fun",
72            Keyword::Val => "val",
73            Keyword::Var => "var",
74            Keyword::If => "if",
75            Keyword::Elif => "elif",
76            Keyword::Else => "else",
77            Keyword::Match => "match",
78            Keyword::While => "while",
79            Keyword::Module => "module",
80            Keyword::Extend => "extend",
81            Keyword::Lambda => "\\",
82            Keyword::Abstract => "abstract",
83            Keyword::Trait => "trait",
84            Keyword::Struct => "struct",
85            Keyword::Class => "class",
86            Keyword::Enum => "enum",
87            Keyword::Foreign => "foreign",
88            Keyword::TypeAlias => "type",
89            Keyword::With => "with",
90            Keyword::Return => "return",
91        }
92    }
93}
94
95#[cfg(all(test, feature = "enum-iter"))]
96mod tests {
97    use std::fmt::Debug;
98    use enum_iterator::{all, Sequence};
99
100    use rstest::rstest;
101    use crate::common::TokenProducer;
102    use crate::lexer::traits::ToRepresentation;
103    use crate::lexer::{DefaultLexer, Keyword, Token, Symbol, Operator};
104
105    #[rstest]
106    #[case(Keyword::Struct)]
107    #[case(Symbol::Comma)]
108    #[case(Operator::Dot)]
109    fn test_lexers<T>(#[case] _example: T)
110    where
111        T: Sequence + ToRepresentation + PartialEq + Debug + for<'a> Into<Token<'a>>
112    {
113        let values = all::<T>().map(|it| {
114            let parsed = DefaultLexer::new().parse_token(it.representation(), 0);
115            (it, parsed)
116        });
117
118        for (original, gen) in values {
119            match gen {
120                Ok(it) => assert_eq!(original.into(), it.token),
121                Err(e) => panic!("For input `{original:?}` {e}"),
122            };
123        }
124    }
125}