1#![allow(dead_code)]
2extern crate proc_macro;
3use proc_macro::{TokenTree, Span, TokenStream, Delimiter, Group, Literal, Ident, Punct, Spacing};
4use proc_macro::token_stream::IntoIter;
5
6pub fn error_span(err: &str, span: Span) -> TokenStream {
9 let mut tb = TokenBuilder::new();
10 tb.ident_with_span("compile_error", span).add("! (").string(err).add(") ;");
11 tb.end()
12}
13
14pub fn error(err: &str) -> TokenStream {
15 let mut tb = TokenBuilder::new();
16 tb.add("compile_error ! (").string(err).add(") ;");
17 tb.end()
18}
19
20pub fn error_result(err: &str) -> Result<(), TokenStream> {
21 let mut tb = TokenBuilder::new();
22 tb.add("compile_error ! (").string(err).add(") ;");
23 Err(tb.end())
24}
25
26pub fn unwrap_option(input: TokenStream) -> Result<TokenStream, TokenStream> {
27 let mut ty_parser = TokenParser::new(input.clone());
28 if ty_parser.eat_ident("Option") {
29 if !ty_parser.eat_punct_alone('<') {
30 panic!()
31 }
32 Ok(ty_parser.eat_level_or_punct('>'))
33 }
34 else {
35 Err(input)
36 }
37}
38
39pub struct TokenBuilder {
40 pub groups: Vec<(Delimiter, TokenStream)>
41}
42
43impl TokenBuilder {
44 pub fn new() -> Self {
45 Self {
46 groups: vec![(Delimiter::None, TokenStream::new())]
47 }
48 }
49
50 pub fn is_empty(&self) -> bool {
51 self.groups.len() == 1 && self.groups[0].1.is_empty()
52 }
53
54 pub fn end(mut self) -> TokenStream {
55 if self.groups.len() != 1 {
56 panic!("Groups not empty, you missed a pop_group")
57 }
58 self.groups.pop().unwrap().1
59 }
60
61 pub fn eprint(&self) {
62 eprintln!("{}", self.groups.last().unwrap().1.to_string());
63 }
64
65 pub fn extend(&mut self, tt: TokenTree) -> &mut Self {
66 self.groups.last_mut().unwrap().1.extend(Some(tt));
67 self
68 }
69
70 pub fn stream(&mut self, what: Option<TokenStream>) -> &mut Self {
71 if let Some(what) = what {
72 for c in what.into_iter() {
73 self.extend(c);
74 }
75 self
76 }
77 else {
78 self
79 }
80 }
81
82 pub fn add(&mut self, what: &str) -> &mut Self {
83 let b = what.as_bytes();
84 let mut o = 0;
85 while o < b.len() {
86 let c0 = b[o] as char;
87 let c1 = if o + 1 < b.len() {b[o + 1] as char}else {'\0'};
88 match (c0, c1) {
89 ('\r', _) | ('\n', _) | (' ', _) | ('\t', _) => {o += 1;}
90 ('{', _) => {self.push_group(Delimiter::Brace); o += 1;},
91 ('(', _) => {self.push_group(Delimiter::Parenthesis); o += 1;},
92 ('[', _) => {self.push_group(Delimiter::Bracket); o += 1;},
93 ('}', _) => {self.pop_group(Delimiter::Brace); o += 1;},
94 (')', _) => {self.pop_group(Delimiter::Parenthesis); o += 1;},
95 (']', _) => {self.pop_group(Delimiter::Bracket); o += 1;},
96 ('<', '<') | ('>', '>') | ('&', '&') | ('|', '|') |
97 ('-', '>') | ('=', '>') |
98 ('<', '=') | ('>', '=') | ('=', '=') | ('!', '=') | (':', ':') |
99 ('+', '=') | ('-', '=') | ('*', '=') | ('/', '=') | ('.', '.') => {
100 self.punct(std::str::from_utf8(&b[o..o + 2]).unwrap());
101 o += 2;
102 }
103 ('+', _) | ('-', _) | ('*', _) | ('/', _) | ('#', _) |
104 ('=', _) | ('<', _) | ('>', _) | ('?', _) | (';', _) | ('&', _) |
105 ('^', _) | (':', _) | (',', _) | ('!', _) | ('.', _) | ('|', _) => {
106 self.punct(std::str::from_utf8(&b[o..o + 1]).unwrap());
107 o += 1;
108 },
109 ('0', 'x') => { let mut e = o + 2;
111 let mut out: u64 = 0;
112 while e < b.len() {
113 match b[e] {
114 b'0'..=b'9' => out = (out << 4) | (b[e] - b'0') as u64,
115 b'a'..=b'f' => out = (out << 4) | (b[e] - b'a' + 10) as u64,
116 b'A'..=b'F' => out = (out << 4) | (b[e] - b'A' + 10) as u64,
117 b'_' => (),
118 _ => break,
119 };
120 e += 1;
121 }
122 self.suf_u64(out);
123 o = e;
124 }
125 ('0'..='9', _) => {
126 let mut e = o + 1;
127 while e < b.len() {
128 match b[e] {
129 b'0'..=b'9' => e += 1,
130 _ => break,
131 }
132 }
133 let num = std::str::from_utf8(&b[o..e]).unwrap();
134 self.unsuf_usize(num.parse().unwrap_or_else(|_| panic!("Can't parse usize number \"{}\"", what)));
135 o = e;
136 }
137 ('"', _) => {
138 let mut e = o + 1;
139 while e < b.len() {
140 match b[e] {
141 b'"' => break,
142 _ => e += 1,
143 }
144 }
145 self.string(std::str::from_utf8(&b[o + 1..e]).unwrap());
146 o = e + 1;
147 }
148 ('\'', _) => {
149 let mut e = o + 1;
150 while e < b.len() {
151 match b[e] {
152 b'0'..=b'9' | b'a'..=b'z' | b'A'..=b'Z' | b'_' => e += 1,
153 _ => break,
154 }
155 }
156 if o == e {
157 panic!("Unexpected character {:?}", b[e] as char);
158 }
159 let ident = std::str::from_utf8(&b[o + 1..e]).unwrap();
160 self.lifetime_mark();
161 self.ident(ident);
162 o = e;
163 }
164 _ => {
165 let mut e = o;
166 while e < b.len() {
167 match b[e] {
168 b'0'..=b'9' | b'a'..=b'z' | b'A'..=b'Z' | b'_' => e += 1,
169 _ => break,
170 }
171 }
172 if o == e {
173 panic!("Unexpected character {:?}", b[e] as char);
174 }
175 let ident = std::str::from_utf8(&b[o..e]).unwrap();
176 self.ident(ident);
177 o = e;
178 }
179 }
180 }
181 self
182 }
183
184 pub fn ident(&mut self, id: &str) -> &mut Self {
185 self.extend(TokenTree::from(Ident::new(id, Span::call_site())))
186 }
187
188 pub fn ident_with_span(&mut self, id: &str, span: Span) -> &mut Self {
189 self.extend(TokenTree::from(Ident::new(id, span)))
190 }
191
192 pub fn punct(&mut self, s: &str) -> &mut Self {
193 for (last, c) in s.chars().identify_last() {
194 self.extend(TokenTree::from(Punct::new(c, if last {Spacing::Alone} else {Spacing::Joint})));
195 }
196 self
197 }
198
199 pub fn lifetime_mark(&mut self) -> &mut Self {
200 self.extend(TokenTree::from(Punct::new('\'', Spacing::Joint)));
201 self
202 }
203
204 pub fn sep(&mut self) -> &mut Self {
205 self.extend(TokenTree::from(Punct::new(':', Spacing::Joint)));
206 self.extend(TokenTree::from(Punct::new(':', Spacing::Alone)));
207 self
208 }
209
210 pub fn string(&mut self, val: &str) -> &mut Self {self.extend(TokenTree::from(Literal::string(val)))}
211 pub fn unsuf_usize(&mut self, val: usize) -> &mut Self {self.extend(TokenTree::from(Literal::usize_unsuffixed(val)))}
212 pub fn suf_u16(&mut self, val: u16) -> &mut Self {self.extend(TokenTree::from(Literal::u16_suffixed(val)))}
213 pub fn suf_u32(&mut self, val: u32) -> &mut Self {self.extend(TokenTree::from(Literal::u32_suffixed(val)))}
214 pub fn suf_u64(&mut self, val: u64) -> &mut Self {self.extend(TokenTree::from(Literal::u64_suffixed(val)))}
215 pub fn unsuf_f32(&mut self, val: f32) -> &mut Self {self.extend(TokenTree::from(Literal::f32_unsuffixed(val)))}
216 pub fn unsuf_f64(&mut self, val: f64) -> &mut Self {self.extend(TokenTree::from(Literal::f64_unsuffixed(val)))}
217 pub fn unsuf_i64(&mut self, val: i64) -> &mut Self {self.extend(TokenTree::from(Literal::i64_unsuffixed(val)))}
218
219 pub fn chr(&mut self, val: char) -> &mut Self {self.extend(TokenTree::from(Literal::character(val)))}
220 pub fn _lit(&mut self, lit: Literal) -> &mut Self {self.extend(TokenTree::from(lit))}
221
222 pub fn push_group(&mut self, delim: Delimiter) -> &mut Self {
223 self.groups.push((delim, TokenStream::new()));
224 self
225 }
226
227 pub fn stack_as_string(&self) -> String {
228 let mut ret = String::new();
229 for i in (0..self.groups.len() - 1).rev() {
230 ret.push_str(&format!("Level {}: {}", i, self.groups[i].1.to_string()));
231 }
232 ret
233 }
234
235 pub fn pop_group(&mut self, delim: Delimiter) -> &mut Self {
236 if self.groups.len() < 2 {
237 eprintln!("Stack dump for error:\n{}", self.stack_as_string());
238 panic!("pop_group stack is empty {}", self.groups.len());
239 }
240 let ts = self.groups.pop().unwrap();
241 if ts.0 != delim {
242 eprintln!("Stack dump for error:\n{}", self.stack_as_string());
243 panic!("pop_group Delimiter mismatch, got {:?} expected {:?}", ts.0, delim);
244 }
245 self.extend(TokenTree::from(Group::new(delim, ts.1)));
246 self
247 }
248}
249
250impl Default for TokenBuilder {
251 fn default() -> Self {
252 Self::new()
253 }
254}
255
256pub trait IdentifyLast: Iterator + Sized {
257 fn identify_last(self) -> Iter<Self>;
258}
259
260impl<It> IdentifyLast for It where It: Iterator {
261 fn identify_last(mut self) -> Iter<Self> {
262 let e = self.next();
263 Iter {
264 iter: self,
265 buffer: e,
266 }
267 }
268}
269
270pub struct Iter<It> where It: Iterator {
271 iter: It,
272 buffer: Option<It::Item>,
273}
274
275#[derive(Debug)]
276pub struct Attribute {
277 pub name: String,
278 pub args: Option<TokenStream>
279}
280
281pub struct StructField {
282 pub name: String,
283 pub ty: TokenStream,
284 pub attrs: Vec<Attribute>
285}
286
287impl<It> Iterator for Iter<It> where It: Iterator {
288 type Item = (bool, It::Item);
289
290 fn next(&mut self) -> Option<Self::Item> {
291 match self.buffer.take() {
292 None => None,
293 Some(e) => {
294 match self.iter.next() {
295 None => Some((true, e)),
296 Some(f) => {
297 self.buffer = Some(f);
298 Some((false, e))
299 },
300 }
301 },
302 }
303 }
304}
305
306pub struct TokenParser {
307 iter_stack: Vec<IntoIter>,
308 pub current: Option<TokenTree>
309}
310
311impl TokenParser {
314 pub fn new(start: TokenStream) -> Self {
315 let mut ret = Self {iter_stack: vec![start.into_iter()], current: None};
316 ret.advance();
317 ret
318 }
319
320 pub fn advance(&mut self) {
321 let last = self.iter_stack.last_mut().unwrap();
322 let value = last.next();
323 if let Some(tok) = value {
324 self.current = Some(tok);
325 }
326 else {
327 self.current = None;
328 }
329 }
332
333 pub fn unexpected(&self) -> TokenStream {
334 error("Unexpected token")
335 }
336
337 pub fn is_delim(&mut self, delim: Delimiter) -> bool {
338 if let Some(TokenTree::Group(group)) = &self.current {
339 group.delimiter() == delim
340 }
341 else {
342 false
343 }
344 }
345
346 pub fn is_brace(&mut self) -> bool {
347 self.is_delim(Delimiter::Brace)
348 }
349
350 pub fn is_paren(&mut self) -> bool {
351 self.is_delim(Delimiter::Parenthesis)
352 }
353
354 pub fn is_bracket(&mut self) -> bool {
355 self.is_delim(Delimiter::Bracket)
356 }
357
358 pub fn open_delim(&mut self, delim: Delimiter) -> bool {
359 if let Some(TokenTree::Group(group)) = &self.current {
360 if group.delimiter() == delim {
361 self.iter_stack.push(group.stream().into_iter());
362 self.advance();
363 return true
364 }
365 }
366 false
367 }
368
369 pub fn is_group_with_delim(&mut self, delim: Delimiter) -> bool {
370 if let Some(TokenTree::Group(group)) = &self.current {
371 delim == group.delimiter()
372 }
373 else {
374 false
375 }
376 }
377
378 pub fn open_group(&mut self) -> Option<Delimiter> {
379 if let Some(TokenTree::Group(group)) = &self.current {
380 let delim = group.delimiter();
381 self.iter_stack.push(group.stream().into_iter());
382 self.advance();
383 return Some(delim)
384 }
385 None
386 }
387
388 pub fn open_brace(&mut self) -> bool {
389 self.open_delim(Delimiter::Brace)
390 }
391
392 pub fn open_paren(&mut self) -> bool {
393 self.open_delim(Delimiter::Parenthesis)
394 }
395
396 pub fn open_bracket(&mut self) -> bool {
397 self.open_delim(Delimiter::Bracket)
398 }
399
400 pub fn is_eot(&mut self) -> bool {
401 self.current.is_none() && !self.iter_stack.is_empty()
402 }
403
404 pub fn eat_eot(&mut self) -> bool {
405 if self.is_eot() {
407 self.iter_stack.pop();
408 if !self.iter_stack.is_empty() {
409 self.advance()
410 }
411 return true;
412 }
413 false
414 }
415
416 pub fn eat_level(&mut self) -> TokenStream {
417 let mut tb = TokenBuilder::new();
418 while !self.eat_eot() {
419 tb.extend(self.current.clone().unwrap());
420 self.advance();
421 }
422 tb.end()
423 }
424
425 pub fn eat_level_or_punct(&mut self, what: char) -> TokenStream {
426 let mut tb = TokenBuilder::new();
427 while !self.eat_eot() {
428 if self.is_punct_alone(what) {
429 self.advance();
430 return tb.end();
431 }
432 tb.extend(self.current.clone().unwrap());
433 self.advance();
434 }
435 tb.end()
436 }
437
438 pub fn eat_ident(&mut self, what: &str) -> bool {
439 if let Some(TokenTree::Ident(ident)) = &self.current {
441 if ident.to_string() == what {
442 self.advance();
443 return true
444 }
445 }
446 false
447 }
448
449 pub fn is_literal(&mut self) -> bool {
450 if let Some(TokenTree::Literal(_)) = &self.current {
452 return true
453 }
454 false
455 }
456
457 pub fn eat_literal(&mut self) -> Option<Literal> {
458 if let Some(TokenTree::Literal(lit)) = &self.current {
460 let ret = Some(lit.clone());
461 self.advance();
462 return ret
463 }
464 None
465 }
466
467 pub fn span(&self) -> Option<Span> {
468 self.current.as_ref().map(|current| current.span())
469 }
470
471 pub fn is_punct_alone(&mut self, what: char) -> bool {
472 if let Some(TokenTree::Punct(current)) = &self.current {
474 if current.as_char() == what && (current.as_char() == '>' || current.spacing() == Spacing::Alone) {
475 return true
476 }
477 }
478 false
479 }
480
481 pub fn is_punct_any(&mut self, what: char) -> bool {
482 if let Some(TokenTree::Punct(current)) = &self.current {
484 if current.as_char() == what {
485 return true
486 }
487 }
488 false
489 }
490
491
492 pub fn eat_double_colon_destruct(&mut self) -> bool {
493 if let Some(TokenTree::Punct(current)) = &self.current {
495 if current.as_char() == ':' && current.spacing() == Spacing::Joint {
496 self.advance();
497 if let Some(TokenTree::Punct(current)) = &self.current {
498 if current.as_char() == ':' && current.spacing() == Spacing::Alone {
499 self.advance();
500 return true
501 }
502 }
503 }
504 }
505 false
506 }
507
508 pub fn eat_sep(&mut self) -> bool {
509 if let Some(TokenTree::Punct(current)) = &self.current {
511 if current.as_char() == ':' && current.spacing() == Spacing::Joint {
512 self.advance();
513 if let Some(TokenTree::Punct(current)) = &self.current {
514 if current.as_char() == ':' && current.spacing() == Spacing::Alone {
515 self.advance();
516 return true
517 }
518 }
519 }
520 }
521 false
522 }
523
524 pub fn eat_punct_alone(&mut self, what: char) -> bool {
525 if self.is_punct_alone(what) {
526 self.advance();
527 return true
528 }
529 false
530 }
531
532 pub fn eat_punct_any(&mut self, what: char) -> bool {
533 if self.is_punct_any(what) {
534 self.advance();
535 return true
536 }
537 false
538 }
539
540 pub fn eat_any_punct(&mut self) -> Option<String> {
541 let mut out = String::new();
542 while let Some(TokenTree::Punct(current)) = &self.current {
543 out.push(current.as_char());
544 if current.spacing() == Spacing::Alone {
545 self.advance();
546 return Some(out);
547 }
548 self.advance();
549 }
550 None
551 }
552
553 pub fn eat_any_ident(&mut self) -> Option<String> {
554 if let Some(TokenTree::Ident(ident)) = &self.current {
555 let ret = Some(ident.to_string());
556 self.advance();
557 return ret
558 }
559 None
560 }
561
562 pub fn eat_any_ident_with_span(&mut self) -> Option<(String, Span)> {
563 if let Some(TokenTree::Ident(ident)) = &self.current {
564 let ret = Some((ident.to_string(), self.span().unwrap()));
565 self.advance();
566 return ret
567 }
568 None
569 }
570
571 pub fn expect_any_ident(&mut self) -> Result<String, TokenStream> {
572 if let Some(TokenTree::Ident(ident)) = &self.current {
573 let ret = ident.to_string();
574 self.advance();
575 return Ok(ret)
576 }
577 Err(error("Expected any ident"))
578 }
579
580
581 pub fn expect_punct_alone(&mut self, what: char) -> Result<(), TokenStream> {
582 if self.is_punct_alone(what) {
583 self.advance();
584 Ok(())
585 }
586 else {
587 Err(error(&format!("Expected punct {}", what)))
588 }
589 }
590
591 pub fn expect_punct_any(&mut self, what: char) -> Result<(), TokenStream> {
592 if self.is_punct_any(what) {
593 self.advance();
594 Ok(())
595 }
596 else {
597 Err(error(&format!("Expected punct {}", what)))
598 }
599 }
600
601 pub fn eat_ident_path(&mut self) -> Option<TokenStream> {
602 let mut tb = TokenBuilder::new();
603 while let Some(ident) = self.eat_any_ident() {
604 tb.ident(&ident);
605 if !self.eat_sep() {
606 break
607 }
608 tb.sep();
609 }
610
611 let ts = tb.end();
612 if !ts.is_empty() {
613 return Some(ts)
614 }
615 None
616 }
617
618 pub fn eat_where_clause(&mut self, add_where: Option<&str>) -> Option<TokenStream> {
619 let mut tb = TokenBuilder::new();
620 if self.eat_ident("where") {
621 tb.add("where");
622 loop {
624 if let Some(ident) = self.eat_any_ident() {
625 tb.ident(&ident);
626 tb.stream(self.eat_generic());
627
628 if !self.eat_punct_alone(':') {
629 return None
630 }
631 tb.add(":");
632 loop {
633 if let Some(ident) = self.eat_any_ident() {
634 tb.add(&ident);
635 tb.stream(self.eat_generic());
636 if self.eat_punct_alone('+') {
639 tb.add("+");
640 continue
641 }
642 if self.eat_punct_alone(',') { if let Some(add_where) = add_where {
644 tb.add("+");
645 tb.ident(add_where);
646 }
647 tb.add(",");
648 break
649 }
650 if self.is_brace() || self.is_punct_alone(';') { if let Some(add_where) = add_where {
652 tb.add("+");
653 tb.ident(add_where);
654 }
655 return Some(tb.end())
656 }
657 }
658 else {
659 return None }
661 }
662 }
663 else {
664 return None }
666 }
667 }
668 None
669 }
670
671 pub fn eat_struct_field(&mut self) -> Option<StructField> {
672 let attrs = self.eat_attributes();
674
675 self.eat_ident("pub");
676 if let Some(field) = self.eat_any_ident() {
677 if self.eat_punct_alone(':') {
678 if let Some(ty) = self.eat_type() {
679 return Some(StructField {name: field, ty, attrs})
680 }
681 }
682 }
683 None
684 }
685
686 pub fn eat_attributes(&mut self) -> Vec<Attribute> {
687 let mut results = Vec::new();
688 while self.eat_punct_alone('#') { if !self.open_bracket() {
690 break;
691 }
692 let mut assign_form = false;
693 while let Some(ident) = self.eat_any_ident() {
694 if self.eat_punct_alone('=') {
696 let level = self.eat_level();
697 results.push(Attribute {name: ident, args: Some(level)});
698 assign_form = true;
700 break;
701 }
702 if !self.open_paren() && !self.open_brace() {
703 results.push(Attribute {name: ident, args: None});
704 break;
705 }
706 results.push(Attribute {name: ident, args: Some(self.eat_level())});
708 self.eat_punct_alone(',');
709 }
710 if !assign_form && !self.eat_eot() {
711 break
712 }
713 }
714 results
715 }
716
717 pub fn eat_all_struct_fields(&mut self,) -> Option<Vec<StructField >> {
718
719 if self.open_brace() {
720 let mut fields = Vec::new();
721 while !self.eat_eot() {
722 if let Some(sf) = self.eat_struct_field() {
724 fields.push(sf);
725 self.eat_punct_alone(',');
726 }
727 else {
728 return None
729 }
730 }
731 return Some(fields)
732 }
733 None
734 }
735
736
737 pub fn eat_generic(&mut self) -> Option<TokenStream> {
738 let mut tb = TokenBuilder::new();
739 if self.eat_punct_alone('<') {
742 tb.add("<");
743 let mut stack = 1;
744 while stack > 0 {
746 if self.eat_punct_alone('<') {
747 tb.add("<");
748 stack += 1;
749 }
750 if self.eat_punct_alone('>') {
751 tb.add(">");
752 stack -= 1;
753 }
754 else if self.eat_eot() { return None
756 }
757 else { if let Some(current) = &self.current {
759 tb.extend(current.clone());
760 }
761 self.advance();
762 }
763 }
764
765 return Some(tb.end())
766 }
767 None
768 }
769
770 pub fn eat_all_types(&mut self) -> Option<Vec<TokenStream >> {
771 if self.open_paren() {
772 let mut ret = Vec::new();
773 while !self.eat_eot() {
774 self.eat_ident("pub");
775 if let Some(tt) = self.eat_type() {
776 ret.push(tt);
777 self.eat_punct_alone(',');
778 }
779 else {
780 return None
781 }
782 }
783 Some(ret)
784 }
785 else {
786 None
787 }
788 }
789
790 pub fn eat_type(&mut self) -> Option<TokenStream> {
791 let mut tb = TokenBuilder::new();
792 if self.eat_punct_alone('&'){
793 tb.add("&");
794 if self.eat_punct_any('\''){
795 tb.lifetime_mark();
796 if let Some((ty, span)) = self.eat_any_ident_with_span() {
797 tb.ident_with_span(&ty, span);
798 }
799 }
800 }
801 if self.open_bracket() { tb.add("[");
803 while !self.eat_eot() {
804 if let Some(current) = &self.current {
805 tb.extend(current.clone());
806 }
807 self.advance();
808 }
809 tb.add("]");
810 return Some(tb.end())
811 }
812 else if self.open_paren() { tb.add("(");
814 while !self.eat_eot() {
815 tb.stream(self.eat_type());
816 self.eat_punct_alone(',');
817 }
818 tb.add(")");
819 return Some(tb.end());
820 }
821 else if let Some((ty, span)) = self.eat_any_ident_with_span() {
822 tb.ident_with_span(&ty, span);
823 if ty == "dyn" {
824 if let Some((ty, span)) = self.eat_any_ident_with_span() {
825 tb.ident_with_span(&ty, span);
826 }
827 }
828 tb.stream(self.eat_generic());
829 return Some(tb.end())
830 }
831 None
832 }
833
834}
835