40
40
#![ feature( lang_items) ]
41
41
#![ feature( optin_builtin_traits) ]
42
42
43
- #[ macro_use]
44
43
extern crate syntax;
45
44
extern crate syntax_pos;
46
45
extern crate rustc_errors;
@@ -156,7 +155,7 @@ impl IntoIterator for TokenStream {
156
155
type IntoIter = TokenTreeIter ;
157
156
158
157
fn into_iter ( self ) -> TokenTreeIter {
159
- TokenTreeIter { cursor : self . 0 . trees ( ) , next : None }
158
+ TokenTreeIter { cursor : self . 0 . trees ( ) , stack : Vec :: new ( ) }
160
159
}
161
160
}
162
161
@@ -554,7 +553,7 @@ impl Literal {
554
553
#[ unstable( feature = "proc_macro" , issue = "38356" ) ]
555
554
pub struct TokenTreeIter {
556
555
cursor : tokenstream:: Cursor ,
557
- next : Option < tokenstream :: TokenStream > ,
556
+ stack : Vec < TokenTree > ,
558
557
}
559
558
560
559
#[ unstable( feature = "proc_macro" , issue = "38356" ) ]
@@ -563,9 +562,10 @@ impl Iterator for TokenTreeIter {
563
562
564
563
fn next ( & mut self ) -> Option < TokenTree > {
565
564
loop {
566
- let next =
567
- unwrap_or ! ( self . next. take( ) . or_else( || self . cursor. next_as_stream( ) ) , return None ) ;
568
- let tree = TokenTree :: from_internal ( next, & mut self . next ) ;
565
+ let tree = self . stack . pop ( ) . or_else ( || {
566
+ let next = self . cursor . next_as_stream ( ) ?;
567
+ Some ( TokenTree :: from_internal ( next, & mut self . stack ) )
568
+ } ) ?;
569
569
if tree. span . 0 == DUMMY_SP {
570
570
if let TokenNode :: Group ( Delimiter :: None , stream) = tree. kind {
571
571
self . cursor . insert ( stream. 0 ) ;
@@ -598,12 +598,12 @@ impl Delimiter {
598
598
}
599
599
600
600
impl TokenTree {
601
- fn from_internal ( stream : tokenstream:: TokenStream , next : & mut Option < tokenstream :: TokenStream > )
601
+ fn from_internal ( stream : tokenstream:: TokenStream , stack : & mut Vec < TokenTree > )
602
602
-> TokenTree {
603
603
use syntax:: parse:: token:: * ;
604
604
605
605
let ( tree, is_joint) = stream. as_tree ( ) ;
606
- let ( mut span, token) = match tree {
606
+ let ( span, token) = match tree {
607
607
tokenstream:: TokenTree :: Token ( span, token) => ( span, token) ,
608
608
tokenstream:: TokenTree :: Delimited ( span, delimed) => {
609
609
let delimiter = Delimiter :: from_internal ( delimed. delim ) ;
@@ -615,34 +615,32 @@ impl TokenTree {
615
615
} ;
616
616
617
617
let op_kind = if is_joint { Spacing :: Joint } else { Spacing :: Alone } ;
618
- macro_rules! op {
619
- ( $op: expr) => { TokenNode :: Op ( $op, op_kind) }
620
- }
621
-
622
- macro_rules! joint {
623
- ( $first: expr, $rest: expr) => { joint( $first, $rest, is_joint, & mut span, next) }
618
+ macro_rules! tt {
619
+ ( $e: expr) => ( TokenTree { span: Span ( span) , kind: $e } )
624
620
}
625
-
626
- fn joint ( first : char , rest : Token , is_joint : bool , span : & mut syntax_pos:: Span ,
627
- next : & mut Option < tokenstream:: TokenStream > )
628
- -> TokenNode {
629
- let ( first_span, rest_span) = ( * span, * span) ;
630
- * span = first_span;
631
- let tree = tokenstream:: TokenTree :: Token ( rest_span, rest) ;
632
- * next = Some ( if is_joint { tree. joint ( ) } else { tree. into ( ) } ) ;
633
- TokenNode :: Op ( first, Spacing :: Joint )
621
+ macro_rules! op {
622
+ ( $a: expr) => ( TokenNode :: Op ( $a, op_kind) ) ;
623
+ ( $a: expr, $b: expr) => ( {
624
+ stack. push( tt!( TokenNode :: Op ( $b, op_kind) . into( ) ) ) ;
625
+ TokenNode :: Op ( $a, Spacing :: Joint )
626
+ } ) ;
627
+ ( $a: expr, $b: expr, $c: expr) => ( {
628
+ stack. push( tt!( TokenNode :: Op ( $c, op_kind) ) ) ;
629
+ stack. push( tt!( TokenNode :: Op ( $b, Spacing :: Joint ) ) ) ;
630
+ TokenNode :: Op ( $a, Spacing :: Joint )
631
+ } )
634
632
}
635
633
636
634
let kind = match token {
637
635
Eq => op ! ( '=' ) ,
638
636
Lt => op ! ( '<' ) ,
639
- Le => joint ! ( '<' , Eq ) ,
640
- EqEq => joint ! ( '=' , Eq ) ,
641
- Ne => joint ! ( '!' , Eq ) ,
642
- Ge => joint ! ( '>' , Eq ) ,
637
+ Le => op ! ( '<' , '=' ) ,
638
+ EqEq => op ! ( '=' , '=' ) ,
639
+ Ne => op ! ( '!' , '=' ) ,
640
+ Ge => op ! ( '>' , '=' ) ,
643
641
Gt => op ! ( '>' ) ,
644
- AndAnd => joint ! ( '&' , BinOp ( And ) ) ,
645
- OrOr => joint ! ( '|' , BinOp ( Or ) ) ,
642
+ AndAnd => op ! ( '&' , '&' ) ,
643
+ OrOr => op ! ( '|' , '|' ) ,
646
644
Not => op ! ( '!' ) ,
647
645
Tilde => op ! ( '~' ) ,
648
646
BinOp ( Plus ) => op ! ( '+' ) ,
@@ -653,37 +651,46 @@ impl TokenTree {
653
651
BinOp ( Caret ) => op ! ( '^' ) ,
654
652
BinOp ( And ) => op ! ( '&' ) ,
655
653
BinOp ( Or ) => op ! ( '|' ) ,
656
- BinOp ( Shl ) => joint ! ( '<' , Lt ) ,
657
- BinOp ( Shr ) => joint ! ( '>' , Gt ) ,
658
- BinOpEq ( Plus ) => joint ! ( '+' , Eq ) ,
659
- BinOpEq ( Minus ) => joint ! ( '-' , Eq ) ,
660
- BinOpEq ( Star ) => joint ! ( '*' , Eq ) ,
661
- BinOpEq ( Slash ) => joint ! ( '/' , Eq ) ,
662
- BinOpEq ( Percent ) => joint ! ( '%' , Eq ) ,
663
- BinOpEq ( Caret ) => joint ! ( '^' , Eq ) ,
664
- BinOpEq ( And ) => joint ! ( '&' , Eq ) ,
665
- BinOpEq ( Or ) => joint ! ( '|' , Eq ) ,
666
- BinOpEq ( Shl ) => joint ! ( '<' , Le ) ,
667
- BinOpEq ( Shr ) => joint ! ( '>' , Ge ) ,
654
+ BinOp ( Shl ) => op ! ( '<' , '<' ) ,
655
+ BinOp ( Shr ) => op ! ( '>' , '>' ) ,
656
+ BinOpEq ( Plus ) => op ! ( '+' , '=' ) ,
657
+ BinOpEq ( Minus ) => op ! ( '-' , '=' ) ,
658
+ BinOpEq ( Star ) => op ! ( '*' , '=' ) ,
659
+ BinOpEq ( Slash ) => op ! ( '/' , '=' ) ,
660
+ BinOpEq ( Percent ) => op ! ( '%' , '=' ) ,
661
+ BinOpEq ( Caret ) => op ! ( '^' , '=' ) ,
662
+ BinOpEq ( And ) => op ! ( '&' , '=' ) ,
663
+ BinOpEq ( Or ) => op ! ( '|' , '=' ) ,
664
+ BinOpEq ( Shl ) => op ! ( '<' , '<' , '=' ) ,
665
+ BinOpEq ( Shr ) => op ! ( '>' , '>' , '=' ) ,
668
666
At => op ! ( '@' ) ,
669
667
Dot => op ! ( '.' ) ,
670
- DotDot => joint ! ( '.' , Dot ) ,
671
- DotDotDot => joint ! ( '.' , DotDot ) ,
672
- DotDotEq => joint ! ( '.' , DotEq ) ,
668
+ DotDot => op ! ( '.' , '.' ) ,
669
+ DotDotDot => op ! ( '.' , '.' , '.' ) ,
670
+ DotDotEq => op ! ( '.' , '.' , '=' ) ,
673
671
Comma => op ! ( ',' ) ,
674
672
Semi => op ! ( ';' ) ,
675
673
Colon => op ! ( ':' ) ,
676
- ModSep => joint ! ( ':' , Colon ) ,
677
- RArrow => joint ! ( '-' , Gt ) ,
678
- LArrow => joint ! ( '<' , BinOp ( Minus ) ) ,
679
- FatArrow => joint ! ( '=' , Gt ) ,
674
+ ModSep => op ! ( ':' , ':' ) ,
675
+ RArrow => op ! ( '-' , '>' ) ,
676
+ LArrow => op ! ( '<' , '-' ) ,
677
+ FatArrow => op ! ( '=' , '>' ) ,
680
678
Pound => op ! ( '#' ) ,
681
679
Dollar => op ! ( '$' ) ,
682
680
Question => op ! ( '?' ) ,
683
681
684
682
Ident ( ident, false ) | Lifetime ( ident) => TokenNode :: Term ( Term ( ident. name ) ) ,
685
683
Ident ( ident, true ) => TokenNode :: Term ( Term ( Symbol :: intern ( & format ! ( "r#{}" , ident) ) ) ) ,
686
- Literal ( ..) | DocComment ( ..) => TokenNode :: Literal ( self :: Literal ( token) ) ,
684
+ Literal ( ..) => TokenNode :: Literal ( self :: Literal ( token) ) ,
685
+ DocComment ( c) => {
686
+ let stream = vec ! [
687
+ tt!( TokenNode :: Term ( Term :: intern( "doc" ) ) ) ,
688
+ tt!( op!( '=' ) ) ,
689
+ tt!( TokenNode :: Literal ( self :: Literal ( Literal ( Lit :: Str_ ( c) , None ) ) ) ) ,
690
+ ] . into_iter ( ) . collect ( ) ;
691
+ stack. push ( tt ! ( TokenNode :: Group ( Delimiter :: Bracket , stream) ) ) ;
692
+ op ! ( '#' )
693
+ }
687
694
688
695
Interpolated ( _) => {
689
696
__internal:: with_sess ( |( sess, _) | {
@@ -692,7 +699,7 @@ impl TokenTree {
692
699
} )
693
700
}
694
701
695
- DotEq => joint ! ( '.' , Eq ) ,
702
+ DotEq => op ! ( '.' , '=' ) ,
696
703
OpenDelim ( ..) | CloseDelim ( ..) => unreachable ! ( ) ,
697
704
Whitespace | Comment | Shebang ( ..) | Eof => unreachable ! ( ) ,
698
705
} ;
@@ -724,7 +731,29 @@ impl TokenTree {
724
731
} else { Ident ( ident, false ) } ;
725
732
return TokenTree :: Token ( self . span . 0 , token) . into ( ) ;
726
733
}
727
- TokenNode :: Literal ( token) => return TokenTree :: Token ( self . span . 0 , token. 0 ) . into ( ) ,
734
+ TokenNode :: Literal ( self :: Literal ( Literal ( Lit :: Integer ( ref a) , b) ) )
735
+ if a. as_str ( ) . starts_with ( "-" ) =>
736
+ {
737
+ let minus = BinOp ( BinOpToken :: Minus ) ;
738
+ let integer = Symbol :: intern ( & a. as_str ( ) [ 1 ..] ) ;
739
+ let integer = Literal ( Lit :: Integer ( integer) , b) ;
740
+ let a = TokenTree :: Token ( self . span . 0 , minus) ;
741
+ let b = TokenTree :: Token ( self . span . 0 , integer) ;
742
+ return vec ! [ a, b] . into_iter ( ) . collect ( )
743
+ }
744
+ TokenNode :: Literal ( self :: Literal ( Literal ( Lit :: Float ( ref a) , b) ) )
745
+ if a. as_str ( ) . starts_with ( "-" ) =>
746
+ {
747
+ let minus = BinOp ( BinOpToken :: Minus ) ;
748
+ let float = Symbol :: intern ( & a. as_str ( ) [ 1 ..] ) ;
749
+ let float = Literal ( Lit :: Float ( float) , b) ;
750
+ let a = TokenTree :: Token ( self . span . 0 , minus) ;
751
+ let b = TokenTree :: Token ( self . span . 0 , float) ;
752
+ return vec ! [ a, b] . into_iter ( ) . collect ( )
753
+ }
754
+ TokenNode :: Literal ( token) => {
755
+ return TokenTree :: Token ( self . span . 0 , token. 0 ) . into ( )
756
+ }
728
757
} ;
729
758
730
759
let token = match op {
0 commit comments