diff options
| author | bors <bors@rust-lang.org> | 2014-03-28 20:21:45 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2014-03-28 20:21:45 -0700 |
| commit | 6584f3746e552a626003f564e2f83262d93cbd57 (patch) | |
| tree | b5ee7f3495c68acd4fb712ca4f762b41bff384fb /src/libsyntax/ext | |
| parent | b334f7c3cc3fcab8170ccb46a1f9a12702a2582c (diff) | |
| parent | b0e3cb5f32ec25efb9af65293f9d776b6374b657 (diff) | |
| download | rust-6584f3746e552a626003f564e2f83262d93cbd57.tar.gz rust-6584f3746e552a626003f564e2f83262d93cbd57.zip | |
auto merge of #13170 : eddyb/rust/syntax-cleanup, r=alexcrichton
Removes all Cell's/RefCell's from lexer::Reader implementations and a couple @.
Diffstat (limited to 'src/libsyntax/ext')
| -rw-r--r-- | src/libsyntax/ext/log_syntax.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/ext/tt/macro_parser.rs | 49 | ||||
| -rw-r--r-- | src/libsyntax/ext/tt/macro_rules.rs | 19 | ||||
| -rw-r--r-- | src/libsyntax/ext/tt/transcribe.rs | 325 |
4 files changed, 185 insertions, 212 deletions
diff --git a/src/libsyntax/ext/log_syntax.rs b/src/libsyntax/ext/log_syntax.rs index 1ce08b8303e..c9e444a9b8c 100644 --- a/src/libsyntax/ext/log_syntax.rs +++ b/src/libsyntax/ext/log_syntax.rs @@ -13,6 +13,8 @@ use codemap; use ext::base; use print; +use std::rc::Rc; + pub fn expand_syntax_ext(cx: &mut base::ExtCtxt, sp: codemap::Span, tt: &[ast::TokenTree]) @@ -20,7 +22,7 @@ pub fn expand_syntax_ext(cx: &mut base::ExtCtxt, cx.print_backtrace(); println!("{}", print::pprust::tt_to_str(&ast::TTDelim( - @tt.iter().map(|x| (*x).clone()).collect()))); + Rc::new(tt.iter().map(|x| (*x).clone()).collect())))); // any so that `log_syntax` can be invoked as an expression and item. base::MacResult::dummy_any(sp) diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index 0d90093a40f..ae537cc4782 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -21,6 +21,7 @@ use parse::parser::{LifetimeAndTypesWithoutColons, Parser}; use parse::token::{Token, EOF, Nonterminal}; use parse::token; +use std::rc::Rc; use collections::HashMap; /* This is an Earley-like parser, without support for in-grammar nonterminals, @@ -102,7 +103,7 @@ pub struct MatcherPos { sep: Option<Token>, idx: uint, up: Option<~MatcherPos>, - matches: Vec<Vec<@NamedMatch>>, + matches: Vec<Vec<Rc<NamedMatch>>>, match_lo: uint, match_hi: uint, sp_lo: BytePos, } @@ -165,14 +166,14 @@ pub fn initial_matcher_pos(ms: Vec<Matcher> , sep: Option<Token>, lo: BytePos) // ast::Matcher it was derived from. pub enum NamedMatch { - MatchedSeq(Vec<@NamedMatch> , codemap::Span), + MatchedSeq(Vec<Rc<NamedMatch>>, codemap::Span), MatchedNonterminal(Nonterminal) } -pub fn nameize(p_s: &ParseSess, ms: &[Matcher], res: &[@NamedMatch]) - -> HashMap<Ident, @NamedMatch> { - fn n_rec(p_s: &ParseSess, m: &Matcher, res: &[@NamedMatch], - ret_val: &mut HashMap<Ident, @NamedMatch>) { +pub fn nameize(p_s: &ParseSess, ms: &[Matcher], res: &[Rc<NamedMatch>]) + -> HashMap<Ident, Rc<NamedMatch>> { + fn n_rec(p_s: &ParseSess, m: &Matcher, res: &[Rc<NamedMatch>], + ret_val: &mut HashMap<Ident, Rc<NamedMatch>>) { match *m { codemap::Spanned {node: MatchTok(_), .. } => (), codemap::Spanned {node: MatchSeq(ref more_ms, _, _, _, _), .. } => { @@ -189,7 +190,7 @@ pub fn nameize(p_s: &ParseSess, ms: &[Matcher], res: &[@NamedMatch]) p_s.span_diagnostic .span_fatal(span, "duplicated bind name: " + string.get()) } - ret_val.insert(bind_name, res[idx]); + ret_val.insert(bind_name, res[idx].clone()); } } } @@ -199,16 +200,16 @@ pub fn nameize(p_s: &ParseSess, ms: &[Matcher], res: &[@NamedMatch]) } pub enum ParseResult { - Success(HashMap<Ident, @NamedMatch>), + Success(HashMap<Ident, Rc<NamedMatch>>), Failure(codemap::Span, ~str), Error(codemap::Span, ~str) } -pub fn parse_or_else<R: Reader>(sess: &ParseSess, - cfg: ast::CrateConfig, - rdr: R, - ms: Vec<Matcher> ) - -> HashMap<Ident, @NamedMatch> { +pub fn parse_or_else(sess: &ParseSess, + cfg: ast::CrateConfig, + rdr: TtReader, + ms: Vec<Matcher> ) + -> HashMap<Ident, Rc<NamedMatch>> { match parse(sess, cfg, rdr, ms.as_slice()) { Success(m) => m, Failure(sp, str) => sess.span_diagnostic.span_fatal(sp, str), @@ -226,11 +227,11 @@ pub fn token_name_eq(t1 : &Token, t2 : &Token) -> bool { } } -pub fn parse<R: Reader>(sess: &ParseSess, - cfg: ast::CrateConfig, - rdr: R, - ms: &[Matcher]) - -> ParseResult { +pub fn parse(sess: &ParseSess, + cfg: ast::CrateConfig, + mut rdr: TtReader, + ms: &[Matcher]) + -> ParseResult { let mut cur_eis = Vec::new(); cur_eis.push(initial_matcher_pos(ms.iter() .map(|x| (*x).clone()) @@ -282,8 +283,8 @@ pub fn parse<R: Reader>(sess: &ParseSess, let sub = (*ei.matches.get(idx)).clone(); new_pos.matches .get_mut(idx) - .push(@MatchedSeq(sub, mk_sp(ei.sp_lo, - sp.hi))); + .push(Rc::new(MatchedSeq(sub, mk_sp(ei.sp_lo, + sp.hi)))); } new_pos.idx += 1; @@ -325,7 +326,7 @@ pub fn parse<R: Reader>(sess: &ParseSess, for idx in range(match_idx_lo, match_idx_hi) { new_ei.matches .get_mut(idx) - .push(@MatchedSeq(Vec::new(), sp)); + .push(Rc::new(MatchedSeq(Vec::new(), sp))); } cur_eis.push(new_ei); @@ -395,14 +396,14 @@ pub fn parse<R: Reader>(sess: &ParseSess, } rdr.next_token(); } else /* bb_eis.len() == 1 */ { - let mut rust_parser = Parser(sess, cfg.clone(), rdr.dup()); + let mut rust_parser = Parser(sess, cfg.clone(), ~rdr.clone()); let mut ei = bb_eis.pop().unwrap(); match ei.elts.get(ei.idx).node { MatchNonterminal(_, name, idx) => { let name_string = token::get_ident(name); - ei.matches.get_mut(idx).push(@MatchedNonterminal( - parse_nt(&mut rust_parser, name_string.get()))); + ei.matches.get_mut(idx).push(Rc::new(MatchedNonterminal( + parse_nt(&mut rust_parser, name_string.get())))); ei.idx += 1u; } _ => fail!() diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index b3e3023388b..d4a883a63eb 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -28,6 +28,7 @@ use print; use util::small_vector::SmallVector; use std::cell::RefCell; +use std::rc::Rc; struct ParserAnyMacro<'a> { parser: RefCell<Parser<'a>>, @@ -85,8 +86,8 @@ impl<'a> AnyMacro for ParserAnyMacro<'a> { struct MacroRulesMacroExpander { name: Ident, - lhses: @Vec<@NamedMatch> , - rhses: @Vec<@NamedMatch> , + lhses: Vec<Rc<NamedMatch>>, + rhses: Vec<Rc<NamedMatch>>, } impl MacroExpander for MacroRulesMacroExpander { @@ -109,15 +110,15 @@ fn generic_extension(cx: &ExtCtxt, sp: Span, name: Ident, arg: &[ast::TokenTree], - lhses: &[@NamedMatch], - rhses: &[@NamedMatch]) + lhses: &[Rc<NamedMatch>], + rhses: &[Rc<NamedMatch>]) -> MacResult { if cx.trace_macros() { println!("{}! \\{ {} \\}", token::get_ident(name), - print::pprust::tt_to_str(&TTDelim(@arg.iter() - .map(|x| (*x).clone()) - .collect()))); + print::pprust::tt_to_str(&TTDelim(Rc::new(arg.iter() + .map(|x| (*x).clone()) + .collect())))); } // Which arm's failure should we report? (the one furthest along) @@ -220,12 +221,12 @@ pub fn add_new_extension(cx: &mut ExtCtxt, // Extract the arguments: let lhses = match **argument_map.get(&lhs_nm) { - MatchedSeq(ref s, _) => /* FIXME (#2543) */ @(*s).clone(), + MatchedSeq(ref s, _) => /* FIXME (#2543) */ (*s).clone(), _ => cx.span_bug(sp, "wrong-structured lhs") }; let rhses = match **argument_map.get(&rhs_nm) { - MatchedSeq(ref s, _) => /* FIXME (#2543) */ @(*s).clone(), + MatchedSeq(ref s, _) => /* FIXME (#2543) */ (*s).clone(), _ => cx.span_bug(sp, "wrong-structured rhs") }; diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs index 933fbe3d566..bc8709befae 100644 --- a/src/libsyntax/ext/tt/transcribe.rs +++ b/src/libsyntax/ext/tt/transcribe.rs @@ -17,107 +17,79 @@ use parse::token::{EOF, INTERPOLATED, IDENT, Token, NtIdent}; use parse::token; use parse::lexer::TokenAndSpan; -use std::cell::{Cell, RefCell}; +use std::rc::Rc; use collections::HashMap; ///an unzipping of `TokenTree`s +#[deriving(Clone)] struct TtFrame { - forest: @Vec<ast::TokenTree> , - idx: Cell<uint>, + forest: Rc<Vec<ast::TokenTree>>, + idx: uint, dotdotdoted: bool, sep: Option<Token>, - up: Option<@TtFrame>, } +#[deriving(Clone)] pub struct TtReader<'a> { sp_diag: &'a SpanHandler, // the unzipped tree: - priv stack: RefCell<@TtFrame>, + priv stack: Vec<TtFrame>, /* for MBE-style macro transcription */ - priv interpolations: RefCell<HashMap<Ident, @NamedMatch>>, - priv repeat_idx: RefCell<Vec<uint> >, - priv repeat_len: RefCell<Vec<uint> >, + priv interpolations: HashMap<Ident, Rc<NamedMatch>>, + priv repeat_idx: Vec<uint>, + priv repeat_len: Vec<uint>, /* cached: */ - cur_tok: RefCell<Token>, - cur_span: RefCell<Span>, + cur_tok: Token, + cur_span: Span, } /** This can do Macro-By-Example transcription. On the other hand, if * `src` contains no `TTSeq`s and `TTNonterminal`s, `interp` can (and * should) be none. */ pub fn new_tt_reader<'a>(sp_diag: &'a SpanHandler, - interp: Option<HashMap<Ident, @NamedMatch>>, + interp: Option<HashMap<Ident, Rc<NamedMatch>>>, src: Vec<ast::TokenTree> ) -> TtReader<'a> { - let r = TtReader { + let mut r = TtReader { sp_diag: sp_diag, - stack: RefCell::new(@TtFrame { - forest: @src, - idx: Cell::new(0u), + stack: vec!(TtFrame { + forest: Rc::new(src), + idx: 0, dotdotdoted: false, sep: None, - up: None }), interpolations: match interp { /* just a convienience */ - None => RefCell::new(HashMap::new()), - Some(x) => RefCell::new(x), + None => HashMap::new(), + Some(x) => x, }, - repeat_idx: RefCell::new(Vec::new()), - repeat_len: RefCell::new(Vec::new()), + repeat_idx: Vec::new(), + repeat_len: Vec::new(), /* dummy values, never read: */ - cur_tok: RefCell::new(EOF), - cur_span: RefCell::new(DUMMY_SP), + cur_tok: EOF, + cur_span: DUMMY_SP, }; - tt_next_token(&r); /* get cur_tok and cur_span set up */ + tt_next_token(&mut r); /* get cur_tok and cur_span set up */ r } -fn dup_tt_frame(f: @TtFrame) -> @TtFrame { - @TtFrame { - forest: @(*f.forest).clone(), - idx: f.idx.clone(), - dotdotdoted: f.dotdotdoted, - sep: f.sep.clone(), - up: match f.up { - Some(up_frame) => Some(dup_tt_frame(up_frame)), - None => None - } - } -} - -pub fn dup_tt_reader<'a>(r: &TtReader<'a>) -> TtReader<'a> { - TtReader { - sp_diag: r.sp_diag, - stack: RefCell::new(dup_tt_frame(r.stack.get())), - repeat_idx: r.repeat_idx.clone(), - repeat_len: r.repeat_len.clone(), - cur_tok: r.cur_tok.clone(), - cur_span: r.cur_span.clone(), - interpolations: r.interpolations.clone(), - } -} - - -fn lookup_cur_matched_by_matched(r: &TtReader, start: @NamedMatch) - -> @NamedMatch { - fn red(ad: @NamedMatch, idx: &uint) -> @NamedMatch { +fn lookup_cur_matched_by_matched(r: &TtReader, start: Rc<NamedMatch>) -> Rc<NamedMatch> { + r.repeat_idx.iter().fold(start, |ad, idx| { match *ad { MatchedNonterminal(_) => { // end of the line; duplicate henceforth - ad + ad.clone() } - MatchedSeq(ref ads, _) => *ads.get(*idx) + MatchedSeq(ref ads, _) => ads.get(*idx).clone() } - } - r.repeat_idx.borrow().iter().fold(start, red) + }) } -fn lookup_cur_matched(r: &TtReader, name: Ident) -> @NamedMatch { - let matched_opt = r.interpolations.borrow().find_copy(&name); +fn lookup_cur_matched(r: &TtReader, name: Ident) -> Rc<NamedMatch> { + let matched_opt = r.interpolations.find_copy(&name); match matched_opt { Some(s) => lookup_cur_matched_by_matched(r, s), None => { - r.sp_diag.span_fatal(r.cur_span.get(), + r.sp_diag.span_fatal(r.cur_span, format!("unknown macro variable `{}`", token::get_ident(name))); } @@ -167,143 +139,140 @@ fn lockstep_iter_size(t: &TokenTree, r: &TtReader) -> LockstepIterSize { // return the next token from the TtReader. // EFFECT: advances the reader's token field -pub fn tt_next_token(r: &TtReader) -> TokenAndSpan { +pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan { // FIXME(pcwalton): Bad copy? let ret_val = TokenAndSpan { - tok: r.cur_tok.get(), - sp: r.cur_span.get(), + tok: r.cur_tok.clone(), + sp: r.cur_span.clone(), }; loop { - if r.stack.borrow().idx.get() < r.stack.borrow().forest.len() { - break; - } - - /* done with this set; pop or repeat? */ - if !r.stack.get().dotdotdoted || { - *r.repeat_idx.borrow().last().unwrap() == - *r.repeat_len.borrow().last().unwrap() - 1 - } { - - match r.stack.get().up { - None => { - r.cur_tok.set(EOF); + let should_pop = match r.stack.last() { + None => { + assert_eq!(ret_val.tok, EOF); return ret_val; - } - Some(tt_f) => { - if r.stack.get().dotdotdoted { - r.repeat_idx.borrow_mut().pop().unwrap(); - r.repeat_len.borrow_mut().pop().unwrap(); + } + Some(frame) => { + if frame.idx < frame.forest.len() { + break; } - - r.stack.set(tt_f); - r.stack.get().idx.set(r.stack.get().idx.get() + 1u); - } + !frame.dotdotdoted || + *r.repeat_idx.last().unwrap() == *r.repeat_len.last().unwrap() - 1 } + }; - } else { /* repeat */ - r.stack.get().idx.set(0u); - { - let mut repeat_idx = r.repeat_idx.borrow_mut(); - let last_repeat_idx = repeat_idx.len() - 1u; - *repeat_idx.get_mut(last_repeat_idx) += 1u; + /* done with this set; pop or repeat? */ + if should_pop { + let prev = r.stack.pop().unwrap(); + match r.stack.mut_last() { + None => { + r.cur_tok = EOF; + return ret_val; + } + Some(frame) => { + frame.idx += 1; + } } - match r.stack.get().sep.clone() { - Some(tk) => { - r.cur_tok.set(tk); /* repeat same span, I guess */ - return ret_val; - } - None => () + if prev.dotdotdoted { + r.repeat_idx.pop(); + r.repeat_len.pop(); + } + } else { /* repeat */ + *r.repeat_idx.mut_last().unwrap() += 1u; + r.stack.mut_last().unwrap().idx = 0; + match r.stack.last().unwrap().sep.clone() { + Some(tk) => { + r.cur_tok = tk; /* repeat same span, I guess */ + return ret_val; + } + None => {} } } } loop { /* because it's easiest, this handles `TTDelim` not starting - with a `TTTok`, even though it won't happen */ - // FIXME(pcwalton): Bad copy. - match (*r.stack.get().forest.get(r.stack.get().idx.get())).clone() { - TTDelim(tts) => { - r.stack.set(@TtFrame { - forest: tts, - idx: Cell::new(0u), - dotdotdoted: false, - sep: None, - up: Some(r.stack.get()) - }); - // if this could be 0-length, we'd need to potentially recur here - } - TTTok(sp, tok) => { - r.cur_span.set(sp); - r.cur_tok.set(tok); - r.stack.get().idx.set(r.stack.get().idx.get() + 1u); - return ret_val; - } - TTSeq(sp, tts, sep, zerok) => { + with a `TTTok`, even though it won't happen */ + let t = { + let frame = r.stack.last().unwrap(); // FIXME(pcwalton): Bad copy. - let t = TTSeq(sp, tts, sep.clone(), zerok); - match lockstep_iter_size(&t, r) { - LisUnconstrained => { - r.sp_diag.span_fatal( - sp, /* blame macro writer */ - "attempted to repeat an expression \ - containing no syntax \ - variables matched as repeating at this depth"); - } - LisContradiction(ref msg) => { - /* FIXME #2887 blame macro invoker instead*/ - r.sp_diag.span_fatal(sp, (*msg)); - } - LisConstraint(len, _) => { - if len == 0 { - if !zerok { - r.sp_diag.span_fatal(sp, /* FIXME #2887 blame invoker - */ - "this must repeat at least \ - once"); - } - - r.stack.get().idx.set(r.stack.get().idx.get() + 1u); - return tt_next_token(r); - } else { - r.repeat_len.borrow_mut().push(len); - r.repeat_idx.borrow_mut().push(0u); - r.stack.set(@TtFrame { - forest: tts, - idx: Cell::new(0u), - dotdotdoted: true, - sep: sep, - up: Some(r.stack.get()) - }); - } - } + (*frame.forest.get(frame.idx)).clone() + }; + match t { + TTDelim(tts) => { + r.stack.push(TtFrame { + forest: tts, + idx: 0, + dotdotdoted: false, + sep: None + }); + // if this could be 0-length, we'd need to potentially recur here } - } - // FIXME #2887: think about span stuff here - TTNonterminal(sp, ident) => { - match *lookup_cur_matched(r, ident) { - /* sidestep the interpolation tricks for ident because - (a) idents can be in lots of places, so it'd be a pain - (b) we actually can, since it's a token. */ - MatchedNonterminal(NtIdent(~sn,b)) => { - r.cur_span.set(sp); - r.cur_tok.set(IDENT(sn,b)); - r.stack.get().idx.set(r.stack.get().idx.get() + 1u); + TTTok(sp, tok) => { + r.cur_span = sp; + r.cur_tok = tok; + r.stack.mut_last().unwrap().idx += 1; return ret_val; - } - MatchedNonterminal(ref other_whole_nt) => { + } + TTSeq(sp, tts, sep, zerok) => { // FIXME(pcwalton): Bad copy. - r.cur_span.set(sp); - r.cur_tok.set(INTERPOLATED((*other_whole_nt).clone())); - r.stack.get().idx.set(r.stack.get().idx.get() + 1u); - return ret_val; - } - MatchedSeq(..) => { - r.sp_diag.span_fatal( - r.cur_span.get(), /* blame the macro writer */ - format!("variable '{}' is still repeating at this depth", - token::get_ident(ident))); - } + match lockstep_iter_size(&TTSeq(sp, tts.clone(), sep.clone(), zerok), r) { + LisUnconstrained => { + r.sp_diag.span_fatal( + sp.clone(), /* blame macro writer */ + "attempted to repeat an expression \ + containing no syntax \ + variables matched as repeating at this depth"); + } + LisContradiction(ref msg) => { + // FIXME #2887 blame macro invoker instead + r.sp_diag.span_fatal(sp.clone(), *msg); + } + LisConstraint(len, _) => { + if len == 0 { + if !zerok { + // FIXME #2887 blame invoker + r.sp_diag.span_fatal(sp.clone(), + "this must repeat at least once"); + } + + r.stack.mut_last().unwrap().idx += 1; + return tt_next_token(r); + } + r.repeat_len.push(len); + r.repeat_idx.push(0); + r.stack.push(TtFrame { + forest: tts, + idx: 0, + dotdotdoted: true, + sep: sep.clone() + }); + } + } + } + // FIXME #2887: think about span stuff here + TTNonterminal(sp, ident) => { + r.stack.mut_last().unwrap().idx += 1; + match *lookup_cur_matched(r, ident) { + /* sidestep the interpolation tricks for ident because + (a) idents can be in lots of places, so it'd be a pain + (b) we actually can, since it's a token. */ + MatchedNonterminal(NtIdent(~sn,b)) => { + r.cur_span = sp; + r.cur_tok = IDENT(sn,b); + return ret_val; + } + MatchedNonterminal(ref other_whole_nt) => { + // FIXME(pcwalton): Bad copy. + r.cur_span = sp; + r.cur_tok = INTERPOLATED((*other_whole_nt).clone()); + return ret_val; + } + MatchedSeq(..) => { + r.sp_diag.span_fatal( + r.cur_span, /* blame the macro writer */ + format!("variable '{}' is still repeating at this depth", + token::get_ident(ident))); + } + } } - } } } - } |
