logos_codegen/generator/
leaf.rs1use 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}