about summary refs log tree commit diff
path: root/src/librustsyntax/parse
diff options
context:
space:
mode:
authorGraydon Hoare <graydon@mozilla.com>2012-04-09 17:32:49 -0700
committerGraydon Hoare <graydon@mozilla.com>2012-04-11 11:08:40 -0700
commit7a3b29024548e1dcb13590002d5cf4dd94ddd4d4 (patch)
treea0cc34e4635bb317347ca1b5424e494ec68e9909 /src/librustsyntax/parse
parent0c94cd5d431816c68825a08bcb24754d09b8dc31 (diff)
downloadrust-7a3b29024548e1dcb13590002d5cf4dd94ddd4d4.tar.gz
rust-7a3b29024548e1dcb13590002d5cf4dd94ddd4d4.zip
Add vstore/evec/estr to compiler.
Diffstat (limited to 'src/librustsyntax/parse')
-rw-r--r--src/librustsyntax/parse/parser.rs143
1 files changed, 113 insertions, 30 deletions
diff --git a/src/librustsyntax/parse/parser.rs b/src/librustsyntax/parse/parser.rs
index c2f1dd58096..05669e1f5f0 100644
--- a/src/librustsyntax/parse/parser.rs
+++ b/src/librustsyntax/parse/parser.rs
@@ -382,15 +382,32 @@ fn parse_type_constraints(p: parser) -> [@ast::ty_constr] {
 
 fn parse_ty_postfix(orig_t: ast::ty_, p: parser, colons_before_params: bool,
                     lo: uint) -> @ast::ty {
+
+
+    fn mk_ty(p: parser, t: ast::ty_, lo: uint, hi: uint) -> @ast::ty {
+        @{id: p.get_id(),
+          node: t,
+          span: ast_util::mk_sp(lo, hi)}
+    }
+
+    if p.token == token::BINOP(token::SLASH) {
+        let orig_hi = p.last_span.hi;
+        alt parse_maybe_vstore(p) {
+          none { }
+          some(v) {
+            let t = ast::ty_vstore(mk_ty(p, orig_t, lo, orig_hi), v);
+            ret mk_ty(p, t, lo, p.last_span.hi);
+          }
+        }
+    }
+
     if colons_before_params && p.token == token::MOD_SEP {
         p.bump();
         expect(p, token::LT);
     } else if !colons_before_params && p.token == token::LT {
         p.bump();
     } else {
-        ret @{id: p.get_id(),
-              node: orig_t,
-              span: ast_util::mk_sp(lo, p.last_span.hi)};
+        ret mk_ty(p, orig_t, lo, p.last_span.hi);
     }
 
     // If we're here, we have explicit type parameter instantiation.
@@ -399,12 +416,11 @@ fn parse_ty_postfix(orig_t: ast::ty_, p: parser, colons_before_params: bool,
 
     alt orig_t {
       ast::ty_path(pth, ann) {
-        ret @{id: p.get_id(),
-              node: ast::ty_path(@spanned(lo, p.last_span.hi,
-                                          {global: pth.node.global,
-                                           idents: pth.node.idents,
-                                           types: seq}), ann),
-              span: ast_util::mk_sp(lo, p.last_span.hi)};
+        ret mk_ty(p, ast::ty_path(@spanned(lo, p.last_span.hi,
+                                           {global: pth.node.global,
+                                            idents: pth.node.idents,
+                                            types: seq}), ann),
+                  lo, p.last_span.hi);
       }
       _ { p.fatal("type parameter instantiation only allowed for paths"); }
     }
@@ -428,22 +444,33 @@ fn parse_ret_ty(p: parser) -> (ast::ret_style, @ast::ty) {
     }
 }
 
-fn parse_region(p: parser) -> ast::region {
-    let region_ = alt p.token {
-        token::IDENT(sid, _) if p.look_ahead(1u) == token::DOT {
-            let string = p.get_str(sid);
-            p.bump(); p.bump();
-            if string == "self" {
-                ast::re_self
-            } else if string == "static" {
-                ast::re_static
-            } else {
-                ast::re_named(string)
-            }
+fn region_from_name(p: parser, s: option<str>) -> ast::region {
+    let r = alt s {
+      some (string) {
+        if string == "self" {
+            ast::re_self
+        } else if string == "static" {
+            ast::re_static
+        } else {
+            ast::re_named(string)
         }
-        _ { ast::re_inferred }
+      }
+      none { ast::re_inferred }
     };
-    ret {id: p.get_id(), node: region_};
+
+    {id: p.get_id(), node: r}
+}
+
+fn parse_region(p: parser) -> ast::region {
+    let name =
+        alt p.token {
+          token::IDENT(sid, _) if p.look_ahead(1u) == token::DOT {
+            p.bump(); p.bump();
+            some(p.get_str(sid))
+          }
+          _ { none }
+        };
+    region_from_name(p, name)
 }
 
 fn parse_ty(p: parser, colons_before_params: bool) -> @ast::ty {
@@ -666,6 +693,44 @@ fn have_dollar(p: parser) -> option<ast::mac_> {
     }
 }
 
+fn parse_maybe_vstore(p: parser) -> option<ast::vstore> {
+    if p.token == token::BINOP(token::SLASH) {
+        p.bump();
+        alt p.token {
+          token::AT {
+            p.bump(); some(ast::vstore_box)
+          }
+          token::TILDE {
+            p.bump(); some(ast::vstore_uniq)
+          }
+          token::UNDERSCORE {
+            p.bump(); some(ast::vstore_fixed(none))
+          }
+          token::LIT_INT(i, ast::ty_i) if i >= 0 {
+            p.bump(); some(ast::vstore_fixed(some(i as uint)))
+          }
+          token::BINOP(token::AND) {
+            p.bump();
+            alt p.token {
+              token::IDENT(sid, _) {
+                p.bump();
+                let n = p.get_str(sid);
+                some(ast::vstore_slice(region_from_name(p, some(n))))
+              }
+              _ {
+                some(ast::vstore_slice(region_from_name(p, none)))
+              }
+            }
+          }
+          _ {
+            none
+          }
+        }
+    } else {
+        none
+    }
+}
+
 fn lit_from_token(p: parser, tok: token::token) -> ast::lit_ {
     alt tok {
       token::LIT_INT(i, it) { ast::lit_int(i, it) }
@@ -678,7 +743,7 @@ fn lit_from_token(p: parser, tok: token::token) -> ast::lit_ {
 }
 
 fn parse_lit(p: parser) -> ast::lit {
-    let sp = p.span;
+    let lo = p.span.lo;
     let lit = if eat_word(p, "true") {
         ast::lit_bool(true)
     } else if eat_word(p, "false") {
@@ -688,7 +753,7 @@ fn parse_lit(p: parser) -> ast::lit {
         p.bump();
         lit_from_token(p, tok)
     };
-    ret {node: lit, span: sp};
+    ret {node: lit, span: ast_util::mk_sp(lo, p.last_span.hi)};
 }
 
 fn is_ident(t: token::token) -> bool {
@@ -891,6 +956,7 @@ fn parse_bottom_expr(p: parser) -> pexpr {
         let es =
             parse_seq_to_end(token::RBRACKET, seq_sep(token::COMMA),
                              parse_expr, p);
+        hi = p.span.hi;
         ex = ast::expr_vec(es, mutbl);
     } else if p.token == token::POUND_LT {
         p.bump();
@@ -988,6 +1054,23 @@ fn parse_bottom_expr(p: parser) -> pexpr {
         hi = lit.span.hi;
         ex = ast::expr_lit(@lit);
     }
+
+    // Vstore is legal following expr_lit(lit_str(...)) and expr_vec(...)
+    // only.
+    alt ex {
+      ast::expr_lit(@{node: ast::lit_str(_), span: _}) |
+      ast::expr_vec(_, _)  {
+        alt parse_maybe_vstore(p) {
+          none { }
+          some(v) {
+            hi = p.span.hi;
+            ex = ast::expr_vstore(mk_expr(p, lo, hi, ex), v);
+          }
+        }
+      }
+      _ { }
+    }
+
     ret mk_pexpr(p, lo, hi, ex);
 }
 
@@ -1194,10 +1277,10 @@ type op_spec = {tok: token::token, op: ast::binop, prec: int};
 
 // FIXME make this a const, don't store it in parser state
 fn prec_table() -> @[op_spec] {
-    ret @[// 'as' sits between here with 12
-          {tok: token::BINOP(token::STAR), op: ast::mul, prec: 11},
-          {tok: token::BINOP(token::SLASH), op: ast::div, prec: 11},
-          {tok: token::BINOP(token::PERCENT), op: ast::rem, prec: 11},
+    ret @[{tok: token::BINOP(token::STAR), op: ast::mul, prec: 12},
+          {tok: token::BINOP(token::SLASH), op: ast::div, prec: 12},
+          {tok: token::BINOP(token::PERCENT), op: ast::rem, prec: 12},
+          // 'as' sits between here with 11
           {tok: token::BINOP(token::PLUS), op: ast::add, prec: 10},
           {tok: token::BINOP(token::MINUS), op: ast::subtract, prec: 10},
           {tok: token::BINOP(token::LSL), op: ast::lsl, prec: 9},
@@ -1222,7 +1305,7 @@ fn parse_binops(p: parser) -> @ast::expr {
 
 const unop_prec: int = 100;
 
-const as_prec: int = 12;
+const as_prec: int = 11;
 
 fn parse_more_binops(p: parser, plhs: pexpr, min_prec: int) ->
    @ast::expr {