about summary refs log tree commit diff
path: root/src/libsyntax/parse
diff options
context:
space:
mode:
authorJohn Clements <clements@racket-lang.org>2013-02-26 10:15:29 -0800
committerJohn Clements <clements@racket-lang.org>2013-02-26 10:36:55 -0800
commit08b6057538b9bb81bb71db632344ed0312e57f5f (patch)
tree66bf782f1ab3f8e6194f4d156bf384be2f4d3858 /src/libsyntax/parse
parent5e319fb2827903d6cb0c0d9d0af638c3f9503c81 (diff)
downloadrust-08b6057538b9bb81bb71db632344ed0312e57f5f.tar.gz
rust-08b6057538b9bb81bb71db632344ed0312e57f5f.zip
Macros now leave scope
Macro scope is now delimited by function, block, and module boundaries,
except for modules that are marked with #[macro_escape], which allows
macros to escape.
Diffstat (limited to 'src/libsyntax/parse')
-rw-r--r--src/libsyntax/parse/lexer.rs48
-rw-r--r--src/libsyntax/parse/mod.rs36
-rw-r--r--src/libsyntax/parse/token.rs4
3 files changed, 67 insertions, 21 deletions
diff --git a/src/libsyntax/parse/lexer.rs b/src/libsyntax/parse/lexer.rs
index 92c4f1e828f..51cc25e84a3 100644
--- a/src/libsyntax/parse/lexer.rs
+++ b/src/libsyntax/parse/lexer.rs
@@ -770,11 +770,13 @@ pub mod test {
     use diagnostic;
     use util::testing::{check_equal, check_equal_ptr};
 
+    // represents a testing reader (incl. both reader and interner)
     struct Env {
         interner: @token::ident_interner,
         string_reader: @mut StringReader
     }
 
+    // open a string reader for the given string
     fn setup(teststr: ~str) -> Env {
         let cm = CodeMap::new();
         let fm = cm.new_filemap(~"zebra.rs", @teststr);
@@ -809,6 +811,52 @@ pub mod test {
         check_equal (string_reader.last_pos,BytePos(29))
     }
 
+    // check that the given reader produces the desired stream
+    // of tokens (stop checking after exhausting the expected vec)
+    fn check_tokenization (env: Env, expected: ~[token::Token]) {
+        for expected.each |expected_tok| {
+            let TokenAndSpan {tok:actual_tok, sp: _} =
+                env.string_reader.next_token();
+            check_equal(&actual_tok,expected_tok);
+        }
+    }
+
+    // make the identifier by looking up the string in the interner
+    fn mk_ident (env: Env, id: ~str, is_mod_name: bool) -> token::Token {
+        token::IDENT (env.interner.intern(@id),is_mod_name)
+    }
+
+    #[test] fn doublecolonparsing () {
+        let env = setup (~"a b");
+        check_tokenization (env,
+                           ~[mk_ident (env,~"a",false),
+                             mk_ident (env,~"b",false)]);
+    }
+
+    #[test] fn dcparsing_2 () {
+        let env = setup (~"a::b");
+        check_tokenization (env,
+                           ~[mk_ident (env,~"a",true),
+                             token::MOD_SEP,
+                             mk_ident (env,~"b",false)]);
+    }
+
+    #[test] fn dcparsing_3 () {
+        let env = setup (~"a ::b");
+        check_tokenization (env,
+                           ~[mk_ident (env,~"a",false),
+                             token::MOD_SEP,
+                             mk_ident (env,~"b",false)]);
+    }
+
+    #[test] fn dcparsing_4 () {
+        let env = setup (~"a:: b");
+        check_tokenization (env,
+                           ~[mk_ident (env,~"a",true),
+                             token::MOD_SEP,
+                             mk_ident (env,~"b",false)]);
+    }
+
     #[test] fn character_a() {
         let env = setup(~"'a'");
         let TokenAndSpan {tok, sp: _} =
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 5fa61159385..a31a73f594a 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -94,9 +94,7 @@ pub fn parse_crate_from_source_str(name: ~str,
                                    sess: @mut ParseSess) -> @ast::crate {
     let p = new_parser_from_source_str(sess, cfg, name,
                                        codemap::FssNone, source);
-    let r = p.parse_crate_mod(cfg);
-    p.abort_if_errors();
-    return r;
+    maybe_aborted(p.parse_crate_mod(cfg),p)
 }
 
 pub fn parse_expr_from_source_str(name: ~str,
@@ -105,9 +103,7 @@ pub fn parse_expr_from_source_str(name: ~str,
                                   sess: @mut ParseSess) -> @ast::expr {
     let p = new_parser_from_source_str(sess, cfg, name,
                                        codemap::FssNone, source);
-    let r = p.parse_expr();
-    p.abort_if_errors();
-    return r;
+    maybe_aborted(p.parse_expr(), p)
 }
 
 pub fn parse_item_from_source_str(name: ~str,
@@ -118,9 +114,7 @@ pub fn parse_item_from_source_str(name: ~str,
                                -> Option<@ast::item> {
     let p = new_parser_from_source_str(sess, cfg, name,
                                        codemap::FssNone, source);
-    let r = p.parse_item(attrs);
-    p.abort_if_errors();
-    return r;
+    maybe_aborted(p.parse_item(attrs),p)
 }
 
 pub fn parse_stmt_from_source_str(name: ~str,
@@ -130,9 +124,7 @@ pub fn parse_stmt_from_source_str(name: ~str,
                                   sess: @mut ParseSess) -> @ast::stmt {
     let p = new_parser_from_source_str(sess, cfg, name,
                                        codemap::FssNone, source);
-    let r = p.parse_stmt(attrs);
-    p.abort_if_errors();
-    return r;
+    maybe_aborted(p.parse_stmt(attrs),p)
 }
 
 pub fn parse_tts_from_source_str(name: ~str,
@@ -142,9 +134,7 @@ pub fn parse_tts_from_source_str(name: ~str,
     let p = new_parser_from_source_str(sess, cfg, name,
                                        codemap::FssNone, source);
     *p.quote_depth += 1u;
-    let r = p.parse_all_token_trees();
-    p.abort_if_errors();
-    return r;
+    maybe_aborted(p.parse_all_token_trees(),p)
 }
 
 pub fn parse_from_source_str<T>(f: fn (p: Parser) -> T,
@@ -159,8 +149,7 @@ pub fn parse_from_source_str<T>(f: fn (p: Parser) -> T,
     if !p.reader.is_eof() {
         p.reader.fatal(~"expected end-of-string");
     }
-    p.abort_if_errors();
-    r
+    maybe_aborted(r,p)
 }
 
 pub fn next_node_id(sess: @mut ParseSess) -> node_id {
@@ -181,8 +170,8 @@ pub fn new_parser_from_source_str(sess: @mut ParseSess, cfg: ast::crate_cfg,
     return Parser(sess, cfg, srdr as reader);
 }
 
-// Read the entire source file, return a parser
-// that draws from that string
+/// Read the entire source file, return a parser
+/// that draws from that string
 pub fn new_parser_result_from_file(sess: @mut ParseSess,
                             cfg: ast::crate_cfg,
                             path: &Path)
@@ -201,7 +190,7 @@ pub fn new_parser_result_from_file(sess: @mut ParseSess,
     }
 }
 
-/// Create a new parser for an entire crate, handling errors as appropriate
+/// Create a new parser, handling errors as appropriate
 /// if the file doesn't exist
 pub fn new_parser_from_file(sess: @mut ParseSess, cfg: ast::crate_cfg,
                               path: &Path) -> Parser {
@@ -232,6 +221,13 @@ pub fn new_parser_from_tts(sess: @mut ParseSess, cfg: ast::crate_cfg,
     return Parser(sess, cfg, trdr as reader)
 }
 
+// abort if necessary
+pub fn maybe_aborted<T>(+result : T, p: Parser) -> T {
+    p.abort_if_errors();
+    result
+}
+
+
 
 #[cfg(test)]
 mod test {
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index f145e433fa7..207f6d49915 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -87,7 +87,9 @@ pub enum Token {
     LIT_STR(ast::ident),
 
     /* Name components */
-    // an identifier contains an "is_mod_name" boolean.
+    // an identifier contains an "is_mod_name" boolean,
+    // indicating whether :: follows this token with no
+    // whitespace in between.
     IDENT(ast::ident, bool),
     UNDERSCORE,
     LIFETIME(ast::ident),