summary refs log tree commit diff
path: root/src/comp/syntax
diff options
context:
space:
mode:
authorMarijn Haverbeke <marijnh@gmail.com>2011-07-28 12:01:45 +0200
committerMarijn Haverbeke <marijnh@gmail.com>2011-08-01 17:51:37 +0200
commit985c32ef4c930cdfba23db2191014d772c354407 (patch)
treef9cfb1ad055221eb63cfd22e49cbe18d59dcf520 /src/comp/syntax
parent48ec25da423cd6535e6354a00fa6c98f3f2b4065 (diff)
downloadrust-985c32ef4c930cdfba23db2191014d772c354407.tar.gz
rust-985c32ef4c930cdfba23db2191014d772c354407.zip
Partially implement destructuring locals
You can now say

    let {bcx, val} = some_result_returner();

Similar for loop variables. Assigning to such variables is not safe
yet. Function arguments also remain a TODO.
Diffstat (limited to 'src/comp/syntax')
-rw-r--r--src/comp/syntax/ast.rs32
-rw-r--r--src/comp/syntax/fold.rs18
-rw-r--r--src/comp/syntax/parse/parser.rs10
-rw-r--r--src/comp/syntax/print/pprust.rs11
-rw-r--r--src/comp/syntax/visit.rs1
5 files changed, 43 insertions, 29 deletions
diff --git a/src/comp/syntax/ast.rs b/src/comp/syntax/ast.rs
index fc2d64ddb49..5dfe6ba7463 100644
--- a/src/comp/syntax/ast.rs
+++ b/src/comp/syntax/ast.rs
@@ -142,7 +142,7 @@ fn pat_id_map(pat: &@pat) -> pat_id_map {
     fn walk(map: &pat_id_map, pat: &@pat) {
         alt pat.node {
           pat_bind(name) { map.insert(name, pat.id); }
-          pat_tag(_, sub) { for p: @pat  in sub { walk(map, p); } }
+          pat_tag(_, sub) { for p: @pat in sub { walk(map, p); } }
           pat_rec(fields, _) {
             for f: field_pat  in fields { walk(map, f.pat); }
           }
@@ -154,6 +154,26 @@ fn pat_id_map(pat: &@pat) -> pat_id_map {
     ret map;
 }
 
+// FIXME This wanted to be an iter, but bug #791 got in the way.
+fn pat_bindings(pat: &@pat) -> (@pat)[] {
+    let found = ~[];
+    fn recur(found: &mutable (@pat)[], pat: &@pat) {
+        alt pat.node {
+          pat_bind(_) { found += ~[pat]; }
+          pat_tag(_, sub) {
+            for p in sub { recur(found, p); }
+          }
+          pat_rec(fields, _) {
+            for f: field_pat in fields { recur(found, f.pat); }
+          }
+          pat_box(sub) { recur(found, sub); }
+          pat_wild. | pat_lit(_) {}
+        }
+    }
+    recur(found, pat);
+    ret found;
+}
+
 tag mutability { mut; imm; maybe_mut; }
 
 tag kind { kind_pinned; kind_shared; kind_unique; }
@@ -240,12 +260,10 @@ tag init_op { init_assign; init_recv; init_move; }
 
 type initializer = {op: init_op, expr: @expr};
 
-type local_ =
-    {ty: option::t[@ty],
-     infer: bool,
-     ident: ident,
-     init: option::t[initializer],
-     id: node_id};
+type local_ = {ty: option::t[@ty],
+               pat: @pat,
+               init: option::t[initializer],
+               id: node_id};
 
 type local = spanned[local_];
 
diff --git a/src/comp/syntax/fold.rs b/src/comp/syntax/fold.rs
index fee5b03174d..e2bb0380c04 100644
--- a/src/comp/syntax/fold.rs
+++ b/src/comp/syntax/fold.rs
@@ -486,16 +486,14 @@ fn noop_fold_path(p: &path_, fld: ast_fold) -> path_ {
 
 fn noop_fold_local(l: &local_, fld: ast_fold) -> local_ {
     ret {ty: option::map(fld.fold_ty, l.ty),
-         infer: l.infer,
-         ident: fld.fold_ident(l.ident),
-         init:
-             alt l.init {
-               option::none[initializer]. { l.init }
-               option::some[initializer](init) {
-                 option::some[initializer]({op: init.op,
-                                            expr: fld.fold_expr(init.expr)})
-               }
-             },
+         pat: fld.fold_pat(l.pat),
+         init: alt l.init {
+           option::none[initializer]. { l.init }
+           option::some[initializer](init) {
+             option::some[initializer]({op: init.op,
+                                        expr: fld.fold_expr(init.expr)})
+           }
+         },
          id: l.id};
 }
 
diff --git a/src/comp/syntax/parse/parser.rs b/src/comp/syntax/parse/parser.rs
index 3fba6f614f0..9c929390bd2 100644
--- a/src/comp/syntax/parse/parser.rs
+++ b/src/comp/syntax/parse/parser.rs
@@ -1337,9 +1337,6 @@ fn parse_alt_expr(p: &parser) -> @ast::expr {
     expect(p, token::LBRACE);
     let arms: ast::arm[] = ~[];
     while p.peek() != token::RBRACE {
-        // Optionally eat the case keyword.
-        // FIXME remove this (and the optional parens) once we've updated our
-        // code to not use the old syntax
         let pats = parse_pats(p);
         let blk = parse_block(p);
         arms += ~[{pats: pats, block: blk}];
@@ -1472,7 +1469,7 @@ fn parse_pat(p: &parser) -> @ast::pat {
                          _ { true }
                        }) {
             hi = p.get_hi_pos();
-            pat = ast::pat_bind(parse_ident(p));
+            pat = ast::pat_bind(parse_value_ident(p));
         } else {
             let tag_path = parse_path_and_ty_param_substs(p);
             hi = tag_path.span.hi;
@@ -1497,14 +1494,13 @@ fn parse_pat(p: &parser) -> @ast::pat {
 
 fn parse_local(p: &parser, allow_init: bool) -> @ast::local {
     let lo = p.get_lo_pos();
-    let ident = parse_value_ident(p);
+    let pat = parse_pat(p);
     let ty = none;
     if eat(p, token::COLON) { ty = some(parse_ty(p)); }
     let init = if allow_init { parse_initializer(p) } else { none };
     ret @spanned(lo, p.get_last_hi_pos(),
                  {ty: ty,
-                  infer: false,
-                  ident: ident,
+                  pat: pat,
                   init: init,
                   id: p.get_id()});
 }
diff --git a/src/comp/syntax/print/pprust.rs b/src/comp/syntax/print/pprust.rs
index bf5460452b4..7533eced7cf 100644
--- a/src/comp/syntax/print/pprust.rs
+++ b/src/comp/syntax/print/pprust.rs
@@ -1002,15 +1002,16 @@ fn print_decl(s: &ps, decl: &@ast::decl) {
         ibox(s, indent_unit);
         word_nbsp(s, "let");
         fn print_local(s: &ps, loc: &@ast::local) {
+            ibox(s, indent_unit);
+            print_pat(s, loc.node.pat);
             alt loc.node.ty {
               some(ty) {
-                ibox(s, indent_unit);
-                word_space(s, loc.node.ident + ":");
+                word_space(s, ":");
                 print_type(s, *ty);
-                end(s);
               }
-              _ { word(s.s, loc.node.ident); }
+              _ { }
             }
+            end(s);
             alt loc.node.init {
               some(init) {
                 nbsp(s);
@@ -1034,7 +1035,7 @@ fn print_decl(s: &ps, decl: &@ast::decl) {
 fn print_ident(s: &ps, ident: &ast::ident) { word(s.s, ident); }
 
 fn print_for_decl(s: &ps, loc: &@ast::local, coll: &@ast::expr) {
-    word(s.s, loc.node.ident);
+    print_pat(s, loc.node.pat);
     alt loc.node.ty {
       some(t) { word_space(s, ":"); print_type(s, *t); }
       none. { }
diff --git a/src/comp/syntax/visit.rs b/src/comp/syntax/visit.rs
index 3c2eb231647..673fa46d466 100644
--- a/src/comp/syntax/visit.rs
+++ b/src/comp/syntax/visit.rs
@@ -78,6 +78,7 @@ fn visit_mod[E](m: &_mod, sp: &span, e: &E, v: &vt[E]) {
 fn visit_view_item[E](vi: &@view_item, e: &E, v: &vt[E]) { }
 
 fn visit_local[E](loc: &@local, e: &E, v: &vt[E]) {
+    v.visit_pat(loc.node.pat, e, v);
     alt loc.node.ty { none. { } some(t) { v.visit_ty(t, e, v); } }
     alt loc.node.init { none. { } some(i) { v.visit_expr(i.expr, e, v); } }
 }