1010
1111// The Rust abstract syntax tree.
1212
13- use codemap:: { Span , Spanned , DUMMY_SP , ExpnId } ;
13+ use codemap:: { Span , Spanned , DUMMY_SP , ExpnId , respan } ;
1414use abi:: Abi ;
1515use ast_util;
1616use owned_slice:: OwnedSlice ;
@@ -713,6 +713,19 @@ impl Delimited {
713713 }
714714}
715715
716+ /// A sequence of token treesee
717+ #[ deriving( Clone , PartialEq , Eq , Encodable , Decodable , Hash , Show ) ]
718+ pub struct SequenceRepetition {
719+ /// The sequence of token trees
720+ pub tts : Vec < TokenTree > ,
721+ /// The optional separator
722+ pub separator : Option < token:: Token > ,
723+ /// Whether the sequence can be repeated zero (*), or one or more times (+)
724+ pub op : KleeneOp ,
725+ /// The number of `MatchNt`s that appear in the sequence (and subsequences)
726+ pub num_captures : uint ,
727+ }
728+
716729/// A Kleene-style [repetition operator](http://en.wikipedia.org/wiki/Kleene_star)
717730/// for token sequences.
718731#[ deriving( Clone , PartialEq , Eq , Encodable , Decodable , Hash , Show ) ]
@@ -727,14 +740,12 @@ pub enum KleeneOp {
727740/// be passed to syntax extensions using a uniform type.
728741///
729742/// If the syntax extension is an MBE macro, it will attempt to match its
730- /// LHS "matchers" against the provided token tree, and if it finds a
743+ /// LHS token tree against the provided token tree, and if it finds a
731744/// match, will transcribe the RHS token tree, splicing in any captured
732- /// ` macro_parser::matched_nonterminals` into the `TtNonterminal `s it finds.
745+ /// macro_parser::matched_nonterminals into the `SubstNt `s it finds.
733746///
734- /// The RHS of an MBE macro is the only place a `TtNonterminal` or `TtSequence`
735- /// makes any real sense. You could write them elsewhere but nothing
736- /// else knows what to do with them, so you'll probably get a syntax
737- /// error.
747+ /// The RHS of an MBE macro is the only place `SubstNt`s are substituted.
748+ /// Nothing special happens to misnamed or misplaced `SubstNt`s.
738749#[ deriving( Clone , PartialEq , Eq , Encodable , Decodable , Hash , Show ) ]
739750#[ doc="For macro invocations; parsing is delegated to the macro" ]
740751pub enum TokenTree {
@@ -743,90 +754,82 @@ pub enum TokenTree {
743754 /// A delimited sequence of token trees
744755 TtDelimited ( Span , Rc < Delimited > ) ,
745756
746- // These only make sense for right-hand-sides of MBE macros:
757+ // This only makes sense in MBE macros.
747758
748- /// A Kleene-style repetition sequence with an optional separator.
749- // FIXME(eddyb) #6308 Use Rc<[TokenTree]> after DST.
750- TtSequence ( Span , Rc < Vec < TokenTree > > , Option < token:: Token > , KleeneOp ) ,
751- /// A syntactic variable that will be filled in by macro expansion.
752- TtNonterminal ( Span , Ident )
759+ /// A kleene-style repetition sequence with a span
760+ // FIXME(eddyb) #12938 Use DST.
761+ TtSequence ( Span , Rc < SequenceRepetition > ) ,
753762}
754763
755764impl TokenTree {
765+ pub fn len ( & self ) -> uint {
766+ match * self {
767+ TtToken ( _, token:: DocComment ( _) ) => 2 ,
768+ TtToken ( _, token:: SubstNt ( ..) ) => 2 ,
769+ TtToken ( _, token:: MatchNt ( ..) ) => 3 ,
770+ TtDelimited ( _, ref delimed) => {
771+ delimed. tts . len ( ) + 2
772+ }
773+ TtSequence ( _, ref seq) => {
774+ seq. tts . len ( )
775+ }
776+ TtToken ( ..) => 0
777+ }
778+ }
779+
780+ pub fn get_tt ( & self , index : uint ) -> TokenTree {
781+ match ( self , index) {
782+ ( & TtToken ( sp, token:: DocComment ( _) ) , 0 ) => {
783+ TtToken ( sp, token:: Pound )
784+ }
785+ ( & TtToken ( sp, token:: DocComment ( name) ) , 1 ) => {
786+ let doc = MetaNameValue ( token:: intern_and_get_ident ( "doc" ) ,
787+ respan ( sp, LitStr ( token:: get_name ( name) , CookedStr ) ) ) ;
788+ let doc = token:: NtMeta ( P ( respan ( sp, doc) ) ) ;
789+ TtDelimited ( sp, Rc :: new ( Delimited {
790+ delim : token:: Bracket ,
791+ open_span : sp,
792+ tts : vec ! [ TtToken ( sp, token:: Interpolated ( doc) ) ] ,
793+ close_span : sp,
794+ } ) )
795+ }
796+ ( & TtDelimited ( _, ref delimed) , _) => {
797+ if index == 0 {
798+ return delimed. open_tt ( ) ;
799+ }
800+ if index == delimed. tts . len ( ) + 1 {
801+ return delimed. close_tt ( ) ;
802+ }
803+ delimed. tts [ index - 1 ] . clone ( )
804+ }
805+ ( & TtToken ( sp, token:: SubstNt ( name, name_st) ) , _) => {
806+ let v = [ TtToken ( sp, token:: Dollar ) ,
807+ TtToken ( sp, token:: Ident ( name, name_st) ) ] ;
808+ v[ index]
809+ }
810+ ( & TtToken ( sp, token:: MatchNt ( name, kind, name_st, kind_st) ) , _) => {
811+ let v = [ TtToken ( sp, token:: SubstNt ( name, name_st) ) ,
812+ TtToken ( sp, token:: Colon ) ,
813+ TtToken ( sp, token:: Ident ( kind, kind_st) ) ] ;
814+ v[ index]
815+ }
816+ ( & TtSequence ( _, ref seq) , _) => {
817+ seq. tts [ index] . clone ( )
818+ }
819+ _ => panic ! ( "Cannot expand a token tree" )
820+ }
821+ }
822+
756823 /// Returns the `Span` corresponding to this token tree.
757824 pub fn get_span ( & self ) -> Span {
758825 match * self {
759- TtToken ( span, _) => span,
760- TtDelimited ( span, _) => span,
761- TtSequence ( span, _, _, _) => span,
762- TtNonterminal ( span, _) => span,
826+ TtToken ( span, _) => span,
827+ TtDelimited ( span, _) => span,
828+ TtSequence ( span, _) => span,
763829 }
764830 }
765831}
766832
767- // Matchers are nodes defined-by and recognized-by the main rust parser and
768- // language, but they're only ever found inside syntax-extension invocations;
769- // indeed, the only thing that ever _activates_ the rules in the rust parser
770- // for parsing a matcher is a matcher looking for the 'matchers' nonterminal
771- // itself. Matchers represent a small sub-language for pattern-matching
772- // token-trees, and are thus primarily used by the macro-defining extension
773- // itself.
774- //
775- // MatchTok
776- // --------
777- //
778- // A matcher that matches a single token, denoted by the token itself. So
779- // long as there's no $ involved.
780- //
781- //
782- // MatchSeq
783- // --------
784- //
785- // A matcher that matches a sequence of sub-matchers, denoted various
786- // possible ways:
787- //
788- // $(M)* zero or more Ms
789- // $(M)+ one or more Ms
790- // $(M),+ one or more comma-separated Ms
791- // $(A B C);* zero or more semi-separated 'A B C' seqs
792- //
793- //
794- // MatchNonterminal
795- // -----------------
796- //
797- // A matcher that matches one of a few interesting named rust
798- // nonterminals, such as types, expressions, items, or raw token-trees. A
799- // black-box matcher on expr, for example, binds an expr to a given ident,
800- // and that ident can re-occur as an interpolation in the RHS of a
801- // macro-by-example rule. For example:
802- //
803- // $foo:expr => 1 + $foo // interpolate an expr
804- // $foo:tt => $foo // interpolate a token-tree
805- // $foo:tt => bar! $foo // only other valid interpolation
806- // // is in arg position for another
807- // // macro
808- //
809- // As a final, horrifying aside, note that macro-by-example's input is
810- // also matched by one of these matchers. Holy self-referential! It is matched
811- // by a MatchSeq, specifically this one:
812- //
813- // $( $lhs:matchers => $rhs:tt );+
814- //
815- // If you understand that, you have closed the loop and understand the whole
816- // macro system. Congratulations.
817- pub type Matcher = Spanned < Matcher_ > ;
818-
819- #[ deriving( Clone , PartialEq , Eq , Encodable , Decodable , Hash , Show ) ]
820- pub enum Matcher_ {
821- /// Match one token
822- MatchTok ( token:: Token ) ,
823- /// Match repetitions of a sequence: body, separator, Kleene operator,
824- /// lo, hi position-in-match-array used:
825- MatchSeq ( Vec < Matcher > , Option < token:: Token > , KleeneOp , uint , uint ) ,
826- /// Parse a Rust NT: name to bind, name of NT, position in match array:
827- MatchNonterminal ( Ident , Ident , uint )
828- }
829-
830833pub type Mac = Spanned < Mac_ > ;
831834
832835/// Represents a macro invocation. The Path indicates which macro
0 commit comments