1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
use proc_macro::{Delimiter, TokenStream, TokenTree};
use quote::quote;
struct Tag {
id: u64,
path: Vec<String>,
name: String,
r#type: Option<String>, // None -> Master
}
#[proc_macro]
pub fn define_ebml(ts: TokenStream) -> TokenStream {
let mut next_glob = false;
let mut ts = ts.into_iter();
let mut tags = vec![];
while let Some(t) = ts.next() {
match t {
TokenTree::Ident(ident) => {
let ident = ident.to_string();
if &ident == "global" {
next_glob = true;
} else {
let glob = next_glob;
next_glob = false;
let id = if let Some(TokenTree::Group(gr)) = ts.next() {
assert_eq!(gr.delimiter(), Delimiter::Bracket);
let mut ts = gr.stream().into_iter();
if let TokenTree::Literal(lit) = ts.next().unwrap() {
u64::from_str_radix(&lit.to_string()[2..], 16).unwrap()
} else {
panic!("literal expected")
}
} else {
panic!("group expected")
};
if let Some(TokenTree::Punct(p)) = ts.next() {
assert_eq!(p.as_char(), ':')
} else {
panic!("colon expected")
}
match ts.next() {
Some(TokenTree::Group(_)) => {}
Some(TokenTree::Ident(ident)) => {
let r#type = ident.to_string();
eprintln!("global={glob} id={id}, type={}", r#type);
}
_ => panic!("group or ident expected"),
}
if let Some(TokenTree::Punct(p)) = ts.next() {
assert_eq!(p.as_char(), ',')
} else {
panic!("colon expected")
}
}
}
x => panic!("unexpected {x:?}"),
}
}
quote! {}.into()
}
|