about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2012-04-19 16:44:24 -0700
committerBrian Anderson <banderson@mozilla.com>2012-04-19 16:59:28 -0700
commitb9ae0c555b5c283553c8b29787dadb3bf6166172 (patch)
tree8c624ee8e031de007341ebeb93ddf5c9cf73ca88 /src
parentf641dce852a66417a5fa6b2c7ccf252a2ea590d7 (diff)
downloadrust-b9ae0c555b5c283553c8b29787dadb3bf6166172.tar.gz
rust-b9ae0c555b5c283553c8b29787dadb3bf6166172.zip
syntax: Funnel all words through a single keyword table
Diffstat (limited to 'src')
-rw-r--r--src/librustsyntax/parse.rs1
-rw-r--r--src/librustsyntax/parse/parser.rs26
-rw-r--r--src/librustsyntax/parse/token.rs36
3 files changed, 53 insertions, 10 deletions
diff --git a/src/librustsyntax/parse.rs b/src/librustsyntax/parse.rs
index 747775ebaa6..dd8caa9a5cc 100644
--- a/src/librustsyntax/parse.rs
+++ b/src/librustsyntax/parse.rs
@@ -77,6 +77,7 @@ fn new_parser(sess: parse_sess, cfg: ast::crate_cfg, rdr: lexer::reader,
       mut restriction: parser::UNRESTRICTED,
       reader: rdr,
       binop_precs: prec::binop_prec_table(),
+      keywords: token::keyword_table(),
       bad_expr_words: token::bad_expr_word_table()}
 }
 
diff --git a/src/librustsyntax/parse/parser.rs b/src/librustsyntax/parse/parser.rs
index 73ec8236fa5..52f9bc29896 100644
--- a/src/librustsyntax/parse/parser.rs
+++ b/src/librustsyntax/parse/parser.rs
@@ -49,6 +49,7 @@ type parser = @{
     mut restriction: restriction,
     reader: reader,
     binop_precs: @[op_spec],
+    keywords: hashmap<str, ()>,
     bad_expr_words: hashmap<str, ()>
 };
 
@@ -83,6 +84,9 @@ impl parser for parser {
     fn span_fatal(sp: span, m: str) -> ! {
         self.sess.span_diagnostic.span_fatal(sp, m)
     }
+    fn bug(m: str) -> ! {
+        self.sess.span_diagnostic.span_bug(self.span, m)
+    }
     fn warn(m: str) {
         self.sess.span_diagnostic.span_warn(self.span, m)
     }
@@ -161,7 +165,15 @@ fn eat(p: parser, tok: token::token) -> bool {
     ret if p.token == tok { p.bump(); true } else { false };
 }
 
+// A sanity check that the word we are asking for is a known keyword
+fn require_keyword(p: parser, word: str) {
+    if !p.keywords.contains_key(word) {
+        p.bug(#fmt("unknown keyword: %s", word));
+    }
+}
+
 fn is_word(p: parser, word: str) -> bool {
+    require_keyword(p, word);
     ret alt p.token {
           token::IDENT(sid, false) { str::eq(word, p.get_str(sid)) }
           _ { false }
@@ -169,6 +181,7 @@ fn is_word(p: parser, word: str) -> bool {
 }
 
 fn eat_word(p: parser, word: str) -> bool {
+    require_keyword(p, word);
     alt p.token {
       token::IDENT(sid, false) {
         if str::eq(word, p.get_str(sid)) {
@@ -181,6 +194,7 @@ fn eat_word(p: parser, word: str) -> bool {
 }
 
 fn expect_word(p: parser, word: str) {
+    require_keyword(p, word);
     if !eat_word(p, word) {
         p.fatal("expecting " + word + ", found " +
                     token_to_str(p.reader, p.token));
@@ -386,6 +400,9 @@ fn parse_ret_ty(p: parser) -> (ast::ret_style, @ast::ty) {
 fn region_from_name(p: parser, s: option<str>) -> ast::region {
     let r = alt s {
       some (string) {
+        // FIXME: To be consistent with our type resolution the
+        // static region should probably be resolved during type
+        // checking, not in the parser.
         if string == "static" {
             ast::re_static
         } else {
@@ -2578,14 +2595,7 @@ fn parse_view_item(p: parser) -> @ast::view_item {
 }
 
 fn is_view_item(p: parser) -> bool {
-    alt p.token {
-      token::IDENT(sid, false) {
-        let st = p.get_str(sid);
-        ret str::eq(st, "use") || str::eq(st, "import") ||
-                str::eq(st, "export");
-      }
-      _ { ret false; }
-    }
+    is_word(p, "use") || is_word(p, "import") || is_word(p, "export")
 }
 
 fn maybe_parse_view(
diff --git a/src/librustsyntax/parse/token.rs b/src/librustsyntax/parse/token.rs
index 1b4e871270a..f60e2f26381 100644
--- a/src/librustsyntax/parse/token.rs
+++ b/src/librustsyntax/parse/token.rs
@@ -218,6 +218,38 @@ fn is_bad_expr_word(t: token,
 }
 
 #[doc = "
+All the valid words that have meaning in the Rust language. Some of these are
+nonetheless valid as identifiers becasue they are unambiguous.
+"]
+fn keyword_table() -> hashmap<str, ()> {
+    let keywords = str_hash();
+    bad_expr_word_table().keys() {|word|
+        keywords.insert(word, ());
+    }
+    let other_keywords = [
+        "as",
+        "bind",
+        "else",
+        "false",
+        "implements",
+        "move",
+        "of",
+        "priv",
+        "self",
+        "send",
+        "static",
+        "to",
+        "true",
+        "use",
+        "with"
+    ];
+    for other_keywords.each {|word|
+        keywords.insert(word, ());
+    }
+    ret keywords;
+}
+
+#[doc = "
 These are the words that shouldn't be allowed as value identifiers,
 because, if used at the start of a line, they will cause the line to be
 interpreted as a specific kind of statement, which would be confusing.
@@ -228,8 +260,8 @@ fn bad_expr_word_table() -> hashmap<str, ()> {
                 "class", "const", "cont", "copy", "crust", "do", "else",
                 "enum", "export", "fail", "fn", "for", "if",  "iface",
                 "impl", "import", "let", "log", "loop", "mod",
-                "mut", "native", "pure", "resource", "ret", "trait",
-                "type", "unchecked", "unsafe", "while", "new"];
+                "mut", "mutable", "native", "new", "pure", "resource",
+                "ret", "trait", "type", "unchecked", "unsafe", "while"];
     for keys.each {|word|
         words.insert(word, ());
     }