Skip to content

Commit 114e740

Browse files
committed
WIP
1 parent f0dd1ac commit 114e740

File tree

1 file changed

+178
-91
lines changed

1 file changed

+178
-91
lines changed

library/proc_macro/src/quote.rs

Lines changed: 178 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
//! items from `proc_macro`, to build a `proc_macro::TokenStream`.
66
77
use core::iter::Peekable;
8+
89
use crate::{
910
BitOr, Delimiter, Group, Ident, Literal, Punct, Spacing, Span, ToTokens, TokenStream, TokenTree,
1011
};
@@ -545,7 +546,10 @@ fn collect_meta_vars(content_stream: TokenStream) -> Vec<Ident> {
545546
}
546547

547548
// fn consume_dollar_group(content_stream: TokenStream, iter: &mut Peekable<impl Iterator<Item = TokenTree>>) -> TokenStream {
548-
fn consume_dollar_group(content_stream: TokenStream, iter: &mut Peekable<crate::token_stream::IntoIter>) -> TokenStream {
549+
fn consume_dollar_group(
550+
content_stream: TokenStream,
551+
iter: &mut Peekable<crate::token_stream::IntoIter>,
552+
) -> TokenStream {
549553
let mut tokens = crate::TokenStream::new();
550554

551555
let mut sep_cand = Vec::new();
@@ -559,23 +563,28 @@ fn consume_dollar_group(content_stream: TokenStream, iter: &mut Peekable<crate::
559563
// sep内の$-GROUPに*が結合する場合は、このGruopは単なるTokenStreamとして扱う。(after_dollar=falseとして処理なので、再呼び出しでいい。)
560564
// そうではない場合は、このGruopはrepで処理する。
561565
loop {
562-
match (iter.next(), iter.peek()) { // *=*
566+
match (iter.next(), iter.peek()) {
567+
// *=*
563568

564569
// 1. starを消費する。
565570
// *= じゃない *: nestしたほうがきれいかも。
566571
(Some(TokenTree::Punct(star)), opt)
567-
if star.as_char() == '*' && !matches!(opt, Some(TokenTree::Punct(_))) => {
572+
if star.as_char() == '*' && !matches!(opt, Some(TokenTree::Punct(_))) =>
573+
{
568574
eprintln!("DEBUG1");
569-
let sep_opt: Option<TokenStream> = (!sep_cand.is_empty()).then(|| sep_cand.into_iter().collect::<TokenStream>());
575+
let sep_opt: Option<TokenStream> =
576+
(!sep_cand.is_empty()).then(|| sep_cand.into_iter().collect::<TokenStream>());
570577

571578
expand_dollar_group(current_contents.clone(), sep_opt).to_tokens(&mut tokens);
572579
break;
573-
574580
}
575581
(Some(TokenTree::Punct(star)), Some(TokenTree::Punct(not_assign)))
576-
if star.as_char() == '*' && !(star.spacing() == Spacing::Joint && not_assign.as_char() == '=') => {
582+
if star.as_char() == '*'
583+
&& !(star.spacing() == Spacing::Joint && not_assign.as_char() == '=') =>
584+
{
577585
eprintln!("DEBUG1");
578-
let sep_opt: Option<TokenStream> = (!sep_cand.is_empty()).then(|| sep_cand.into_iter().collect::<TokenStream>());
586+
let sep_opt: Option<TokenStream> =
587+
(!sep_cand.is_empty()).then(|| sep_cand.into_iter().collect::<TokenStream>());
579588
// let sep_opt: Option<TokenStream> = (!sep_cand.is_empty()).then(|| minimal_quote_ts!((@ sep_cand.into_iter().collect::<TokenStream>())).into());
580589

581590
// let t = sep_cand.into_iter().collect::<TokenStream>();
@@ -588,9 +597,11 @@ fn consume_dollar_group(content_stream: TokenStream, iter: &mut Peekable<crate::
588597

589598
// 2. starの前に$groupを見つけた場合は、現在の$groupをリテラル通り先に消費して、次の$groupからの処理に移る。
590599
(Some(TokenTree::Punct(dollar)), Some(TokenTree::Group(next_group)))
591-
if dollar.as_char() == '$' => {
600+
if dollar.as_char() == '$' =>
601+
{
592602
// 現在の$groupに*がないのが確定
593-
minimal_quote!((@ TokenTree::from(Punct::new('$', Spacing::Joint)))).to_tokens(&mut tokens); // $
603+
minimal_quote!((@ TokenTree::from(Punct::new('$', Spacing::Joint))))
604+
.to_tokens(&mut tokens); // $
594605
// quote([tree].into_iter().collect::<TokenStream>()).to_tokens(&mut tokens); // group
595606
// quote(stream.clone()).to_to\
596607
// XXX sep_candの処理が必要。
@@ -610,8 +621,7 @@ fn consume_dollar_group(content_stream: TokenStream, iter: &mut Peekable<crate::
610621

611622
// sep候補を追加する。ただし、groupは一回だけ許容。punct列も既知の演算の場合だけ一回認められる。多分declマクロで処理したほうがいい。sep_candと合わせて最大3つみれるから、それでクリアできる気がする。
612623
// !matches!(x, TokenTree::Group(_))
613-
(Some(x), _) if !flag =>
614-
{
624+
(Some(x), _) if !flag => {
615625
eprintln!("DEBUG2: XXXXXXXXXXXXXXXXX");
616626
sep_cand.push(x.clone());
617627
flag = judge(sep_cand.as_slice());
@@ -622,34 +632,37 @@ fn consume_dollar_group(content_stream: TokenStream, iter: &mut Peekable<crate::
622632

623633
// 現在の$Groupをstarなしでする。
624634
// 次の$Groupでここに来た場合は、tokenstreamに再度くっつけないとだめ。なさそう。
625-
(x, _) =>
626-
{
635+
(x, _) => {
627636
eprintln!("DEBUG3: XXXXXXXXXXXXXXXXX");
628637

629-
minimal_quote!((@ TokenTree::from(Punct::new('$', Spacing::Joint)))).to_tokens(&mut tokens);
638+
minimal_quote!((@ TokenTree::from(Punct::new('$', Spacing::Joint))))
639+
.to_tokens(&mut tokens);
630640

631641
eprintln!("DEBUG3.1: XXXXXXXXXXXXXXXXX");
632642

633643
quote(
634-
[TokenTree::Group(Group::new(Delimiter::Brace, current_contents.clone()))].into_iter().collect::<TokenStream>()
635-
).to_tokens(&mut tokens);
644+
[TokenTree::Group(Group::new(Delimiter::Brace, current_contents.clone()))]
645+
.into_iter()
646+
.collect::<TokenStream>(),
647+
)
648+
.to_tokens(&mut tokens);
636649
eprintln!("DEBUG3.2: XXXXXXXXXXXXXXXXX");
637650

638-
let sep_opt: Option<TokenStream> = (!sep_cand.is_empty()).then(|| sep_cand.clone().into_iter().collect::<TokenStream>());
651+
let sep_opt: Option<TokenStream> = (!sep_cand.is_empty())
652+
.then(|| sep_cand.clone().into_iter().collect::<TokenStream>());
639653
sep_opt.into_iter().for_each(|sep| {
640-
quote(sep).to_tokens(&mut tokens);
641-
});
654+
quote(sep).to_tokens(&mut tokens);
655+
});
642656

643657
let mut new_stream = x.into_iter().collect::<TokenStream>();
644658
new_stream.extend(iter.by_ref());
645659
*iter = new_stream.into_iter().peekable();
646660

647661
eprintln!("DEBUG3.3: XXXXXXXXXXXXXXXXX");
648662

649-
break
663+
break;
650664
}
651665
}
652-
653666
}
654667

655668
return tokens;
@@ -662,98 +675,172 @@ fn judge(ts: &[TokenTree]) -> bool {
662675
match ts {
663676
[TokenTree::Ident(_)] => true,
664677
[TokenTree::Punct(t1), TokenTree::Punct(t2)]
665-
if t1.as_char() == ':' && t2.as_char() == ':' => true,
678+
if t1.as_char() == ':' && t1.spacing() == Spacing::Joint && t2.as_char() == ':' =>
679+
{
680+
true
681+
}
666682
[TokenTree::Group(_)] => true,
667-
[TokenTree::Punct(t1)]
668-
if t1.as_char() == '#' => true,
669-
[TokenTree::Punct(t1)]
670-
if t1.as_char() == ',' => true,
671-
[TokenTree::Punct(t1)]
672-
if t1.as_char() == '.' => true,
673-
[TokenTree::Punct(t1)]
674-
if t1.as_char() == ';' => true,
675-
[TokenTree::Punct(t1)]
676-
if t1.as_char() == ':' => true,
677-
[TokenTree::Punct(t1)]
678-
if t1.as_char() == '+' => true,
683+
[TokenTree::Punct(t1)] if t1.as_char() == '#' => true,
684+
[TokenTree::Punct(t1)] if t1.as_char() == ',' => true,
685+
[TokenTree::Punct(t1)] if t1.as_char() == '.' => true,
686+
[TokenTree::Punct(t1)] if t1.as_char() == ';' => true,
687+
[TokenTree::Punct(t1)] if t1.as_char() == ':' => true,
688+
[TokenTree::Punct(t1)] if t1.as_char() == '+' => true,
679689
[TokenTree::Punct(t1), TokenTree::Punct(t2)]
680-
if t1.as_char() == '+' && t2.as_char() == '=' => true,
681-
[TokenTree::Punct(t1)]
682-
if t1.as_char() == '&' => true,
690+
if t1.as_char() == '+' && t1.spacing() == Spacing::Joint && t2.as_char() == '=' =>
691+
{
692+
true
693+
}
694+
[TokenTree::Punct(t1)] if t1.as_char() == '&' => true,
683695
[TokenTree::Punct(t1), TokenTree::Punct(t2)]
684-
if t1.as_char() == '&' && t2.as_char() == '&' => true,
696+
if t1.as_char() == '&' && t1.spacing() == Spacing::Joint && t2.as_char() == '&' =>
697+
{
698+
true
699+
}
685700
[TokenTree::Punct(t1), TokenTree::Punct(t2)]
686-
if t1.as_char() == '&' && t2.as_char() == '=' => true,
687-
[TokenTree::Punct(t1)]
688-
if t1.as_char() == '@' => true,
689-
[TokenTree::Punct(t1)]
690-
if t1.as_char() == '!' => true,
691-
[TokenTree::Punct(t1)]
692-
if t1.as_char() == '^' => true,
701+
if t1.as_char() == '&' && t1.spacing() == Spacing::Joint && t2.as_char() == '=' =>
702+
{
703+
true
704+
}
705+
[TokenTree::Punct(t1)] if t1.as_char() == '@' => true,
706+
[TokenTree::Punct(t1)] if t1.as_char() == '!' => true,
707+
[TokenTree::Punct(t1)] if t1.as_char() == '^' => true,
693708
[TokenTree::Punct(t1), TokenTree::Punct(t2)]
694-
if t1.as_char() == '^' && t2.as_char() == '=' => true,
695-
[TokenTree::Punct(t1)]
696-
if t1.as_char() == '/' => true,
709+
if t1.as_char() == '^' && t1.spacing() == Spacing::Joint && t2.as_char() == '=' =>
710+
{
711+
true
712+
}
713+
[TokenTree::Punct(t1)] if t1.as_char() == '/' => true,
697714
[TokenTree::Punct(t1), TokenTree::Punct(t2)]
698-
if t1.as_char() == '/' && t2.as_char() == '=' => true,
715+
if t1.as_char() == '/' && t1.spacing() == Spacing::Joint && t2.as_char() == '=' =>
716+
{
717+
true
718+
}
699719
[TokenTree::Punct(t1), TokenTree::Punct(t2)]
700-
if t1.as_char() == '.' && t2.as_char() == '.' => true,
720+
if t1.as_char() == '.' && t1.spacing() == Spacing::Joint && t2.as_char() == '.' =>
721+
{
722+
true
723+
}
701724
[TokenTree::Punct(t1), TokenTree::Punct(t2), TokenTree::Punct(t3)]
702-
if t1.as_char() == '.' && t2.as_char() == '.' && t3.as_char() == '.' => true,
725+
if t1.as_char() == '.'
726+
&& t1.spacing() == Spacing::Joint
727+
&& t2.as_char() == '.'
728+
&& t2.spacing() == Spacing::Joint
729+
&& t3.as_char() == '.' =>
730+
{
731+
true
732+
}
703733
[TokenTree::Punct(t1), TokenTree::Punct(t2), TokenTree::Punct(t3)]
704-
if t1.as_char() == '.' && t2.as_char() == '.' && t3.as_char() == '=' => true,
705-
[TokenTree::Punct(t1)]
706-
if t1.as_char() == '=' => true,
734+
if t1.as_char() == '.'
735+
&& t1.spacing() == Spacing::Joint
736+
&& t2.as_char() == '.'
737+
&& t2.spacing() == Spacing::Joint
738+
&& t3.as_char() == '=' =>
739+
{
740+
true
741+
}
742+
[TokenTree::Punct(t1)] if t1.as_char() == '=' => true,
707743
[TokenTree::Punct(t1), TokenTree::Punct(t2)]
708-
if t1.as_char() == '=' && t2.as_char() == '=' => true,
744+
if t1.as_char() == '=' && t1.spacing() == Spacing::Joint && t2.as_char() == '=' =>
745+
{
746+
true
747+
}
709748
[TokenTree::Punct(t1), TokenTree::Punct(t2)]
710-
if t1.as_char() == '>' && t2.as_char() == '=' => true,
711-
[TokenTree::Punct(t1)]
712-
if t1.as_char() == '>' => true,
749+
if t1.as_char() == '>' && t1.spacing() == Spacing::Joint && t2.as_char() == '=' =>
750+
{
751+
true
752+
}
753+
[TokenTree::Punct(t1)] if t1.as_char() == '>' => true,
713754
[TokenTree::Punct(t1), TokenTree::Punct(t2)]
714-
if t1.as_char() == '<' && t2.as_char() == '=' => true,
715-
[TokenTree::Punct(t1)]
716-
if t1.as_char() == '<' => true,
755+
if t1.as_char() == '<' && t1.spacing() == Spacing::Joint && t2.as_char() == '=' =>
756+
{
757+
true
758+
}
759+
[TokenTree::Punct(t1)] if t1.as_char() == '<' => true,
717760
[TokenTree::Punct(t1), TokenTree::Punct(t2)]
718-
if t1.as_char() == '*' && t2.as_char() == '=' => true,
761+
if t1.as_char() == '*' && t1.spacing() == Spacing::Joint && t2.as_char() == '=' =>
762+
{
763+
true
764+
}
719765
[TokenTree::Punct(t1), TokenTree::Punct(t2)]
720-
if t1.as_char() == '!' && t2.as_char() == '=' => true,
721-
[TokenTree::Punct(t1)]
722-
if t1.as_char() == '|' => true,
766+
if t1.as_char() == '!' && t1.spacing() == Spacing::Joint && t2.as_char() == '=' =>
767+
{
768+
true
769+
}
770+
[TokenTree::Punct(t1)] if t1.as_char() == '|' => true,
723771
[TokenTree::Punct(t1), TokenTree::Punct(t2)]
724-
if t1.as_char() == '|' && t2.as_char() == '=' => true,
772+
if t1.as_char() == '|' && t1.spacing() == Spacing::Joint && t2.as_char() == '=' =>
773+
{
774+
true
775+
}
725776
[TokenTree::Punct(t1), TokenTree::Punct(t2)]
726-
if t1.as_char() == '|' && t2.as_char() == '|' => true,
727-
[TokenTree::Punct(t1)]
728-
if t1.as_char() == '?' => true,
777+
if t1.as_char() == '|' && t1.spacing() == Spacing::Joint && t2.as_char() == '|' =>
778+
{
779+
true
780+
}
781+
[TokenTree::Punct(t1)] if t1.as_char() == '?' => true,
729782
[TokenTree::Punct(t1), TokenTree::Punct(t2)]
730-
if t1.as_char() == '-' && t2.as_char() == '>' => true,
783+
if t1.as_char() == '-' && t1.spacing() == Spacing::Joint && t2.as_char() == '>' =>
784+
{
785+
true
786+
}
731787
[TokenTree::Punct(t1), TokenTree::Punct(t2)]
732-
if t1.as_char() == '<' && t2.as_char() == '-' => true,
733-
[TokenTree::Punct(t1)]
734-
if t1.as_char() == '%' => true,
788+
if t1.as_char() == '<' && t1.spacing() == Spacing::Joint && t2.as_char() == '-' =>
789+
{
790+
true
791+
}
792+
[TokenTree::Punct(t1)] if t1.as_char() == '%' => true,
735793
[TokenTree::Punct(t1), TokenTree::Punct(t2)]
736-
if t1.as_char() == '%' && t2.as_char() == '=' => true,
794+
if t1.as_char() == '%' && t1.spacing() == Spacing::Joint && t2.as_char() == '=' =>
795+
{
796+
true
797+
}
737798
[TokenTree::Punct(t1), TokenTree::Punct(t2)]
738-
if t1.as_char() == '=' && t2.as_char() == '>' => true,
799+
if t1.as_char() == '=' && t1.spacing() == Spacing::Joint && t2.as_char() == '>' =>
800+
{
801+
true
802+
}
739803
[TokenTree::Punct(t1), TokenTree::Punct(t2)]
740-
if t1.as_char() == '<' && t2.as_char() == '<' => true,
804+
if t1.as_char() == '<' && t1.spacing() == Spacing::Joint && t2.as_char() == '<' =>
805+
{
806+
true
807+
}
741808
[TokenTree::Punct(t1), TokenTree::Punct(t2), TokenTree::Punct(t3)]
742-
if t1.as_char() == '<' && t2.as_char() == '<' && t3.as_char() == '=' => true,
809+
if t1.as_char() == '<'
810+
&& t1.spacing() == Spacing::Joint
811+
&& t2.as_char() == '<'
812+
&& t2.spacing() == Spacing::Joint
813+
&& t3.as_char() == '=' =>
814+
{
815+
true
816+
}
743817
[TokenTree::Punct(t1), TokenTree::Punct(t2)]
744-
if t1.as_char() == '>' && t2.as_char() == '>' => true,
818+
if t1.as_char() == '>' && t1.spacing() == Spacing::Joint && t2.as_char() == '>' =>
819+
{
820+
true
821+
}
745822
[TokenTree::Punct(t1), TokenTree::Punct(t2), TokenTree::Punct(t3)]
746-
if t1.as_char() == '>' && t2.as_char() == '>' && t3.as_char() == '=' => true,
747-
[TokenTree::Punct(t1)]
748-
if t1.as_char() == '*' => true,
749-
[TokenTree::Punct(t1)]
750-
if t1.as_char() == '-' => true,
823+
if t1.as_char() == '>'
824+
&& t1.spacing() == Spacing::Joint
825+
&& t2.as_char() == '>'
826+
&& t2.spacing() == Spacing::Joint
827+
&& t3.as_char() == '=' =>
828+
{
829+
true
830+
}
831+
[TokenTree::Punct(t1)] if t1.as_char() == '*' => true,
832+
[TokenTree::Punct(t1)] if t1.as_char() == '-' => true,
751833
[TokenTree::Punct(t1), TokenTree::Punct(t2)]
752-
if t1.as_char() == '-' && t2.as_char() == '=' => true,
834+
if t1.as_char() == '-' && t1.spacing() == Spacing::Joint && t2.as_char() == '=' =>
835+
{
836+
true
837+
}
753838
[TokenTree::Punct(single_quote), TokenTree::Ident(_)]
754-
if single_quote.as_char() == '\'' => true,
755-
[TokenTree::Punct(t1)]
756-
if t1.as_char() == '_' => true,
839+
if single_quote.as_char() == '\'' && single_quote.spacing() == Spacing::Joint =>
840+
{
841+
true
842+
} // lifetime
843+
[TokenTree::Punct(t1)] if t1.as_char() == '_' => true,
757844
[_x] => true,
758845
_ => false,
759846
}
@@ -785,8 +872,7 @@ fn expand_dollar_group(contents: TokenStream, sep_opt: Option<TokenStream>) -> T
785872
)
786873
.to_tokens(&mut rep_expanded);
787874
}
788-
minimal_quote!(let _: crate::HasIterator = has_iter;)
789-
.to_tokens(&mut rep_expanded);
875+
minimal_quote!(let _: crate::HasIterator = has_iter;).to_tokens(&mut rep_expanded);
790876

791877
// Append the `while` to `REP_EXPANDED`.
792878
let mut while_body = TokenStream::new();
@@ -812,14 +898,15 @@ fn expand_dollar_group(contents: TokenStream, sep_opt: Option<TokenStream>) -> T
812898
})
813899
(@ quote(contents.clone())).to_tokens(&mut ts);
814900
)
815-
.to_tokens(&mut while_body); // tsに入れてるのは怪しい。
901+
.to_tokens(&mut while_body); // tsに入れてるのは怪しい。
816902
rep_expanded.extend(vec![
817903
TokenTree::Ident(Ident::new("while", Span::call_site())),
818904
TokenTree::Ident(Ident::new("true", Span::call_site())),
819905
TokenTree::Group(Group::new(Delimiter::Brace, while_body)),
820906
]);
821907

822-
minimal_quote!((@ TokenTree::Group(Group::new(Delimiter::Brace, rep_expanded)))).to_tokens(&mut tokens);
908+
minimal_quote!((@ TokenTree::Group(Group::new(Delimiter::Brace, rep_expanded))))
909+
.to_tokens(&mut tokens);
823910
return tokens;
824911
}
825912

0 commit comments

Comments
 (0)