diff options
| author | Marijn Haverbeke <marijnh@gmail.com> | 2011-07-28 12:01:45 +0200 |
|---|---|---|
| committer | Marijn Haverbeke <marijnh@gmail.com> | 2011-08-01 17:51:37 +0200 |
| commit | 985c32ef4c930cdfba23db2191014d772c354407 (patch) | |
| tree | f9cfb1ad055221eb63cfd22e49cbe18d59dcf520 /src/comp/syntax | |
| parent | 48ec25da423cd6535e6354a00fa6c98f3f2b4065 (diff) | |
| download | rust-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.rs | 32 | ||||
| -rw-r--r-- | src/comp/syntax/fold.rs | 18 | ||||
| -rw-r--r-- | src/comp/syntax/parse/parser.rs | 10 | ||||
| -rw-r--r-- | src/comp/syntax/print/pprust.rs | 11 | ||||
| -rw-r--r-- | src/comp/syntax/visit.rs | 1 |
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); } } } |
