diff options
| author | Patrick Walton <pcwalton@mimiga.net> | 2012-08-07 14:24:04 -0700 |
|---|---|---|
| committer | Patrick Walton <pcwalton@mimiga.net> | 2012-08-07 14:25:53 -0700 |
| commit | 727c7c74994cf54baecab8ab6b03c50ace44d634 (patch) | |
| tree | 7a3d1ae73f49614ed0163ba20a03f23451d69f00 /src/libsyntax | |
| parent | bc267c696c015525ea303e03d448d1507b6afeb6 (diff) | |
rustc: Add stub support for struct variants to the AST
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 8 | ||||
| -rw-r--r-- | src/libsyntax/ast_util.rs | 11 | ||||
| -rw-r--r-- | src/libsyntax/ext/auto_serialize.rs | 122 | ||||
| -rw-r--r-- | src/libsyntax/ext/pipes/ast_builder.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 13 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 21 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 37 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 6 |
8 files changed, 136 insertions, 84 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 577ef1464cf..87fe7fe67a9 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -632,7 +632,13 @@ type foreign_mod = type variant_arg = {ty: @ty, id: node_id}; #[auto_serialize] -type variant_ = {name: ident, attrs: ~[attribute], args: ~[variant_arg], +enum variant_kind { + tuple_variant_kind(~[variant_arg]), + struct_variant_kind +} + +#[auto_serialize] +type variant_ = {name: ident, attrs: ~[attribute], kind: variant_kind, id: node_id, disr_expr: option<@expr>, vis: visibility}; #[auto_serialize] diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index deb8bb5963d..7d7867d0516 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -187,12 +187,13 @@ fn is_exported(i: ident, m: _mod) -> bool { for m.items.each |it| { if it.ident == i { local = true; } match it.node { - item_enum(variants, _) => for variants.each |v| { - if v.node.name == i { - local = true; - parent_enum = some(/* FIXME (#2543) */ copy it.ident); + item_enum(variants, _) => + for variants.each |v| { + if v.node.name == i { + local = true; + parent_enum = some(/* FIXME (#2543) */ copy it.ident); + } } - }, _ => () } if local { break; } diff --git a/src/libsyntax/ext/auto_serialize.rs b/src/libsyntax/ext/auto_serialize.rs index 053c972d1ea..4ce017eeae9 100644 --- a/src/libsyntax/ext/auto_serialize.rs +++ b/src/libsyntax/ext/auto_serialize.rs @@ -830,43 +830,51 @@ fn ser_enum(cx: ext_ctxt, tps: ser_tps_map, e_name: ast::ident, let variant = variants[vidx]; let v_span = variant.span; let v_name = variant.node.name; - let variant_tys = vec::map(variant.node.args, |a| a.ty); - - ser_variant( - cx, tps, variant_tys, v_span, cx.clone(s), - - // Generate pattern var(v1, v2, v3) - |pats| { - if vec::is_empty(pats) { - ast::pat_ident(ast::bind_by_implicit_ref, - cx.path(v_span, ~[v_name]), - none) - } else { - ast::pat_enum(cx.path(v_span, ~[v_name]), some(pats)) - } - }, - - // Generate body s.emit_enum_variant("foo", 0u, - // 3u, {|| blk }) - |-s, blk| { - let v_name = cx.lit_str(v_span, v_name); - let v_id = cx.lit_uint(v_span, vidx); - let sz = cx.lit_uint(v_span, vec::len(variant_tys)); - let body = cx.lambda(blk); - #ast[expr]{ - $(s).emit_enum_variant($(v_name), $(v_id), - $(sz), $(body)) - } - }, - - // Generate s.emit_enum_variant_arg(i, {|| blk }) - |-s, i, blk| { - let idx = cx.lit_uint(v_span, i); - let body = cx.lambda(blk); - #ast[expr]{ - $(s).emit_enum_variant_arg($(idx), $(body)) - } - }) + + match variant.node.kind { + ast::tuple_variant_kind(args) => { + let variant_tys = vec::map(args, |a| a.ty); + + ser_variant( + cx, tps, variant_tys, v_span, cx.clone(s), + + // Generate pattern var(v1, v2, v3) + |pats| { + if vec::is_empty(pats) { + ast::pat_ident(ast::bind_by_implicit_ref, + cx.path(v_span, ~[v_name]), + none) + } else { + ast::pat_enum(cx.path(v_span, ~[v_name]), + some(pats)) + } + }, + + // Generate body s.emit_enum_variant("foo", 0u, + // 3u, {|| blk }) + |-s, blk| { + let v_name = cx.lit_str(v_span, v_name); + let v_id = cx.lit_uint(v_span, vidx); + let sz = cx.lit_uint(v_span, vec::len(variant_tys)); + let body = cx.lambda(blk); + #ast[expr]{ + $(s).emit_enum_variant($(v_name), $(v_id), + $(sz), $(body)) + } + }, + + // Generate s.emit_enum_variant_arg(i, {|| blk }) + |-s, i, blk| { + let idx = cx.lit_uint(v_span, i); + let body = cx.lambda(blk); + #ast[expr]{ + $(s).emit_enum_variant_arg($(idx), $(body)) + } + }) + } + _ => + fail ~"struct variants unimplemented for auto serialize" + } }; let lam = cx.lambda(cx.blk(e_span, ~[cx.alt_stmt(arms, e_span, v)])); let e_name = cx.lit_str(e_span, e_name); @@ -881,24 +889,32 @@ fn deser_enum(cx: ext_ctxt, tps: deser_tps_map, e_name: ast::ident, let variant = variants[vidx]; let v_span = variant.span; let v_name = variant.node.name; - let tys = vec::map(variant.node.args, |a| a.ty); - - let arg_exprs = do vec::from_fn(vec::len(tys)) |i| { - let idx = cx.lit_uint(v_span, i); - let body = deser_lambda(cx, tps, tys[i], cx.clone(d)); - #ast{ $(d).read_enum_variant_arg($(idx), $(body)) } - }; - let body = { - if vec::is_empty(tys) { - // for a nullary variant v, do "v" - cx.var_ref(v_span, v_name) - } else { - // for an n-ary variant v, do "v(a_1, ..., a_n)" - cx.expr(v_span, ast::expr_call( - cx.var_ref(v_span, v_name), arg_exprs, false)) + let body; + match variant.node.kind { + ast::tuple_variant_kind(args) => { + let tys = vec::map(args, |a| a.ty); + + let arg_exprs = do vec::from_fn(vec::len(tys)) |i| { + let idx = cx.lit_uint(v_span, i); + let body = deser_lambda(cx, tps, tys[i], cx.clone(d)); + #ast{ $(d).read_enum_variant_arg($(idx), $(body)) } + }; + + body = { + if vec::is_empty(tys) { + // for a nullary variant v, do "v" + cx.var_ref(v_span, v_name) + } else { + // for an n-ary variant v, do "v(a_1, ..., a_n)" + cx.expr(v_span, ast::expr_call( + cx.var_ref(v_span, v_name), arg_exprs, false)) + } + }; } - }; + ast::struct_variant_kind => + fail ~"struct variants unimplemented" + } {pats: ~[@{id: cx.next_id(), node: ast::pat_lit(cx.lit_uint(v_span, vidx)), diff --git a/src/libsyntax/ext/pipes/ast_builder.rs b/src/libsyntax/ext/pipes/ast_builder.rs index b8c37f84452..06a22b63fe0 100644 --- a/src/libsyntax/ext/pipes/ast_builder.rs +++ b/src/libsyntax/ext/pipes/ast_builder.rs @@ -254,7 +254,7 @@ impl ast_builder of ext_ctxt_ast_builder for ext_ctxt { {node: {name: name, attrs: ~[], - args: args, + kind: ast::tuple_variant_kind(args), id: self.next_id(), disr_expr: none, vis: ast::public}, diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index ab39bf53f6a..0ceee7f7d97 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -541,7 +541,15 @@ fn noop_fold_variant(v: variant_, fld: ast_fold) -> variant_ { return {ty: fld.fold_ty(va.ty), id: fld.new_id(va.id)}; } let fold_variant_arg = |x| fold_variant_arg_(x, fld); - let args = vec::map(v.args, fold_variant_arg); + + let kind; + match v.kind { + tuple_variant_kind(variant_args) => + kind = tuple_variant_kind(vec::map(variant_args, + fold_variant_arg)), + struct_variant_kind => + kind = struct_variant_kind + } let fold_attribute = |x| fold_attribute_(x, fld); let attrs = vec::map(v.attrs, fold_attribute); @@ -552,7 +560,8 @@ fn noop_fold_variant(v: variant_, fld: ast_fold) -> variant_ { }; return {name: /* FIXME (#2543) */ copy v.name, attrs: attrs, - args: args, id: fld.new_id(v.id), + kind: kind, + id: fld.new_id(v.id), disr_expr: de, vis: v.vis}; } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 993419bd9c4..5feb753657d 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -49,14 +49,14 @@ import ast::{_mod, add, alt_check, alt_exhaustive, arg, arm, attribute, return_val, self_ty, shl, shr, stmt, stmt_decl, stmt_expr, stmt_semi, subtract, sty_box, sty_by_ref, sty_region, sty_uniq, sty_value, token_tree, trait_method, trait_ref, tt_delim, tt_seq, - tt_tok, tt_nonterminal, ty, ty_, ty_bot, ty_box, ty_field, ty_fn, - ty_infer, ty_mac, ty_method, ty_nil, ty_param, ty_param_bound, - ty_path, ty_ptr, ty_rec, ty_rptr, ty_tup, ty_u32, ty_uniq, - ty_vec, ty_fixed_length, unchecked_blk, uniq, unsafe_blk, - unsafe_fn, variant, view_item, view_item_, view_item_export, - view_item_import, view_item_use, view_path, view_path_glob, - view_path_list, view_path_simple, visibility, vstore, vstore_box, - vstore_fixed, vstore_slice, vstore_uniq}; + tt_tok, tt_nonterminal, tuple_variant_kind, ty, ty_, ty_bot, + ty_box, ty_field, ty_fn, ty_infer, ty_mac, ty_method, ty_nil, + ty_param, ty_param_bound, ty_path, ty_ptr, ty_rec, ty_rptr, + ty_tup, ty_u32, ty_uniq, ty_vec, ty_fixed_length, unchecked_blk, + uniq, unsafe_blk, unsafe_fn, variant, view_item, view_item_, + view_item_export, view_item_import, view_item_use, view_path, + view_path_glob, view_path_list, view_path_simple, visibility, + vstore, vstore_box, vstore_fixed, vstore_slice, vstore_uniq}; export file_type; export parser; @@ -2830,7 +2830,8 @@ class parser { spanned(ty.span.lo, ty.span.hi, {name: id, attrs: ~[], - args: ~[{ty: ty, id: self.get_id()}], + kind: tuple_variant_kind + (~[{ty: ty, id: self.get_id()}]), id: self.get_id(), disr_expr: none, vis: public}); @@ -2861,7 +2862,7 @@ class parser { } let vr = {name: ident, attrs: variant_attrs, - args: args, id: self.get_id(), + kind: tuple_variant_kind(args), id: self.get_id(), disr_expr: disr_expr, vis: vis}; vec::push(variants, spanned(vlo, self.last_span.hi, vr)); diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 41b61f57f92..d3eef85f062 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -488,21 +488,31 @@ fn print_item(s: ps, &&item: @ast::item) { end(s); // end the outer ibox } ast::item_enum(variants, params) => { - let newtype = + let mut newtype = vec::len(variants) == 1u && - str::eq(item.ident, variants[0].node.name) && - vec::len(variants[0].node.args) == 1u; + str::eq(item.ident, variants[0].node.name); + if newtype { + match variants[0].node.kind { + ast::tuple_variant_kind(args) if args.len() == 1 => {} + _ => newtype = false + } + } if newtype { ibox(s, indent_unit); word_space(s, ~"enum"); - } else { head(s, ~"enum"); } + } else { + head(s, ~"enum"); + } word(s.s, *item.ident); print_type_params(s, params); space(s.s); if newtype { word_space(s, ~"="); - print_type(s, variants[0].node.args[0].ty); + match variants[0].node.kind { + ast::tuple_variant_kind(args) => print_type(s, args[0].ty), + _ => fail ~"newtype syntax with struct?" + } word(s.s, ~";"); end(s); } else { @@ -680,13 +690,18 @@ fn print_tt(s: ps, tt: ast::token_tree) { fn print_variant(s: ps, v: ast::variant) { word(s.s, *v.node.name); - if vec::len(v.node.args) > 0u { - popen(s); - fn print_variant_arg(s: ps, arg: ast::variant_arg) { - print_type(s, arg.ty); + match v.node.kind { + ast::tuple_variant_kind(args) => { + if vec::len(args) > 0u { + popen(s); + fn print_variant_arg(s: ps, arg: ast::variant_arg) { + print_type(s, arg.ty); + } + commasep(s, consistent, args, print_variant_arg); + pclose(s); + } } - commasep(s, consistent, v.node.args, print_variant_arg); - pclose(s); + ast::struct_variant_kind => {} } match v.node.disr_expr { some(d) => { diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 830114b47ad..3bf820dd5cf 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -135,7 +135,11 @@ fn visit_item<E>(i: @item, e: E, v: vt<E>) { item_enum(variants, tps) => { v.visit_ty_params(tps, e, v); for variants.each |vr| { - for vr.node.args.each |va| { v.visit_ty(va.ty, e, v); } + match vr.node.kind { + tuple_variant_kind(variant_args) => + for variant_args.each |va| { v.visit_ty(va.ty, e, v); }, + struct_variant_kind => {} + } } } item_impl(tps, traits, ty, methods) => { |
