kodept_parse/lexer/
traits.rs1use 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}