py_lex/
macros.rs

1/// use to define some keyword
2///
3/// you should only use at most one keywords! macro in a mod
4#[macro_export]
5macro_rules! reverse_parse_keywords {
6    ($(
7        $(#[$metas:meta])*
8        keywords $enum_name:ident
9        { $(
10            $string:literal -> $var:ident,
11        )*}
12    )*) => {
13        $(
14        #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
15        $(#[$metas])*
16        pub enum $enum_name {
17            $(
18                $var,
19            )*
20        }
21
22        impl std::ops::Deref for $enum_name {
23            type Target = str;
24            fn deref(&self) -> &Self::Target {
25                match self {
26                    $(Self::$var => $string,)*
27                }
28            }
29
30        }
31
32        impl std::fmt::Display for $enum_name {
33            fn fmt(&self, f: &mut std::fmt::Formatter) -> std::result::Result<(), std::fmt::Error> {
34                f.write_str(self)
35            }
36        }
37
38        #[cfg(feature = "parse")]
39        impl terl::ReverseParseUnit<$crate::Token> for $enum_name {
40            type Left = $enum_name;
41            fn reverse_parse(&self, p:&mut terl::Parser<$crate::Token>) -> Result<$enum_name, terl::ParseError> {
42                use terl::WithSpanExt;
43
44                let Some(next) = p.next() else {
45                    return p.unmatch(format!("expect {}, but non token left", self))
46                };
47
48                if &**next != &**self {
49                    let msg = format!("expect {}, but {} was got", self, &**next);
50                    return p.unmatch(msg)
51                }
52
53                Ok(*self)
54            }
55        }
56
57        )*
58
59
60        thread_local! {
61            pub static KEPPING_KEYWORDS: std::collections::HashSet<&'static str> = {
62                let mut set = std::collections::HashSet::<&'static str>::default();
63                $($(
64                    set.insert($string);
65                )*)*
66                set
67            };
68        }
69    };
70}
71
72#[macro_export]
73macro_rules! front_parse_keywords {
74    ($(
75        $(#[$metas:meta])*
76        keywords $enum_name:ident
77        { $(
78            $string:literal -> $var:ident,
79        )*}
80    )*) => {
81        $crate::reverse_parse_keywords! {
82            $(
83            $(#[$metas])*
84            keywords $enum_name
85            { $(
86                $string -> $var,
87            )*}
88            )*
89        }
90        $(
91        $crate::parse_unit_impl! {
92            $(#[$metas])*
93            $enum_name
94            { $(
95                $string -> $var,
96            )*}
97        }
98        )*
99    }
100}