4040#![ feature( lang_items) ]
4141#![ feature( optin_builtin_traits) ]
4242
43- #[ macro_use]
4443extern crate syntax;
4544extern crate syntax_pos;
4645extern crate rustc_errors;
@@ -156,7 +155,7 @@ impl IntoIterator for TokenStream {
156155 type IntoIter = TokenTreeIter ;
157156
158157 fn into_iter ( self ) -> TokenTreeIter {
159- TokenTreeIter { cursor : self . 0 . trees ( ) , next : None }
158+ TokenTreeIter { cursor : self . 0 . trees ( ) , stack : Vec :: new ( ) }
160159 }
161160}
162161
@@ -554,7 +553,7 @@ impl Literal {
554553#[ unstable( feature = "proc_macro" , issue = "38356" ) ]
555554pub struct TokenTreeIter {
556555 cursor : tokenstream:: Cursor ,
557- next : Option < tokenstream :: TokenStream > ,
556+ stack : Vec < TokenTree > ,
558557}
559558
560559#[ unstable( feature = "proc_macro" , issue = "38356" ) ]
@@ -563,9 +562,10 @@ impl Iterator for TokenTreeIter {
563562
564563 fn next ( & mut self ) -> Option < TokenTree > {
565564 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+ } ) ?;
569569 if tree. span . 0 == DUMMY_SP {
570570 if let TokenNode :: Group ( Delimiter :: None , stream) = tree. kind {
571571 self . cursor . insert ( stream. 0 ) ;
@@ -598,12 +598,12 @@ impl Delimiter {
598598}
599599
600600impl TokenTree {
601- fn from_internal ( stream : tokenstream:: TokenStream , next : & mut Option < tokenstream :: TokenStream > )
601+ fn from_internal ( stream : tokenstream:: TokenStream , stack : & mut Vec < TokenTree > )
602602 -> TokenTree {
603603 use syntax:: parse:: token:: * ;
604604
605605 let ( tree, is_joint) = stream. as_tree ( ) ;
606- let ( mut span, token) = match tree {
606+ let ( span, token) = match tree {
607607 tokenstream:: TokenTree :: Token ( span, token) => ( span, token) ,
608608 tokenstream:: TokenTree :: Delimited ( span, delimed) => {
609609 let delimiter = Delimiter :: from_internal ( delimed. delim ) ;
@@ -615,34 +615,32 @@ impl TokenTree {
615615 } ;
616616
617617 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 } )
624620 }
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+ } )
634632 }
635633
636634 let kind = match token {
637635 Eq => op ! ( '=' ) ,
638636 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 ! ( '>' , '=' ) ,
643641 Gt => op ! ( '>' ) ,
644- AndAnd => joint ! ( '&' , BinOp ( And ) ) ,
645- OrOr => joint ! ( '|' , BinOp ( Or ) ) ,
642+ AndAnd => op ! ( '&' , '&' ) ,
643+ OrOr => op ! ( '|' , '|' ) ,
646644 Not => op ! ( '!' ) ,
647645 Tilde => op ! ( '~' ) ,
648646 BinOp ( Plus ) => op ! ( '+' ) ,
@@ -653,37 +651,46 @@ impl TokenTree {
653651 BinOp ( Caret ) => op ! ( '^' ) ,
654652 BinOp ( And ) => op ! ( '&' ) ,
655653 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 ! ( '>' , '>' , '=' ) ,
668666 At => op ! ( '@' ) ,
669667 Dot => op ! ( '.' ) ,
670- DotDot => joint ! ( '.' , Dot ) ,
671- DotDotDot => joint ! ( '.' , DotDot ) ,
672- DotDotEq => joint ! ( '.' , DotEq ) ,
668+ DotDot => op ! ( '.' , '.' ) ,
669+ DotDotDot => op ! ( '.' , '.' , '.' ) ,
670+ DotDotEq => op ! ( '.' , '.' , '=' ) ,
673671 Comma => op ! ( ',' ) ,
674672 Semi => op ! ( ';' ) ,
675673 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 ! ( '=' , '>' ) ,
680678 Pound => op ! ( '#' ) ,
681679 Dollar => op ! ( '$' ) ,
682680 Question => op ! ( '?' ) ,
683681
684682 Ident ( ident, false ) | Lifetime ( ident) => TokenNode :: Term ( Term ( ident. name ) ) ,
685683 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+ }
687694
688695 Interpolated ( _) => {
689696 __internal:: with_sess ( |( sess, _) | {
@@ -692,7 +699,7 @@ impl TokenTree {
692699 } )
693700 }
694701
695- DotEq => joint ! ( '.' , Eq ) ,
702+ DotEq => op ! ( '.' , '=' ) ,
696703 OpenDelim ( ..) | CloseDelim ( ..) => unreachable ! ( ) ,
697704 Whitespace | Comment | Shebang ( ..) | Eof => unreachable ! ( ) ,
698705 } ;
@@ -724,7 +731,29 @@ impl TokenTree {
724731 } else { Ident ( ident, false ) } ;
725732 return TokenTree :: Token ( self . span . 0 , token) . into ( ) ;
726733 }
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+ }
728757 } ;
729758
730759 let token = match op {
0 commit comments