diff options
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ext/base.rs | 20 | ||||
| -rw-r--r-- | src/libsyntax/ext/tt/macro_parser.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/opt_vec.rs | 24 | ||||
| -rw-r--r-- | src/libsyntax/parse/attr.rs | 131 | ||||
| -rw-r--r-- | src/libsyntax/parse/lexer.rs | 6 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 14 | ||||
| -rw-r--r-- | src/libsyntax/parse/token.rs | 3 |
7 files changed, 119 insertions, 81 deletions
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 1e696451701..dfaffa0c275 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -421,12 +421,12 @@ pub enum MapChain<K,V> { // get the map from an env frame impl <K: Eq + Hash + IterBytes + 'static, V: 'static> MapChain<K,V>{ // Constructor. I don't think we need a zero-arg one. - fn new(init: ~HashMap<K,@V>) -> @mut MapChain<K,V> { + pub fn new(init: ~HashMap<K,@V>) -> @mut MapChain<K,V> { @mut BaseMapChain(init) } // add a new frame to the environment (functionally) - fn push_frame (@mut self) -> @mut MapChain<K,V> { + pub fn push_frame (@mut self) -> @mut MapChain<K,V> { @mut ConsMapChain(~HashMap::new() ,self) } @@ -436,7 +436,7 @@ impl <K: Eq + Hash + IterBytes + 'static, V: 'static> MapChain<K,V>{ // ugh: can't get this to compile with mut because of the // lack of flow sensitivity. - fn get_map<'a>(&'a self) -> &'a HashMap<K,@V> { + pub fn get_map<'a>(&'a self) -> &'a HashMap<K,@V> { match *self { BaseMapChain (~ref map) => map, ConsMapChain (~ref map,_) => map @@ -446,7 +446,7 @@ impl <K: Eq + Hash + IterBytes + 'static, V: 'static> MapChain<K,V>{ // traits just don't work anywhere...? //impl Map<Name,SyntaxExtension> for MapChain { - fn contains_key (&self, key: &K) -> bool { + pub fn contains_key (&self, key: &K) -> bool { match *self { BaseMapChain (ref map) => map.contains_key(key), ConsMapChain (ref map,ref rest) => @@ -457,17 +457,17 @@ impl <K: Eq + Hash + IterBytes + 'static, V: 'static> MapChain<K,V>{ // should each_key and each_value operate on shadowed // names? I think not. // delaying implementing this.... - fn each_key (&self, _f: &fn (&K)->bool) { + pub fn each_key (&self, _f: &fn (&K)->bool) { fail!("unimplemented 2013-02-15T10:01"); } - fn each_value (&self, _f: &fn (&V) -> bool) { + pub fn each_value (&self, _f: &fn (&V) -> bool) { fail!("unimplemented 2013-02-15T10:02"); } // Returns a copy of the value that the name maps to. // Goes down the chain 'til it finds one (or bottom out). - fn find (&self, key: &K) -> Option<@V> { + pub fn find (&self, key: &K) -> Option<@V> { match self.get_map().find (key) { Some(ref v) => Some(**v), None => match *self { @@ -477,7 +477,7 @@ impl <K: Eq + Hash + IterBytes + 'static, V: 'static> MapChain<K,V>{ } } - fn find_in_topmost_frame(&self, key: &K) -> Option<@V> { + pub fn find_in_topmost_frame(&self, key: &K) -> Option<@V> { let map = match *self { BaseMapChain(ref map) => map, ConsMapChain(ref map,_) => map @@ -487,7 +487,7 @@ impl <K: Eq + Hash + IterBytes + 'static, V: 'static> MapChain<K,V>{ } // insert the binding into the top-level map - fn insert (&mut self, key: K, ext: @V) -> bool { + pub fn insert (&mut self, key: K, ext: @V) -> bool { // can't abstract over get_map because of flow sensitivity... match *self { BaseMapChain (~ref mut map) => map.insert(key, ext), @@ -499,7 +499,7 @@ impl <K: Eq + Hash + IterBytes + 'static, V: 'static> MapChain<K,V>{ // ... there are definitely some opportunities for abstraction // here that I'm ignoring. (e.g., manufacturing a predicate on // the maps in the chain, and using an abstract "find". - fn insert_into_frame(&mut self, key: K, ext: @V, n: K, pred: &fn(&@V)->bool) { + pub fn insert_into_frame(&mut self, key: K, ext: @V, n: K, pred: &fn(&@V)->bool) { match *self { BaseMapChain (~ref mut map) => { if satisfies_pred(map,&n,pred) { diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index 5a1317034b2..918949113ad 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -17,6 +17,7 @@ use codemap; use parse::lexer::*; //resolve bug? use parse::ParseSess; use parse::parser::Parser; +use parse::attr::parser_attr; use parse::token::{Token, EOF, to_str, nonterminal, get_ident_interner, ident_to_str}; use parse::token; @@ -430,6 +431,7 @@ pub fn parse_nt(p: &Parser, name: &str) -> nonterminal { + token::to_str(get_ident_interner(), p.token)) }, "path" => token::nt_path(p.parse_path_with_tps(false)), + "attr" => token::nt_attr(@p.parse_attribute(false)), "tt" => { *p.quote_depth += 1u; //but in theory, non-quoted tts might be useful let res = token::nt_tt(@p.parse_token_tree()); diff --git a/src/libsyntax/opt_vec.rs b/src/libsyntax/opt_vec.rs index 5d79532c8c5..3a10206b513 100644 --- a/src/libsyntax/opt_vec.rs +++ b/src/libsyntax/opt_vec.rs @@ -36,7 +36,7 @@ pub fn from<T>(t: ~[T]) -> OptVec<T> { } impl<T> OptVec<T> { - fn push(&mut self, t: T) { + pub fn push(&mut self, t: T) { match *self { Vec(ref mut v) => { v.push(t); @@ -50,32 +50,32 @@ impl<T> OptVec<T> { *self = Vec(~[t]); } - fn map<U>(&self, op: &fn(&T) -> U) -> OptVec<U> { + pub fn map<U>(&self, op: &fn(&T) -> U) -> OptVec<U> { match *self { Empty => Empty, Vec(ref v) => Vec(v.map(op)) } } - fn map_move<U>(self, op: &fn(T) -> U) -> OptVec<U> { + pub fn map_move<U>(self, op: &fn(T) -> U) -> OptVec<U> { match self { Empty => Empty, Vec(v) => Vec(v.move_iter().map(op).collect()) } } - fn get<'a>(&'a self, i: uint) -> &'a T { + pub fn get<'a>(&'a self, i: uint) -> &'a T { match *self { Empty => fail!("Invalid index %u", i), Vec(ref v) => &v[i] } } - fn is_empty(&self) -> bool { + pub fn is_empty(&self) -> bool { self.len() == 0 } - fn len(&self) -> uint { + pub fn len(&self) -> uint { match *self { Empty => 0, Vec(ref v) => v.len() @@ -83,7 +83,7 @@ impl<T> OptVec<T> { } #[inline] - fn iter<'r>(&'r self) -> OptVecIterator<'r, T> { + pub fn iter<'r>(&'r self) -> OptVecIterator<'r, T> { match *self { Empty => OptVecIterator{iter: None}, Vec(ref v) => OptVecIterator{iter: Some(v.iter())} @@ -91,11 +91,11 @@ impl<T> OptVec<T> { } #[inline] - fn map_to_vec<B>(&self, op: &fn(&T) -> B) -> ~[B] { + pub fn map_to_vec<B>(&self, op: &fn(&T) -> B) -> ~[B] { self.iter().map(op).collect() } - fn mapi_to_vec<B>(&self, op: &fn(uint, &T) -> B) -> ~[B] { + pub fn mapi_to_vec<B>(&self, op: &fn(uint, &T) -> B) -> ~[B] { let mut index = 0; self.map_to_vec(|a| { let i = index; @@ -113,7 +113,7 @@ pub fn take_vec<T>(v: OptVec<T>) -> ~[T] { } impl<T:Clone> OptVec<T> { - fn prepend(&self, t: T) -> OptVec<T> { + pub fn prepend(&self, t: T) -> OptVec<T> { let mut v0 = ~[t]; match *self { Empty => {} @@ -124,7 +124,7 @@ impl<T:Clone> OptVec<T> { } impl<A:Eq> Eq for OptVec<A> { - fn eq(&self, other: &OptVec<A>) -> bool { + pub fn eq(&self, other: &OptVec<A>) -> bool { // Note: cannot use #[deriving(Eq)] here because // (Empty, Vec(~[])) ought to be equal. match (self, other) { @@ -135,7 +135,7 @@ impl<A:Eq> Eq for OptVec<A> { } } - fn ne(&self, other: &OptVec<A>) -> bool { + pub fn ne(&self, other: &OptVec<A>) -> bool { !self.eq(other) } } diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs index 8cce5f15e67..f2489d80e1e 100644 --- a/src/libsyntax/parse/attr.rs +++ b/src/libsyntax/parse/attr.rs @@ -9,21 +9,17 @@ // except according to those terms. use ast; -use codemap::spanned; +use codemap::{spanned, mk_sp}; use codemap::BytePos; use parse::common::*; //resolve bug? use parse::token; use parse::parser::Parser; +use parse::token::INTERPOLATED; // a parser that can parse attributes. pub trait parser_attr { fn parse_outer_attributes(&self) -> ~[ast::Attribute]; - fn parse_attribute(&self, style: ast::AttrStyle) -> ast::Attribute; - fn parse_attribute_naked( - &self, - style: ast::AttrStyle, - lo: BytePos - ) -> ast::Attribute; + fn parse_attribute(&self, permit_inner: bool) -> ast::Attribute; fn parse_inner_attrs_and_next(&self) -> (~[ast::Attribute], ~[ast::Attribute]); fn parse_meta_item(&self) -> @ast::MetaItem; @@ -37,12 +33,17 @@ impl parser_attr for Parser { fn parse_outer_attributes(&self) -> ~[ast::Attribute] { let mut attrs: ~[ast::Attribute] = ~[]; loop { + debug!("parse_outer_attributes: self.token=%?", + self.token); match *self.token { + token::INTERPOLATED(token::nt_attr(*)) => { + attrs.push(self.parse_attribute(false)); + } token::POUND => { if self.look_ahead(1, |t| *t != token::LBRACKET) { break; } - attrs.push(self.parse_attribute(ast::AttrOuter)); + attrs.push(self.parse_attribute(false)); } token::DOC_COMMENT(s) => { let attr = ::attr::mk_sugared_doc_attr( @@ -62,23 +63,49 @@ impl parser_attr for Parser { return attrs; } - // matches attribute = # attribute_naked - fn parse_attribute(&self, style: ast::AttrStyle) -> ast::Attribute { - let lo = self.span.lo; - self.expect(&token::POUND); - return self.parse_attribute_naked(style, lo); + // matches attribute = # [ meta_item ] + // + // if permit_inner is true, then a trailing `;` indicates an inner + // attribute + fn parse_attribute(&self, permit_inner: bool) -> ast::Attribute { + debug!("parse_attributes: permit_inner=%? self.token=%?", + permit_inner, self.token); + let (span, value) = match *self.token { + INTERPOLATED(token::nt_attr(attr)) => { + assert!(attr.node.style == ast::AttrOuter); + self.bump(); + (attr.span, attr.node.value) + } + token::POUND => { + let lo = self.span.lo; + self.bump(); + self.expect(&token::LBRACKET); + let meta_item = self.parse_meta_item(); + self.expect(&token::RBRACKET); + let hi = self.span.hi; + (mk_sp(lo, hi), meta_item) + } + _ => { + self.fatal(fmt!("expected `#` but found `%s`", + self.this_token_to_str())); + } + }; + let style = if permit_inner && *self.token == token::SEMI { + self.bump(); + ast::AttrInner + } else { + ast::AttrOuter + }; + return spanned { + span: span, + node: ast::Attribute_ { + style: style, + value: value, + is_sugared_doc: false + } + }; } - // matches attribute_naked = [ meta_item ] - fn parse_attribute_naked(&self, style: ast::AttrStyle, lo: BytePos) -> - ast::Attribute { - self.expect(&token::LBRACKET); - let meta_item = self.parse_meta_item(); - self.expect(&token::RBRACKET); - let hi = self.span.hi; - return spanned(lo, hi, ast::Attribute_ { style: style, - value: meta_item, is_sugared_doc: false }); } - // Parse attributes that appear after the opening of an item, each // terminated by a semicolon. In addition to a vector of inner attributes, // this function also returns a vector that may contain the first outer @@ -89,47 +116,37 @@ impl parser_attr for Parser { // matches inner_attrs* outer_attr? // you can make the 'next' field an Option, but the result is going to be // more useful as a vector. - fn parse_inner_attrs_and_next(&self) -> - (~[ast::Attribute], ~[ast::Attribute]) { + fn parse_inner_attrs_and_next(&self) + -> (~[ast::Attribute], ~[ast::Attribute]) { let mut inner_attrs: ~[ast::Attribute] = ~[]; let mut next_outer_attrs: ~[ast::Attribute] = ~[]; loop { - match *self.token { - token::POUND => { - if self.look_ahead(1, |t| *t != token::LBRACKET) { - // This is an extension - break; + let attr = match *self.token { + token::INTERPOLATED(token::nt_attr(*)) => { + self.parse_attribute(true) + } + token::POUND => { + if self.look_ahead(1, |t| *t != token::LBRACKET) { + // This is an extension + break; + } + self.parse_attribute(true) } - let attr = self.parse_attribute(ast::AttrInner); - if *self.token == token::SEMI { + token::DOC_COMMENT(s) => { self.bump(); - inner_attrs.push(attr); - } else { - // It's not really an inner attribute - let outer_attr = - spanned(attr.span.lo, attr.span.hi, - ast::Attribute_ { style: ast::AttrOuter, - value: attr.node.value, - is_sugared_doc: false }); - next_outer_attrs.push(outer_attr); - break; + ::attr::mk_sugared_doc_attr(self.id_to_str(s), + self.span.lo, + self.span.hi) } - } - token::DOC_COMMENT(s) => { - let attr = ::attr::mk_sugared_doc_attr( - self.id_to_str(s), - self.span.lo, - self.span.hi - ); - self.bump(); - if attr.node.style == ast::AttrInner { - inner_attrs.push(attr); - } else { - next_outer_attrs.push(attr); - break; + _ => { + break; } - } - _ => break + }; + if attr.node.style == ast::AttrInner { + inner_attrs.push(attr); + } else { + next_outer_attrs.push(attr); + break; } } (inner_attrs, next_outer_attrs) diff --git a/src/libsyntax/parse/lexer.rs b/src/libsyntax/parse/lexer.rs index 49deafeda40..bde568b2610 100644 --- a/src/libsyntax/parse/lexer.rs +++ b/src/libsyntax/parse/lexer.rs @@ -129,7 +129,11 @@ impl reader for StringReader { impl reader for TtReader { fn is_eof(@mut self) -> bool { self.cur_tok == token::EOF } - fn next_token(@mut self) -> TokenAndSpan { tt_next_token(self) } + fn next_token(@mut self) -> TokenAndSpan { + let r = tt_next_token(self); + debug!("TtReader: r=%?", r); + return r; + } fn fatal(@mut self, m: ~str) -> ! { self.sp_diag.span_fatal(self.cur_span, m); } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index d1916088a41..77c50a779c0 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#[macro_escape]; + use abi; use abi::AbiSet; use ast::{Sigil, BorrowedSigil, ManagedSigil, OwnedSigil}; @@ -4460,7 +4462,17 @@ impl Parser { attrs: ~[Attribute], macros_allowed: bool) -> item_or_view_item { - maybe_whole!(iovi self, nt_item); + match *self.token { + INTERPOLATED(token::nt_item(item)) => { + self.bump(); + let new_attrs = vec::append(attrs, item.attrs); + return iovi_item(@ast::item { + attrs: new_attrs, + ..(*item).clone()}); + } + _ => {} + } + let lo = self.span.lo; let visibility = self.parse_non_priv_visibility(); diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index fd491c1e890..c554f111bf9 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -105,6 +105,7 @@ pub enum nonterminal { nt_expr(@ast::expr), nt_ty( ast::Ty), nt_ident(ast::ident, bool), + nt_attr(@ast::Attribute), // #[foo] nt_path( ast::Path), nt_tt( @ast::token_tree), //needs @ed to break a circularity nt_matchers(~[ast::matcher]) @@ -205,6 +206,7 @@ pub fn to_str(input: @ident_interner, t: &Token) -> ~str { INTERPOLATED(ref nt) => { match nt { &nt_expr(e) => ::print::pprust::expr_to_str(e, input), + &nt_attr(e) => ::print::pprust::attribute_to_str(e, input), _ => { ~"an interpolated " + match (*nt) { @@ -212,6 +214,7 @@ pub fn to_str(input: @ident_interner, t: &Token) -> ~str { nt_block(*) => ~"block", nt_stmt(*) => ~"statement", nt_pat(*) => ~"pattern", + nt_attr(*) => fail!("should have been handled"), nt_expr(*) => fail!("should have been handled above"), nt_ty(*) => ~"type", nt_ident(*) => ~"identifier", |
