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/parse | |
| 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/parse')
| -rw-r--r-- | src/libsyntax/parse/comments.rs | 62 | ||||
| -rw-r--r-- | src/libsyntax/parse/lexer.rs | 321 | ||||
| -rw-r--r-- | src/libsyntax/parse/mod.rs | 6 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 9 | ||||
| -rw-r--r-- | src/libsyntax/parse/token.rs | 12 |
5 files changed, 195 insertions, 215 deletions
diff --git a/src/libsyntax/parse/comments.rs b/src/libsyntax/parse/comments.rs index 43ae9b97350..53586a66513 100644 --- a/src/libsyntax/parse/comments.rs +++ b/src/libsyntax/parse/comments.rs @@ -133,44 +133,42 @@ pub fn strip_doc_comment_decoration(comment: &str) -> ~str { fail!("not a doc-comment: {}", comment); } -fn read_to_eol(rdr: &StringReader) -> ~str { +fn read_to_eol(rdr: &mut StringReader) -> ~str { let mut val = ~""; while !rdr.curr_is('\n') && !is_eof(rdr) { - val.push_char(rdr.curr.get().unwrap()); + val.push_char(rdr.curr.unwrap()); bump(rdr); } if rdr.curr_is('\n') { bump(rdr); } return val; } -fn read_one_line_comment(rdr: &StringReader) -> ~str { +fn read_one_line_comment(rdr: &mut StringReader) -> ~str { let val = read_to_eol(rdr); assert!((val[0] == '/' as u8 && val[1] == '/' as u8) || (val[0] == '#' as u8 && val[1] == '!' as u8)); return val; } -fn consume_non_eol_whitespace(rdr: &StringReader) { - while is_whitespace(rdr.curr.get()) && !rdr.curr_is('\n') && - !is_eof(rdr) { +fn consume_non_eol_whitespace(rdr: &mut StringReader) { + while is_whitespace(rdr.curr) && !rdr.curr_is('\n') && !is_eof(rdr) { bump(rdr); } } -fn push_blank_line_comment(rdr: &StringReader, comments: &mut Vec<Comment> ) { +fn push_blank_line_comment(rdr: &StringReader, comments: &mut Vec<Comment>) { debug!(">>> blank-line comment"); - let v: Vec<~str> = Vec::new(); comments.push(Comment { style: BlankLine, - lines: v, - pos: rdr.last_pos.get(), + lines: Vec::new(), + pos: rdr.last_pos, }); } -fn consume_whitespace_counting_blank_lines(rdr: &StringReader, - comments: &mut Vec<Comment> ) { - while is_whitespace(rdr.curr.get()) && !is_eof(rdr) { - if rdr.col.get() == CharPos(0u) && rdr.curr_is('\n') { +fn consume_whitespace_counting_blank_lines(rdr: &mut StringReader, + comments: &mut Vec<Comment>) { + while is_whitespace(rdr.curr) && !is_eof(rdr) { + if rdr.col == CharPos(0u) && rdr.curr_is('\n') { push_blank_line_comment(rdr, &mut *comments); } bump(rdr); @@ -178,10 +176,10 @@ fn consume_whitespace_counting_blank_lines(rdr: &StringReader, } -fn read_shebang_comment(rdr: &StringReader, code_to_the_left: bool, - comments: &mut Vec<Comment> ) { +fn read_shebang_comment(rdr: &mut StringReader, code_to_the_left: bool, + comments: &mut Vec<Comment>) { debug!(">>> shebang comment"); - let p = rdr.last_pos.get(); + let p = rdr.last_pos; debug!("<<< shebang comment"); comments.push(Comment { style: if code_to_the_left { Trailing } else { Isolated }, @@ -190,10 +188,10 @@ fn read_shebang_comment(rdr: &StringReader, code_to_the_left: bool, }); } -fn read_line_comments(rdr: &StringReader, code_to_the_left: bool, - comments: &mut Vec<Comment> ) { +fn read_line_comments(rdr: &mut StringReader, code_to_the_left: bool, + comments: &mut Vec<Comment>) { debug!(">>> line comments"); - let p = rdr.last_pos.get(); + let p = rdr.last_pos; let mut lines: Vec<~str> = Vec::new(); while rdr.curr_is('/') && nextch_is(rdr, '/') { let line = read_one_line_comment(rdr); @@ -247,13 +245,13 @@ fn trim_whitespace_prefix_and_push_line(lines: &mut Vec<~str> , lines.push(s1); } -fn read_block_comment(rdr: &StringReader, +fn read_block_comment(rdr: &mut StringReader, code_to_the_left: bool, comments: &mut Vec<Comment> ) { debug!(">>> block comment"); - let p = rdr.last_pos.get(); + let p = rdr.last_pos; let mut lines: Vec<~str> = Vec::new(); - let col: CharPos = rdr.col.get(); + let col = rdr.col; bump(rdr); bump(rdr); @@ -262,7 +260,7 @@ fn read_block_comment(rdr: &StringReader, // doc-comments are not really comments, they are attributes if (rdr.curr_is('*') && !nextch_is(rdr, '*')) || rdr.curr_is('!') { while !(rdr.curr_is('*') && nextch_is(rdr, '/')) && !is_eof(rdr) { - curr_line.push_char(rdr.curr.get().unwrap()); + curr_line.push_char(rdr.curr.unwrap()); bump(rdr); } if !is_eof(rdr) { @@ -286,7 +284,7 @@ fn read_block_comment(rdr: &StringReader, curr_line = ~""; bump(rdr); } else { - curr_line.push_char(rdr.curr.get().unwrap()); + curr_line.push_char(rdr.curr.unwrap()); if rdr.curr_is('/') && nextch_is(rdr, '*') { bump(rdr); bump(rdr); @@ -324,7 +322,7 @@ fn peeking_at_comment(rdr: &StringReader) -> bool { !lexer::nextnextch_is(rdr, '[')); } -fn consume_comment(rdr: &StringReader, +fn consume_comment(rdr: &mut StringReader, code_to_the_left: bool, comments: &mut Vec<Comment> ) { debug!(">>> consume comment"); @@ -355,7 +353,7 @@ pub fn gather_comments_and_literals(span_diagnostic: let src = str::from_utf8_owned(src).unwrap(); let cm = CodeMap::new(); let filemap = cm.new_filemap(path, src); - let rdr = lexer::new_low_level_string_reader(span_diagnostic, filemap); + let mut rdr = lexer::new_low_level_string_reader(span_diagnostic, filemap); let mut comments: Vec<Comment> = Vec::new(); let mut literals: Vec<Literal> = Vec::new(); @@ -363,20 +361,20 @@ pub fn gather_comments_and_literals(span_diagnostic: while !is_eof(&rdr) { loop { let mut code_to_the_left = !first_read; - consume_non_eol_whitespace(&rdr); + consume_non_eol_whitespace(&mut rdr); if rdr.curr_is('\n') { code_to_the_left = false; - consume_whitespace_counting_blank_lines(&rdr, &mut comments); + consume_whitespace_counting_blank_lines(&mut rdr, &mut comments); } while peeking_at_comment(&rdr) { - consume_comment(&rdr, code_to_the_left, &mut comments); - consume_whitespace_counting_blank_lines(&rdr, &mut comments); + consume_comment(&mut rdr, code_to_the_left, &mut comments); + consume_whitespace_counting_blank_lines(&mut rdr, &mut comments); } break; } - let bstart = rdr.last_pos.get(); + let bstart = rdr.last_pos; rdr.next_token(); //discard, and look ahead; we're working with internal state let TokenAndSpan {tok: tok, sp: sp} = rdr.peek(); diff --git a/src/libsyntax/parse/lexer.rs b/src/libsyntax/parse/lexer.rs index ccee21f6281..c18571deaf5 100644 --- a/src/libsyntax/parse/lexer.rs +++ b/src/libsyntax/parse/lexer.rs @@ -12,11 +12,10 @@ use ast; use codemap::{BytePos, CharPos, CodeMap, Pos, Span}; use codemap; use diagnostic::SpanHandler; -use ext::tt::transcribe::{dup_tt_reader, tt_next_token}; +use ext::tt::transcribe::tt_next_token; use parse::token; use parse::token::{str_to_ident}; -use std::cell::{Cell, RefCell}; use std::char; use std::mem::replace; use std::num::from_str_radix; @@ -27,11 +26,10 @@ pub use ext::tt::transcribe::{TtReader, new_tt_reader}; pub trait Reader { fn is_eof(&self) -> bool; - fn next_token(&self) -> TokenAndSpan; + fn next_token(&mut self) -> TokenAndSpan; fn fatal(&self, ~str) -> !; fn span_diag<'a>(&'a self) -> &'a SpanHandler; fn peek(&self) -> TokenAndSpan; - fn dup(&self) -> ~Reader:; } #[deriving(Clone, Eq, Show)] @@ -43,30 +41,30 @@ pub struct TokenAndSpan { pub struct StringReader<'a> { span_diagnostic: &'a SpanHandler, // The absolute offset within the codemap of the next character to read - pos: Cell<BytePos>, + pos: BytePos, // The absolute offset within the codemap of the last character read(curr) - last_pos: Cell<BytePos>, + last_pos: BytePos, // The column of the next character to read - col: Cell<CharPos>, + col: CharPos, // The last character to be read - curr: Cell<Option<char>>, + curr: Option<char>, filemap: Rc<codemap::FileMap>, /* cached: */ - peek_tok: RefCell<token::Token>, - peek_span: RefCell<Span>, + peek_tok: token::Token, + peek_span: Span, } impl<'a> StringReader<'a> { pub fn curr_is(&self, c: char) -> bool { - self.curr.get() == Some(c) + self.curr == Some(c) } } pub fn new_string_reader<'a>(span_diagnostic: &'a SpanHandler, filemap: Rc<codemap::FileMap>) -> StringReader<'a> { - let r = new_low_level_string_reader(span_diagnostic, filemap); - string_advance_token(&r); /* fill in peek_* */ + let mut r = new_low_level_string_reader(span_diagnostic, filemap); + string_advance_token(&mut r); /* fill in peek_* */ r } @@ -76,97 +74,79 @@ pub fn new_low_level_string_reader<'a>(span_diagnostic: &'a SpanHandler, -> StringReader<'a> { // Force the initial reader bump to start on a fresh line let initial_char = '\n'; - let r = StringReader { + let mut r = StringReader { span_diagnostic: span_diagnostic, - pos: Cell::new(filemap.start_pos), - last_pos: Cell::new(filemap.start_pos), - col: Cell::new(CharPos(0)), - curr: Cell::new(Some(initial_char)), + pos: filemap.start_pos, + last_pos: filemap.start_pos, + col: CharPos(0), + curr: Some(initial_char), filemap: filemap, /* dummy values; not read */ - peek_tok: RefCell::new(token::EOF), - peek_span: RefCell::new(codemap::DUMMY_SP), + peek_tok: token::EOF, + peek_span: codemap::DUMMY_SP, }; - bump(&r); + bump(&mut r); r } -// duplicating the string reader is probably a bad idea, in -// that using them will cause interleaved pushes of line -// offsets to the underlying filemap... -fn dup_string_reader<'a>(r: &StringReader<'a>) -> StringReader<'a> { - StringReader { - span_diagnostic: r.span_diagnostic, - pos: Cell::new(r.pos.get()), - last_pos: Cell::new(r.last_pos.get()), - col: Cell::new(r.col.get()), - curr: Cell::new(r.curr.get()), - filemap: r.filemap.clone(), - peek_tok: r.peek_tok.clone(), - peek_span: r.peek_span.clone(), - } -} - impl<'a> Reader for StringReader<'a> { fn is_eof(&self) -> bool { is_eof(self) } // return the next token. EFFECT: advances the string_reader. - fn next_token(&self) -> TokenAndSpan { + fn next_token(&mut self) -> TokenAndSpan { let ret_val = TokenAndSpan { - tok: replace(&mut *self.peek_tok.borrow_mut(), token::UNDERSCORE), - sp: self.peek_span.get(), + tok: replace(&mut self.peek_tok, token::UNDERSCORE), + sp: self.peek_span, }; string_advance_token(self); ret_val } fn fatal(&self, m: ~str) -> ! { - self.span_diagnostic.span_fatal(self.peek_span.get(), m) + self.span_diagnostic.span_fatal(self.peek_span, m) } fn span_diag<'a>(&'a self) -> &'a SpanHandler { self.span_diagnostic } fn peek(&self) -> TokenAndSpan { // FIXME(pcwalton): Bad copy! TokenAndSpan { - tok: self.peek_tok.get(), - sp: self.peek_span.get(), + tok: self.peek_tok.clone(), + sp: self.peek_span.clone(), } } - fn dup(&self) -> ~Reader: { ~dup_string_reader(self) as ~Reader: } } impl<'a> Reader for TtReader<'a> { fn is_eof(&self) -> bool { - *self.cur_tok.borrow() == token::EOF + self.cur_tok == token::EOF } - fn next_token(&self) -> TokenAndSpan { + fn next_token(&mut self) -> TokenAndSpan { let r = tt_next_token(self); debug!("TtReader: r={:?}", r); - return r; + r } fn fatal(&self, m: ~str) -> ! { - self.sp_diag.span_fatal(self.cur_span.get(), m); + self.sp_diag.span_fatal(self.cur_span, m); } fn span_diag<'a>(&'a self) -> &'a SpanHandler { self.sp_diag } fn peek(&self) -> TokenAndSpan { TokenAndSpan { - tok: self.cur_tok.get(), - sp: self.cur_span.get(), + tok: self.cur_tok.clone(), + sp: self.cur_span.clone(), } } - fn dup(&self) -> ~Reader: { ~dup_tt_reader(self) as ~Reader: } } // report a lexical error spanning [`from_pos`, `to_pos`) -fn fatal_span(rdr: &StringReader, +fn fatal_span(rdr: &mut StringReader, from_pos: BytePos, to_pos: BytePos, m: ~str) -> ! { - rdr.peek_span.set(codemap::mk_sp(from_pos, to_pos)); + rdr.peek_span = codemap::mk_sp(from_pos, to_pos); rdr.fatal(m); } // report a lexical error spanning [`from_pos`, `to_pos`), appending an // escaped character to the error message -fn fatal_span_char(rdr: &StringReader, +fn fatal_span_char(rdr: &mut StringReader, from_pos: BytePos, to_pos: BytePos, m: ~str, @@ -180,36 +160,35 @@ fn fatal_span_char(rdr: &StringReader, // report a lexical error spanning [`from_pos`, `to_pos`), appending the // offending string to the error message -fn fatal_span_verbose(rdr: &StringReader, +fn fatal_span_verbose(rdr: &mut StringReader, from_pos: BytePos, to_pos: BytePos, m: ~str) -> ! { let mut m = m; m.push_str(": "); - let s = rdr.filemap.src.slice( - byte_offset(rdr, from_pos).to_uint(), - byte_offset(rdr, to_pos).to_uint()); - m.push_str(s); + let from = byte_offset(rdr, from_pos).to_uint(); + let to = byte_offset(rdr, to_pos).to_uint(); + m.push_str(rdr.filemap.src.slice(from, to)); fatal_span(rdr, from_pos, to_pos, m); } // EFFECT: advance peek_tok and peek_span to refer to the next token. // EFFECT: update the interner, maybe. -fn string_advance_token(r: &StringReader) { +fn string_advance_token(r: &mut StringReader) { match consume_whitespace_and_comments(r) { Some(comment) => { - r.peek_span.set(comment.sp); - r.peek_tok.set(comment.tok); + r.peek_span = comment.sp; + r.peek_tok = comment.tok; }, None => { if is_eof(r) { - r.peek_tok.set(token::EOF); + r.peek_tok = token::EOF; } else { - let start_bytepos = r.last_pos.get(); - r.peek_tok.set(next_token_inner(r)); - r.peek_span.set(codemap::mk_sp(start_bytepos, - r.last_pos.get())); + let start_bytepos = r.last_pos; + r.peek_tok = next_token_inner(r); + r.peek_span = codemap::mk_sp(start_bytepos, + r.last_pos); }; } } @@ -227,7 +206,7 @@ pub fn with_str_from<T>( start: BytePos, f: |s: &str| -> T) -> T { - with_str_from_to(rdr, start, rdr.last_pos.get(), f) + with_str_from_to(rdr, start, rdr.last_pos, f) } /// Calls `f` with astring slice of the source text spanning from `start` @@ -245,36 +224,36 @@ fn with_str_from_to<T>( // EFFECT: advance the StringReader by one character. If a newline is // discovered, add it to the FileMap's list of line start offsets. -pub fn bump(rdr: &StringReader) { - rdr.last_pos.set(rdr.pos.get()); - let current_byte_offset = byte_offset(rdr, rdr.pos.get()).to_uint(); +pub fn bump(rdr: &mut StringReader) { + rdr.last_pos = rdr.pos; + let current_byte_offset = byte_offset(rdr, rdr.pos).to_uint(); if current_byte_offset < rdr.filemap.src.len() { - assert!(rdr.curr.get().is_some()); - let last_char = rdr.curr.get().unwrap(); + assert!(rdr.curr.is_some()); + let last_char = rdr.curr.unwrap(); let next = rdr.filemap.src.char_range_at(current_byte_offset); let byte_offset_diff = next.next - current_byte_offset; - rdr.pos.set(rdr.pos.get() + Pos::from_uint(byte_offset_diff)); - rdr.curr.set(Some(next.ch)); - rdr.col.set(rdr.col.get() + CharPos(1u)); + rdr.pos = rdr.pos + Pos::from_uint(byte_offset_diff); + rdr.curr = Some(next.ch); + rdr.col = rdr.col + CharPos(1u); if last_char == '\n' { - rdr.filemap.next_line(rdr.last_pos.get()); - rdr.col.set(CharPos(0u)); + rdr.filemap.next_line(rdr.last_pos); + rdr.col = CharPos(0u); } if byte_offset_diff > 1 { - rdr.filemap.record_multibyte_char(rdr.last_pos.get(), byte_offset_diff); + rdr.filemap.record_multibyte_char(rdr.last_pos, byte_offset_diff); } } else { - rdr.curr.set(None); + rdr.curr = None; } } pub fn is_eof(rdr: &StringReader) -> bool { - rdr.curr.get().is_none() + rdr.curr.is_none() } pub fn nextch(rdr: &StringReader) -> Option<char> { - let offset = byte_offset(rdr, rdr.pos.get()).to_uint(); + let offset = byte_offset(rdr, rdr.pos).to_uint(); if offset < rdr.filemap.src.len() { Some(rdr.filemap.src.char_at(offset)) } else { @@ -286,7 +265,7 @@ pub fn nextch_is(rdr: &StringReader, c: char) -> bool { } pub fn nextnextch(rdr: &StringReader) -> Option<char> { - let offset = byte_offset(rdr, rdr.pos.get()).to_uint(); + let offset = byte_offset(rdr, rdr.pos).to_uint(); let s = rdr.filemap.deref().src.as_slice(); if offset >= s.len() { return None } let str::CharRange { next, .. } = s.char_range_at(offset); @@ -332,9 +311,9 @@ fn is_hex_digit(c: Option<char>) -> bool { // EFFECT: eats whitespace and comments. // returns a Some(sugared-doc-attr) if one exists, None otherwise. -fn consume_whitespace_and_comments(rdr: &StringReader) +fn consume_whitespace_and_comments(rdr: &mut StringReader) -> Option<TokenAndSpan> { - while is_whitespace(rdr.curr.get()) { bump(rdr); } + while is_whitespace(rdr.curr) { bump(rdr); } return consume_any_line_comment(rdr); } @@ -345,7 +324,7 @@ pub fn is_line_non_doc_comment(s: &str) -> bool { // PRECONDITION: rdr.curr is not whitespace // EFFECT: eats any kind of comment. // returns a Some(sugared-doc-attr) if one exists, None otherwise -fn consume_any_line_comment(rdr: &StringReader) +fn consume_any_line_comment(rdr: &mut StringReader) -> Option<TokenAndSpan> { if rdr.curr_is('/') { match nextch(rdr) { @@ -354,7 +333,7 @@ fn consume_any_line_comment(rdr: &StringReader) bump(rdr); // line comments starting with "///" or "//!" are doc-comments if rdr.curr_is('/') || rdr.curr_is('!') { - let start_bpos = rdr.pos.get() - BytePos(3); + let start_bpos = rdr.pos - BytePos(3); while !rdr.curr_is('\n') && !is_eof(rdr) { bump(rdr); } @@ -363,7 +342,7 @@ fn consume_any_line_comment(rdr: &StringReader) if !is_line_non_doc_comment(string) { Some(TokenAndSpan{ tok: token::DOC_COMMENT(str_to_ident(string)), - sp: codemap::mk_sp(start_bpos, rdr.pos.get()) + sp: codemap::mk_sp(start_bpos, rdr.pos) }) } else { None @@ -394,7 +373,7 @@ fn consume_any_line_comment(rdr: &StringReader) // we're at the beginning of the file... let cmap = CodeMap::new(); cmap.files.borrow_mut().push(rdr.filemap.clone()); - let loc = cmap.lookup_char_pos_adj(rdr.last_pos.get()); + let loc = cmap.lookup_char_pos_adj(rdr.last_pos); if loc.line == 1u && loc.col == CharPos(0u) { while !rdr.curr_is('\n') && !is_eof(rdr) { bump(rdr); } return consume_whitespace_and_comments(rdr); @@ -411,10 +390,10 @@ pub fn is_block_non_doc_comment(s: &str) -> bool { } // might return a sugared-doc-attr -fn consume_block_comment(rdr: &StringReader) -> Option<TokenAndSpan> { +fn consume_block_comment(rdr: &mut StringReader) -> Option<TokenAndSpan> { // block comments starting with "/**" or "/*!" are doc-comments let is_doc_comment = rdr.curr_is('*') || rdr.curr_is('!'); - let start_bpos = rdr.pos.get() - BytePos(if is_doc_comment {3} else {2}); + let start_bpos = rdr.pos - BytePos(if is_doc_comment {3} else {2}); let mut level: int = 1; while level > 0 { @@ -424,7 +403,7 @@ fn consume_block_comment(rdr: &StringReader) -> Option<TokenAndSpan> { } else { ~"unterminated block comment" }; - fatal_span(rdr, start_bpos, rdr.last_pos.get(), msg); + fatal_span(rdr, start_bpos, rdr.last_pos, msg); } else if rdr.curr_is('/') && nextch_is(rdr, '*') { level += 1; bump(rdr); @@ -444,7 +423,7 @@ fn consume_block_comment(rdr: &StringReader) -> Option<TokenAndSpan> { if !is_block_non_doc_comment(string) { Some(TokenAndSpan{ tok: token::DOC_COMMENT(str_to_ident(string)), - sp: codemap::mk_sp(start_bpos, rdr.pos.get()) + sp: codemap::mk_sp(start_bpos, rdr.pos) }) } else { None @@ -458,14 +437,14 @@ fn consume_block_comment(rdr: &StringReader) -> Option<TokenAndSpan> { if res.is_some() { res } else { consume_whitespace_and_comments(rdr) } } -fn scan_exponent(rdr: &StringReader, start_bpos: BytePos) -> Option<~str> { +fn scan_exponent(rdr: &mut StringReader, start_bpos: BytePos) -> Option<~str> { // \x00 hits the `return None` case immediately, so this is fine. - let mut c = rdr.curr.get().unwrap_or('\x00'); + let mut c = rdr.curr.unwrap_or('\x00'); let mut rslt = ~""; if c == 'e' || c == 'E' { rslt.push_char(c); bump(rdr); - c = rdr.curr.get().unwrap_or('\x00'); + c = rdr.curr.unwrap_or('\x00'); if c == '-' || c == '+' { rslt.push_char(c); bump(rdr); @@ -474,16 +453,16 @@ fn scan_exponent(rdr: &StringReader, start_bpos: BytePos) -> Option<~str> { if exponent.len() > 0u { return Some(rslt + exponent); } else { - fatal_span(rdr, start_bpos, rdr.last_pos.get(), + fatal_span(rdr, start_bpos, rdr.last_pos, ~"scan_exponent: bad fp literal"); } } else { return None::<~str>; } } -fn scan_digits(rdr: &StringReader, radix: uint) -> ~str { +fn scan_digits(rdr: &mut StringReader, radix: uint) -> ~str { let mut rslt = ~""; loop { - let c = rdr.curr.get(); + let c = rdr.curr; if c == Some('_') { bump(rdr); continue; } match c.and_then(|cc| char::to_digit(cc, radix)) { Some(_) => { @@ -495,7 +474,7 @@ fn scan_digits(rdr: &StringReader, radix: uint) -> ~str { }; } -fn check_float_base(rdr: &StringReader, start_bpos: BytePos, last_bpos: BytePos, +fn check_float_base(rdr: &mut StringReader, start_bpos: BytePos, last_bpos: BytePos, base: uint) { match base { 16u => fatal_span(rdr, start_bpos, last_bpos, @@ -508,12 +487,12 @@ fn check_float_base(rdr: &StringReader, start_bpos: BytePos, last_bpos: BytePos, } } -fn scan_number(c: char, rdr: &StringReader) -> token::Token { +fn scan_number(c: char, rdr: &mut StringReader) -> token::Token { let mut num_str; let mut base = 10u; let mut c = c; let mut n = nextch(rdr).unwrap_or('\x00'); - let start_bpos = rdr.last_pos.get(); + let start_bpos = rdr.last_pos; if c == '0' && n == 'x' { bump(rdr); bump(rdr); @@ -528,7 +507,7 @@ fn scan_number(c: char, rdr: &StringReader) -> token::Token { base = 2u; } num_str = scan_digits(rdr, base); - c = rdr.curr.get().unwrap_or('\x00'); + c = rdr.curr.unwrap_or('\x00'); nextch(rdr); if c == 'u' || c == 'i' { enum Result { Signed(ast::IntTy), Unsigned(ast::UintTy) } @@ -538,7 +517,7 @@ fn scan_number(c: char, rdr: &StringReader) -> token::Token { else { Unsigned(ast::TyU) } }; bump(rdr); - c = rdr.curr.get().unwrap_or('\x00'); + c = rdr.curr.unwrap_or('\x00'); if c == '8' { bump(rdr); tp = if signed { Signed(ast::TyI8) } @@ -562,12 +541,12 @@ fn scan_number(c: char, rdr: &StringReader) -> token::Token { else { Unsigned(ast::TyU64) }; } if num_str.len() == 0u { - fatal_span(rdr, start_bpos, rdr.last_pos.get(), + fatal_span(rdr, start_bpos, rdr.last_pos, ~"no valid digits found for number"); } let parsed = match from_str_radix::<u64>(num_str, base as uint) { Some(p) => p, - None => fatal_span(rdr, start_bpos, rdr.last_pos.get(), + None => fatal_span(rdr, start_bpos, rdr.last_pos, ~"int literal is too large") }; @@ -594,37 +573,37 @@ fn scan_number(c: char, rdr: &StringReader) -> token::Token { if rdr.curr_is('f') { bump(rdr); - c = rdr.curr.get().unwrap_or('\x00'); + c = rdr.curr.unwrap_or('\x00'); n = nextch(rdr).unwrap_or('\x00'); if c == '3' && n == '2' { bump(rdr); bump(rdr); - check_float_base(rdr, start_bpos, rdr.last_pos.get(), base); + check_float_base(rdr, start_bpos, rdr.last_pos, base); return token::LIT_FLOAT(str_to_ident(num_str), ast::TyF32); } else if c == '6' && n == '4' { bump(rdr); bump(rdr); - check_float_base(rdr, start_bpos, rdr.last_pos.get(), base); + check_float_base(rdr, start_bpos, rdr.last_pos, base); return token::LIT_FLOAT(str_to_ident(num_str), ast::TyF64); /* FIXME (#2252): if this is out of range for either a 32-bit or 64-bit float, it won't be noticed till the back-end. */ } else { - fatal_span(rdr, start_bpos, rdr.last_pos.get(), + fatal_span(rdr, start_bpos, rdr.last_pos, ~"expected `f32` or `f64` suffix"); } } if is_float { - check_float_base(rdr, start_bpos, rdr.last_pos.get(), base); + check_float_base(rdr, start_bpos, rdr.last_pos, base); return token::LIT_FLOAT_UNSUFFIXED(str_to_ident(num_str)); } else { if num_str.len() == 0u { - fatal_span(rdr, start_bpos, rdr.last_pos.get(), + fatal_span(rdr, start_bpos, rdr.last_pos, ~"no valid digits found for number"); } let parsed = match from_str_radix::<u64>(num_str, base as uint) { Some(p) => p, - None => fatal_span(rdr, start_bpos, rdr.last_pos.get(), + None => fatal_span(rdr, start_bpos, rdr.last_pos, ~"int literal is too large") }; @@ -633,14 +612,14 @@ fn scan_number(c: char, rdr: &StringReader) -> token::Token { } } -fn scan_numeric_escape(rdr: &StringReader, n_hex_digits: uint) -> char { +fn scan_numeric_escape(rdr: &mut StringReader, n_hex_digits: uint) -> char { let mut accum_int = 0; let mut i = n_hex_digits; - let start_bpos = rdr.last_pos.get(); + let start_bpos = rdr.last_pos; while i != 0u && !is_eof(rdr) { - let n = rdr.curr.get(); + let n = rdr.curr; if !is_hex_digit(n) { - fatal_span_char(rdr, rdr.last_pos.get(), rdr.pos.get(), + fatal_span_char(rdr, rdr.last_pos, rdr.pos, ~"illegal character in numeric character escape", n.unwrap()); } @@ -650,13 +629,13 @@ fn scan_numeric_escape(rdr: &StringReader, n_hex_digits: uint) -> char { i -= 1u; } if i != 0 && is_eof(rdr) { - fatal_span(rdr, start_bpos, rdr.last_pos.get(), + fatal_span(rdr, start_bpos, rdr.last_pos, ~"unterminated numeric character escape"); } match char::from_u32(accum_int as u32) { Some(x) => x, - None => fatal_span(rdr, start_bpos, rdr.last_pos.get(), + None => fatal_span(rdr, start_bpos, rdr.last_pos, ~"illegal numeric character escape") } } @@ -683,14 +662,14 @@ fn ident_continue(c: Option<char>) -> bool { // return the next token from the string // EFFECT: advances the input past that token // EFFECT: updates the interner -fn next_token_inner(rdr: &StringReader) -> token::Token { - let c = rdr.curr.get(); +fn next_token_inner(rdr: &mut StringReader) -> token::Token { + let c = rdr.curr; if ident_start(c) && !nextch_is(rdr, '"') && !nextch_is(rdr, '#') { // Note: r as in r" or r#" is part of a raw string literal, // not an identifier, and is handled further down. - let start = rdr.last_pos.get(); - while ident_continue(rdr.curr.get()) { + let start = rdr.last_pos; + while ident_continue(rdr.curr) { bump(rdr); } @@ -708,7 +687,7 @@ fn next_token_inner(rdr: &StringReader) -> token::Token { if is_dec_digit(c) { return scan_number(c.unwrap(), rdr); } - fn binop(rdr: &StringReader, op: token::BinOp) -> token::Token { + fn binop(rdr: &mut StringReader, op: token::BinOp) -> token::Token { bump(rdr); if rdr.curr_is('=') { bump(rdr); @@ -783,12 +762,12 @@ fn next_token_inner(rdr: &StringReader) -> token::Token { } '<' => { bump(rdr); - match rdr.curr.get().unwrap_or('\x00') { + match rdr.curr.unwrap_or('\x00') { '=' => { bump(rdr); return token::LE; } '<' => { return binop(rdr, token::SHL); } '-' => { bump(rdr); - match rdr.curr.get().unwrap_or('\x00') { + match rdr.curr.unwrap_or('\x00') { '>' => { bump(rdr); return token::DARROW; } _ => { return token::LARROW; } } @@ -798,7 +777,7 @@ fn next_token_inner(rdr: &StringReader) -> token::Token { } '>' => { bump(rdr); - match rdr.curr.get().unwrap_or('\x00') { + match rdr.curr.unwrap_or('\x00') { '=' => { bump(rdr); return token::GE; } '>' => { return binop(rdr, token::SHR); } _ => { return token::GT; } @@ -807,41 +786,41 @@ fn next_token_inner(rdr: &StringReader) -> token::Token { '\'' => { // Either a character constant 'a' OR a lifetime name 'abc bump(rdr); - let start = rdr.last_pos.get(); + let start = rdr.last_pos; // the eof will be picked up by the final `'` check below - let mut c2 = rdr.curr.get().unwrap_or('\x00'); + let mut c2 = rdr.curr.unwrap_or('\x00'); bump(rdr); // If the character is an ident start not followed by another single // quote, then this is a lifetime name: if ident_start(Some(c2)) && !rdr.curr_is('\'') { - while ident_continue(rdr.curr.get()) { + while ident_continue(rdr.curr) { bump(rdr); } - return with_str_from(rdr, start, |lifetime_name| { - let ident = str_to_ident(lifetime_name); - let tok = &token::IDENT(ident, false); - - if token::is_keyword(token::keywords::Self, tok) { - fatal_span(rdr, start, rdr.last_pos.get(), - ~"invalid lifetime name: 'self is no longer a special lifetime"); - } else if token::is_any_keyword(tok) && - !token::is_keyword(token::keywords::Static, tok) { - fatal_span(rdr, start, rdr.last_pos.get(), - ~"invalid lifetime name"); - } else { - token::LIFETIME(ident) - } - }) + let ident = with_str_from(rdr, start, |lifetime_name| { + str_to_ident(lifetime_name) + }); + let tok = &token::IDENT(ident, false); + + if token::is_keyword(token::keywords::Self, tok) { + fatal_span(rdr, start, rdr.last_pos, + ~"invalid lifetime name: 'self is no longer a special lifetime"); + } else if token::is_any_keyword(tok) && + !token::is_keyword(token::keywords::Static, tok) { + fatal_span(rdr, start, rdr.last_pos, + ~"invalid lifetime name"); + } else { + return token::LIFETIME(ident); + } } // Otherwise it is a character constant: match c2 { '\\' => { // '\X' for some X must be a character constant: - let escaped = rdr.curr.get(); - let escaped_pos = rdr.last_pos.get(); + let escaped = rdr.curr; + let escaped_pos = rdr.last_pos; bump(rdr); match escaped { None => {} @@ -858,7 +837,7 @@ fn next_token_inner(rdr: &StringReader) -> token::Token { 'u' => scan_numeric_escape(rdr, 4u), 'U' => scan_numeric_escape(rdr, 8u), c2 => { - fatal_span_char(rdr, escaped_pos, rdr.last_pos.get(), + fatal_span_char(rdr, escaped_pos, rdr.last_pos, ~"unknown character escape", c2) } } @@ -866,7 +845,7 @@ fn next_token_inner(rdr: &StringReader) -> token::Token { } } '\t' | '\n' | '\r' | '\'' => { - fatal_span_char(rdr, start, rdr.last_pos.get(), + fatal_span_char(rdr, start, rdr.last_pos, ~"character constant must be escaped", c2); } _ => {} @@ -877,7 +856,7 @@ fn next_token_inner(rdr: &StringReader) -> token::Token { // character before position `start` is an // ascii single quote. start - BytePos(1), - rdr.last_pos.get(), + rdr.last_pos, ~"unterminated character constant"); } bump(rdr); // advance curr past token @@ -885,25 +864,25 @@ fn next_token_inner(rdr: &StringReader) -> token::Token { } '"' => { let mut accum_str = ~""; - let start_bpos = rdr.last_pos.get(); + let start_bpos = rdr.last_pos; bump(rdr); while !rdr.curr_is('"') { if is_eof(rdr) { - fatal_span(rdr, start_bpos, rdr.last_pos.get(), + fatal_span(rdr, start_bpos, rdr.last_pos, ~"unterminated double quote string"); } - let ch = rdr.curr.get().unwrap(); + let ch = rdr.curr.unwrap(); bump(rdr); match ch { '\\' => { if is_eof(rdr) { - fatal_span(rdr, start_bpos, rdr.last_pos.get(), + fatal_span(rdr, start_bpos, rdr.last_pos, ~"unterminated double quote string"); } - let escaped = rdr.curr.get().unwrap(); - let escaped_pos = rdr.last_pos.get(); + let escaped = rdr.curr.unwrap(); + let escaped_pos = rdr.last_pos; bump(rdr); match escaped { 'n' => accum_str.push_char('\n'), @@ -924,7 +903,7 @@ fn next_token_inner(rdr: &StringReader) -> token::Token { accum_str.push_char(scan_numeric_escape(rdr, 8u)); } c2 => { - fatal_span_char(rdr, escaped_pos, rdr.last_pos.get(), + fatal_span_char(rdr, escaped_pos, rdr.last_pos, ~"unknown string escape", c2); } } @@ -936,7 +915,7 @@ fn next_token_inner(rdr: &StringReader) -> token::Token { return token::LIT_STR(str_to_ident(accum_str)); } 'r' => { - let start_bpos = rdr.last_pos.get(); + let start_bpos = rdr.last_pos; bump(rdr); let mut hash_count = 0u; while rdr.curr_is('#') { @@ -945,24 +924,24 @@ fn next_token_inner(rdr: &StringReader) -> token::Token { } if is_eof(rdr) { - fatal_span(rdr, start_bpos, rdr.last_pos.get(), + fatal_span(rdr, start_bpos, rdr.last_pos, ~"unterminated raw string"); } else if !rdr.curr_is('"') { - fatal_span_char(rdr, start_bpos, rdr.last_pos.get(), + fatal_span_char(rdr, start_bpos, rdr.last_pos, ~"only `#` is allowed in raw string delimitation; \ found illegal character", - rdr.curr.get().unwrap()); + rdr.curr.unwrap()); } bump(rdr); - let content_start_bpos = rdr.last_pos.get(); + let content_start_bpos = rdr.last_pos; let mut content_end_bpos; 'outer: loop { if is_eof(rdr) { - fatal_span(rdr, start_bpos, rdr.last_pos.get(), + fatal_span(rdr, start_bpos, rdr.last_pos, ~"unterminated raw string"); } if rdr.curr_is('"') { - content_end_bpos = rdr.last_pos.get(); + content_end_bpos = rdr.last_pos; for _ in range(0, hash_count) { bump(rdr); if !rdr.curr_is('#') { @@ -1006,14 +985,14 @@ fn next_token_inner(rdr: &StringReader) -> token::Token { '^' => { return binop(rdr, token::CARET); } '%' => { return binop(rdr, token::PERCENT); } c => { - fatal_span_char(rdr, rdr.last_pos.get(), rdr.pos.get(), + fatal_span_char(rdr, rdr.last_pos, rdr.pos, ~"unknown start of token", c); } } } -fn consume_whitespace(rdr: &StringReader) { - while is_whitespace(rdr.curr.get()) && !is_eof(rdr) { bump(rdr); } +fn consume_whitespace(rdr: &mut StringReader) { + while is_whitespace(rdr.curr) && !is_eof(rdr) { bump(rdr); } } #[cfg(test)] @@ -1041,7 +1020,7 @@ mod test { #[test] fn t1 () { let span_handler = mk_sh(); - let string_reader = setup(&span_handler, + let mut string_reader = setup(&span_handler, ~"/* my source file */ \ fn main() { println!(\"zebra\"); }\n"); let id = str_to_ident("fn"); @@ -1051,7 +1030,7 @@ mod test { sp:Span {lo:BytePos(21),hi:BytePos(23),expn_info: None}}; assert_eq!(tok1,tok2); // the 'main' id is already read: - assert_eq!(string_reader.last_pos.get().clone(), BytePos(28)); + assert_eq!(string_reader.last_pos.clone(), BytePos(28)); // read another token: let tok3 = string_reader.next_token(); let tok4 = TokenAndSpan{ @@ -1059,12 +1038,12 @@ mod test { sp:Span {lo:BytePos(24),hi:BytePos(28),expn_info: None}}; assert_eq!(tok3,tok4); // the lparen is already read: - assert_eq!(string_reader.last_pos.get().clone(), BytePos(29)) + assert_eq!(string_reader.last_pos.clone(), BytePos(29)) } // check that the given reader produces the desired stream // of tokens (stop checking after exhausting the expected vec) - fn check_tokenization (string_reader: StringReader, expected: Vec<token::Token> ) { + fn check_tokenization (mut string_reader: StringReader, expected: Vec<token::Token> ) { for expected_tok in expected.iter() { assert_eq!(&string_reader.next_token().tok, expected_tok); } diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 2df93deea14..f2a7f543bd6 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -366,13 +366,13 @@ mod test { [ast::TTTok(_,_), ast::TTTok(_,token::NOT), ast::TTTok(_,_), - ast::TTDelim(delim_elts)] => { + ast::TTDelim(ref delim_elts)] => { let delim_elts: &[ast::TokenTree] = delim_elts.as_slice(); match delim_elts { [ast::TTTok(_,token::LPAREN), - ast::TTDelim(first_set), + ast::TTDelim(ref first_set), ast::TTTok(_,token::FAT_ARROW), - ast::TTDelim(second_set), + ast::TTDelim(ref second_set), ast::TTTok(_,token::RPAREN)] => { let first_set: &[ast::TokenTree] = first_set.as_slice(); diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index aee843bd857..a20854884b2 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -80,6 +80,7 @@ use owned_slice::OwnedSlice; use collections::HashSet; use std::kinds::marker; use std::mem::replace; +use std::rc::Rc; use std::vec; #[allow(non_camel_case_types)] @@ -274,7 +275,7 @@ struct ParsedItemsAndViewItems { /* ident is handled by common.rs */ -pub fn Parser<'a>(sess: &'a ParseSess, cfg: ast::CrateConfig, rdr: ~Reader:) +pub fn Parser<'a>(sess: &'a ParseSess, cfg: ast::CrateConfig, mut rdr: ~Reader:) -> Parser<'a> { let tok0 = rdr.next_token(); let span = tok0.sp; @@ -328,7 +329,7 @@ pub struct Parser<'a> { restriction: restriction, quote_depth: uint, // not (yet) related to the quasiquoter reader: ~Reader:, - interner: @token::IdentInterner, + interner: Rc<token::IdentInterner>, /// The set of seen errors about obsolete syntax. Used to suppress /// extra detail when the same error is seen twice obsolete_set: HashSet<ObsoleteSyntax>, @@ -2104,7 +2105,7 @@ impl<'a> Parser<'a> { let seq = match seq { Spanned { node, .. } => node, }; - TTSeq(mk_sp(sp.lo, p.span.hi), @seq, s, z) + TTSeq(mk_sp(sp.lo, p.span.hi), Rc::new(seq), s, z) } else { TTNonterminal(sp, p.parse_ident()) } @@ -2147,7 +2148,7 @@ impl<'a> Parser<'a> { result.push(parse_any_tt_tok(self)); self.open_braces.pop().unwrap(); - TTDelim(@result) + TTDelim(Rc::new(result)) } _ => parse_non_delim_tt_tok(self) } diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index e3eb1f1f711..f0b4ebc593a 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -22,6 +22,7 @@ use std::char; use std::fmt; use std::local_data; use std::path::BytesContainer; +use std::rc::Rc; #[allow(non_camel_case_types)] #[deriving(Clone, Encodable, Decodable, Eq, TotalEq, Hash, Show)] @@ -531,13 +532,14 @@ pub type IdentInterner = StrInterner; // if an interner exists in TLS, return it. Otherwise, prepare a // fresh one. -pub fn get_ident_interner() -> @IdentInterner { - local_data_key!(key: @::parse::token::IdentInterner) - match local_data::get(key, |k| k.map(|k| *k)) { +// FIXME(eddyb) #8726 This should probably use a task-local reference. +pub fn get_ident_interner() -> Rc<IdentInterner> { + local_data_key!(key: Rc<::parse::token::IdentInterner>) + match local_data::get(key, |k| k.map(|k| k.clone())) { Some(interner) => interner, None => { - let interner = @mk_fresh_ident_interner(); - local_data::set(key, interner); + let interner = Rc::new(mk_fresh_ident_interner()); + local_data::set(key, interner.clone()); interner } } |
