logos_codegen/generator/
leaf.rs

1use proc_macro2::TokenStream;
2use quote::quote;
3
4use crate::generator::{Context, Generator};
5use crate::leaf::{Callback, Leaf};
6use crate::util::MaybeVoid;
7
8impl Generator<'_> {
9    pub fn generate_leaf(&mut self, leaf: &Leaf, mut ctx: Context) -> TokenStream {
10        let bump = ctx.bump();
11
12        let ident = &leaf.ident;
13        let name = self.name;
14        let this = self.this;
15        let ty = &leaf.field;
16
17        let constructor = match leaf.field {
18            MaybeVoid::Some(_) => quote!(#name::#ident),
19            MaybeVoid::Void => quote!(|()| #name::#ident),
20        };
21
22        match &leaf.callback {
23            Some(Callback::Label(callback)) => quote! {
24                #bump
25                #callback(lex).construct(#constructor, lex);
26            },
27            Some(Callback::Inline(inline)) => {
28                let arg = &inline.arg;
29                let body = &inline.body;
30
31                #[cfg(not(rust_1_82))]
32                let ret = quote!(impl CallbackResult<'s, #ty, #this>);
33
34                #[cfg(rust_1_82)]
35                let ret = quote!(impl CallbackResult<'s, #ty, #this> + use<'s>);
36
37                quote! {
38                    #bump
39
40                    #[inline]
41                    fn callback<'s>(#arg: &mut Lexer<'s>) -> #ret {
42                        #body
43                    }
44
45                    callback(lex).construct(#constructor, lex);
46                }
47            }
48            Some(Callback::Skip(_)) => {
49                quote! {
50                    #bump
51
52                    lex.trivia();
53                    #name::lex(lex);
54                }
55            }
56            None if matches!(leaf.field, MaybeVoid::Void) => quote! {
57                #bump
58                lex.set(Ok(#name::#ident));
59            },
60            None => quote! {
61                #bump
62                let token = #name::#ident(lex.slice());
63                lex.set(Ok(token));
64            },
65        }
66    }
67}