diff options
Diffstat (limited to 'src/librustsyntax/print/pprust.rs')
| -rw-r--r-- | src/librustsyntax/print/pprust.rs | 1861 |
1 files changed, 0 insertions, 1861 deletions
diff --git a/src/librustsyntax/print/pprust.rs b/src/librustsyntax/print/pprust.rs deleted file mode 100644 index 8206bfd2a4a..00000000000 --- a/src/librustsyntax/print/pprust.rs +++ /dev/null @@ -1,1861 +0,0 @@ -import parse::classify::*; -import parse::comments; -import parse::lexer; -import codemap::codemap; -import pp::{break_offset, word, printer, - space, zerobreak, hardbreak, breaks, consistent, - inconsistent, eof}; -import diagnostic; -import ast_util::operator_prec; -import dvec::{dvec, extensions}; - -// The ps is stored here to prevent recursive type. -enum ann_node { - node_block(ps, ast::blk), - node_item(ps, @ast::item), - node_expr(ps, @ast::expr), - node_pat(ps, @ast::pat), -} -type pp_ann = {pre: fn@(ann_node), post: fn@(ann_node)}; - -fn no_ann() -> pp_ann { - fn ignore(_node: ann_node) { } - ret {pre: ignore, post: ignore}; -} - -type ps = - @{s: pp::printer, - cm: option<codemap>, - comments: option<[comments::cmnt]>, - literals: option<[comments::lit]>, - mut cur_cmnt: uint, - mut cur_lit: uint, - boxes: dvec<pp::breaks>, - ann: pp_ann}; - -fn ibox(s: ps, u: uint) { - s.boxes.push(pp::inconsistent); - pp::ibox(s.s, u); -} - -fn end(s: ps) { - s.boxes.pop(); - pp::end(s.s); -} - -fn rust_printer(writer: io::writer) -> ps { - ret @{s: pp::mk_printer(writer, default_columns), - cm: none::<codemap>, - comments: none::<[comments::cmnt]>, - literals: none::<[comments::lit]>, - mut cur_cmnt: 0u, - mut cur_lit: 0u, - boxes: dvec(), - ann: no_ann()}; -} - -const indent_unit: uint = 4u; -const alt_indent_unit: uint = 2u; - -const default_columns: uint = 78u; - -// Requires you to pass an input filename and reader so that -// it can scan the input text for comments and literals to -// copy forward. -fn print_crate(cm: codemap, span_diagnostic: diagnostic::span_handler, - crate: @ast::crate, filename: str, in: io::reader, - out: io::writer, ann: pp_ann) { - let r = comments::gather_comments_and_literals(span_diagnostic, - filename, in); - let s = - @{s: pp::mk_printer(out, default_columns), - cm: some(cm), - comments: some(r.cmnts), - literals: some(r.lits), - mut cur_cmnt: 0u, - mut cur_lit: 0u, - boxes: dvec(), - ann: ann}; - print_crate_(s, crate); -} - -fn print_crate_(s: ps, &&crate: @ast::crate) { - print_mod(s, crate.node.module, crate.node.attrs); - print_remaining_comments(s); - eof(s.s); -} - -fn ty_to_str(ty: @ast::ty) -> str { ret to_str(ty, print_type); } - -fn pat_to_str(pat: @ast::pat) -> str { ret to_str(pat, print_pat); } - -fn expr_to_str(e: @ast::expr) -> str { ret to_str(e, print_expr); } - -fn stmt_to_str(s: ast::stmt) -> str { ret to_str(s, print_stmt); } - -fn item_to_str(i: @ast::item) -> str { ret to_str(i, print_item); } - -fn attr_to_str(i: ast::attribute) -> str { ret to_str(i, print_attribute); } - -fn typarams_to_str(tps: [ast::ty_param]) -> str { - ret to_str(tps, print_type_params) -} - -fn path_to_str(&&p: @ast::path) -> str { - ret to_str(p, bind print_path(_, _, false)); -} - -fn fun_to_str(decl: ast::fn_decl, name: ast::ident, - params: [ast::ty_param]) -> str { - let buffer = io::mem_buffer(); - let s = rust_printer(io::mem_buffer_writer(buffer)); - print_fn(s, decl, name, params); - end(s); // Close the head box - end(s); // Close the outer box - eof(s.s); - io::mem_buffer_str(buffer) -} - -#[test] -fn test_fun_to_str() { - let decl: ast::fn_decl = { - inputs: [], - output: @{id: 0, - node: ast::ty_nil, - span: ast_util::dummy_sp()}, - purity: ast::impure_fn, - cf: ast::return_val, - constraints: [] - }; - assert fun_to_str(decl, "a", []) == "fn a()"; -} - -fn res_to_str(decl: ast::fn_decl, name: ast::ident, - params: [ast::ty_param], rp: ast::region_param) -> str { - let buffer = io::mem_buffer(); - let s = rust_printer(io::mem_buffer_writer(buffer)); - print_res(s, decl, name, params, rp); - end(s); // Close the head box - end(s); // Close the outer box - eof(s.s); - io::mem_buffer_str(buffer) -} - -#[test] -fn test_res_to_str() { - let decl: ast::fn_decl = { - inputs: [{ - mode: ast::expl(ast::by_val), - ty: @{id: 0, - node: ast::ty_nil, - span: ast_util::dummy_sp()}, - ident: "b", - id: 0 - }], - output: @{id: 0, - node: ast::ty_nil, - span: ast_util::dummy_sp()}, - purity: ast::impure_fn, - cf: ast::return_val, - constraints: [] - }; - assert res_to_str(decl, "a", []) == "resource a(b: ())"; -} - -fn block_to_str(blk: ast::blk) -> str { - let buffer = io::mem_buffer(); - let s = rust_printer(io::mem_buffer_writer(buffer)); - // containing cbox, will be closed by print-block at } - cbox(s, indent_unit); - // head-ibox, will be closed by print-block after { - ibox(s, 0u); - print_block(s, blk); - eof(s.s); - io::mem_buffer_str(buffer) -} - -fn meta_item_to_str(mi: ast::meta_item) -> str { - ret to_str(@mi, print_meta_item); -} - -fn attribute_to_str(attr: ast::attribute) -> str { - ret to_str(attr, print_attribute); -} - -fn variant_to_str(var: ast::variant) -> str { - ret to_str(var, print_variant); -} - -#[test] -fn test_variant_to_str() { - let var = ast_util::respan(ast_util::dummy_sp(), { - name: "principle_skinner", - attrs: [], - args: [], - id: 0, - disr_expr: none - }); - - let varstr = variant_to_str(var); - assert varstr == "principle_skinner"; -} - -fn cbox(s: ps, u: uint) { - s.boxes.push(pp::consistent); - pp::cbox(s.s, u); -} - -fn box(s: ps, u: uint, b: pp::breaks) { - s.boxes.push(b); - pp::box(s.s, u, b); -} - -fn nbsp(s: ps) { word(s.s, " "); } - -fn word_nbsp(s: ps, w: str) { word(s.s, w); nbsp(s); } - -fn word_space(s: ps, w: str) { word(s.s, w); space(s.s); } - -fn popen(s: ps) { word(s.s, "("); } - -fn pclose(s: ps) { word(s.s, ")"); } - -fn head(s: ps, w: str) { - // outer-box is consistent - cbox(s, indent_unit); - // head-box is inconsistent - ibox(s, str::len(w) + 1u); - // keyword that starts the head - word_nbsp(s, w); -} - -fn bopen(s: ps) { - word(s.s, "{"); - end(s); // close the head-box -} - -fn bclose_(s: ps, span: codemap::span, indented: uint) { - maybe_print_comment(s, span.hi); - break_offset_if_not_bol(s, 1u, -(indented as int)); - word(s.s, "}"); - end(s); // close the outer-box -} -fn bclose(s: ps, span: codemap::span) { bclose_(s, span, indent_unit); } - -fn is_begin(s: ps) -> bool { - alt s.s.last_token() { pp::BEGIN(_) { true } _ { false } } -} - -fn is_end(s: ps) -> bool { - alt s.s.last_token() { pp::END { true } _ { false } } -} - -fn is_bol(s: ps) -> bool { - ret s.s.last_token() == pp::EOF || - s.s.last_token() == pp::hardbreak_tok(); -} - -fn in_cbox(s: ps) -> bool { - let len = s.boxes.len(); - if len == 0u { ret false; } - ret s.boxes[len - 1u] == pp::consistent; -} - -fn hardbreak_if_not_bol(s: ps) { if !is_bol(s) { hardbreak(s.s); } } -fn space_if_not_bol(s: ps) { if !is_bol(s) { space(s.s); } } -fn break_offset_if_not_bol(s: ps, n: uint, off: int) { - if !is_bol(s) { - break_offset(s.s, n, off); - } else { - if off != 0 && s.s.last_token() == pp::hardbreak_tok() { - // We do something pretty sketchy here: tuck the nonzero - // offset-adjustment we were going to deposit along with the - // break into the previous hardbreak. - s.s.replace_last_token(pp::hardbreak_tok_offset(off)); - } - } -} - -// Synthesizes a comment that was not textually present in the original source -// file. -fn synth_comment(s: ps, text: str) { - word(s.s, "/*"); - space(s.s); - word(s.s, text); - space(s.s); - word(s.s, "*/"); -} - -fn commasep<IN>(s: ps, b: breaks, elts: [IN], op: fn(ps, IN)) { - box(s, 0u, b); - let mut first = true; - for elts.each {|elt| - if first { first = false; } else { word_space(s, ","); } - op(s, elt); - } - end(s); -} - - -fn commasep_cmnt<IN>(s: ps, b: breaks, elts: [IN], op: fn(ps, IN), - get_span: fn(IN) -> codemap::span) { - box(s, 0u, b); - let len = vec::len::<IN>(elts); - let mut i = 0u; - for elts.each {|elt| - maybe_print_comment(s, get_span(elt).hi); - op(s, elt); - i += 1u; - if i < len { - word(s.s, ","); - maybe_print_trailing_comment(s, get_span(elt), - some(get_span(elts[i]).hi)); - space_if_not_bol(s); - } - } - end(s); -} - -fn commasep_exprs(s: ps, b: breaks, exprs: [@ast::expr]) { - fn expr_span(&&expr: @ast::expr) -> codemap::span { ret expr.span; } - commasep_cmnt(s, b, exprs, print_expr, expr_span); -} - -fn print_mod(s: ps, _mod: ast::_mod, attrs: [ast::attribute]) { - print_inner_attributes(s, attrs); - for _mod.view_items.each {|vitem| - print_view_item(s, vitem); - } - for _mod.items.each {|item| print_item(s, item); } -} - -fn print_native_mod(s: ps, nmod: ast::native_mod, attrs: [ast::attribute]) { - print_inner_attributes(s, attrs); - for nmod.view_items.each {|vitem| - print_view_item(s, vitem); - } - for nmod.items.each {|item| print_native_item(s, item); } -} - -fn print_region(s: ps, region: @ast::region) { - alt region.node { - ast::re_anon { word_space(s, "&"); } - ast::re_named(name) { - word(s.s, "&"); - word_space(s, name); - } - } -} - -fn print_type(s: ps, &&ty: @ast::ty) { - print_type_ex(s, ty, false); -} - -fn print_type_ex(s: ps, &&ty: @ast::ty, print_colons: bool) { - maybe_print_comment(s, ty.span.lo); - ibox(s, 0u); - alt ty.node { - ast::ty_nil { word(s.s, "()"); } - ast::ty_bot { word(s.s, "!"); } - ast::ty_box(mt) { word(s.s, "@"); print_mt(s, mt); } - ast::ty_uniq(mt) { word(s.s, "~"); print_mt(s, mt); } - ast::ty_vec(mt) { - word(s.s, "["); - alt mt.mutbl { - ast::m_mutbl { word_space(s, "mut"); } - ast::m_const { word_space(s, "const"); } - ast::m_imm { } - } - print_type(s, mt.ty); - word(s.s, "]"); - } - ast::ty_ptr(mt) { word(s.s, "*"); print_mt(s, mt); } - ast::ty_rptr(region, mt) { - alt region.node { - ast::re_anon { word(s.s, "&"); } - _ { print_region(s, region); word(s.s, "."); } - } - print_mt(s, mt); - } - ast::ty_rec(fields) { - word(s.s, "{"); - fn print_field(s: ps, f: ast::ty_field) { - cbox(s, indent_unit); - print_mutability(s, f.node.mt.mutbl); - word(s.s, f.node.ident); - word_space(s, ":"); - print_type(s, f.node.mt.ty); - end(s); - } - fn get_span(f: ast::ty_field) -> codemap::span { ret f.span; } - commasep_cmnt(s, consistent, fields, print_field, get_span); - word(s.s, ",}"); - } - ast::ty_tup(elts) { - popen(s); - commasep(s, inconsistent, elts, print_type); - pclose(s); - } - ast::ty_fn(proto, d) { - print_ty_fn(s, some(proto), d, none, none); - } - ast::ty_path(path, _) { print_path(s, path, print_colons); } - ast::ty_constr(t, cs) { - print_type(s, t); - space(s.s); - word(s.s, constrs_str(cs, ty_constr_to_str)); - } - ast::ty_vstore(t, v) { - print_type(s, t); - print_vstore(s, v); - } - ast::ty_mac(_) { - fail "print_type doesn't know how to print a ty_mac"; - } - ast::ty_infer { - fail "print_type shouldn't see a ty_infer"; - } - - } - end(s); -} - -fn print_native_item(s: ps, item: @ast::native_item) { - hardbreak_if_not_bol(s); - maybe_print_comment(s, item.span.lo); - print_outer_attributes(s, item.attrs); - alt item.node { - ast::native_item_fn(decl, typarams) { - print_fn(s, decl, item.ident, typarams); - end(s); // end head-ibox - word(s.s, ";"); - end(s); // end the outer fn box - } - } -} - -fn print_item(s: ps, &&item: @ast::item) { - hardbreak_if_not_bol(s); - maybe_print_comment(s, item.span.lo); - print_outer_attributes(s, item.attrs); - let ann_node = node_item(s, item); - s.ann.pre(ann_node); - alt item.node { - ast::item_const(ty, expr) { - head(s, "const"); - word_space(s, item.ident + ":"); - print_type(s, ty); - space(s.s); - end(s); // end the head-ibox - - word_space(s, "="); - print_expr(s, expr); - word(s.s, ";"); - end(s); // end the outer cbox - - } - ast::item_fn(decl, typarams, body) { - print_fn(s, decl, item.ident, typarams); - word(s.s, " "); - print_block_with_attrs(s, body, item.attrs); - } - ast::item_mod(_mod) { - head(s, "mod"); - word_nbsp(s, item.ident); - bopen(s); - print_mod(s, _mod, item.attrs); - bclose(s, item.span); - } - ast::item_native_mod(nmod) { - head(s, "native"); - word_nbsp(s, "mod"); - word_nbsp(s, item.ident); - bopen(s); - print_native_mod(s, nmod, item.attrs); - bclose(s, item.span); - } - ast::item_ty(ty, params, rp) { - ibox(s, indent_unit); - ibox(s, 0u); - word_nbsp(s, "type"); - word(s.s, item.ident); - print_region_param(s, rp); - print_type_params(s, params); - end(s); // end the inner ibox - - space(s.s); - word_space(s, "="); - print_type(s, ty); - word(s.s, ";"); - end(s); // end the outer ibox - } - ast::item_enum(variants, params, rp) { - let newtype = - vec::len(variants) == 1u && - str::eq(item.ident, variants[0].node.name) && - vec::len(variants[0].node.args) == 1u; - if newtype { - ibox(s, indent_unit); - word_space(s, "enum"); - } else { head(s, "enum"); } - word(s.s, item.ident); - print_region_param(s, rp); - print_type_params(s, params); - space(s.s); - if newtype { - word_space(s, "="); - print_type(s, variants[0].node.args[0].ty); - word(s.s, ";"); - end(s); - } else { - bopen(s); - for variants.each {|v| - space_if_not_bol(s); - maybe_print_comment(s, v.span.lo); - print_outer_attributes(s, v.node.attrs); - ibox(s, indent_unit); - print_variant(s, v); - word(s.s, ","); - end(s); - maybe_print_trailing_comment(s, v.span, none::<uint>); - } - bclose(s, item.span); - } - } - ast::item_class(tps, ifaces, items, ctor, m_dtor, rp) { - head(s, "class"); - word_nbsp(s, item.ident); - print_region_param(s, rp); - print_type_params(s, tps); - word_space(s, "implements"); - commasep(s, inconsistent, ifaces, {|s, p| - print_path(s, p.path, false)}); - bopen(s); - hardbreak_if_not_bol(s); - maybe_print_comment(s, ctor.span.lo); - head(s, "new"); - print_fn_args_and_ret(s, ctor.node.dec, []); - space(s.s); - print_block(s, ctor.node.body); - option::iter(m_dtor) {|dtor| - hardbreak_if_not_bol(s); - head(s, "drop"); - print_block(s, dtor.node.body); - } - for items.each {|ci| - /* - FIXME: collect all private items and print them - in a single "priv" section - - tjc: I'm not going to fix this yet b/c we might - change how exports work, including for class items - (see #1893) - */ - hardbreak_if_not_bol(s); - maybe_print_comment(s, ci.span.lo); - let pr = ast_util::class_member_visibility(ci); - alt pr { - ast::private { - head(s, "priv"); - bopen(s); - hardbreak_if_not_bol(s); - } - _ {} - } - alt ci.node { - ast::instance_var(nm, t, mt, _,_) { - word_nbsp(s, "let"); - alt mt { - ast::class_mutable { word_nbsp(s, "mut"); } - _ {} - } - word(s.s, nm); - word_nbsp(s, ":"); - print_type(s, t); - word(s.s, ";"); - } - ast::class_method(m) { - print_method(s, m); - } - } - alt pr { - ast::private { bclose(s, ci.span); } - _ {} - } - } - bclose(s, item.span); - } - ast::item_impl(tps, rp, ifce, ty, methods) { - head(s, "impl"); - word(s.s, item.ident); - print_region_param(s, rp); - print_type_params(s, tps); - space(s.s); - option::iter(ifce, {|p| - word_nbsp(s, "of"); - print_path(s, p.path, false); - space(s.s); - }); - word_nbsp(s, "for"); - print_type(s, ty); - space(s.s); - bopen(s); - for methods.each {|meth| - print_method(s, meth); - } - bclose(s, item.span); - } - ast::item_iface(tps, rp, methods) { - head(s, "iface"); - word(s.s, item.ident); - print_region_param(s, rp); - print_type_params(s, tps); - word(s.s, " "); - bopen(s); - for methods.each {|meth| print_ty_method(s, meth); } - bclose(s, item.span); - } - ast::item_res(decl, tps, body, dt_id, ct_id, rp) { - print_res(s, decl, item.ident, tps, rp); - print_block(s, body); - } - } - s.ann.post(ann_node); -} - -fn print_res(s: ps, decl: ast::fn_decl, name: ast::ident, - typarams: [ast::ty_param], rp: ast::region_param) { - head(s, "resource"); - word(s.s, name); - print_region_param(s, rp); - print_type_params(s, typarams); - popen(s); - word_space(s, decl.inputs[0].ident + ":"); - print_type(s, decl.inputs[0].ty); - pclose(s); - space(s.s); -} - -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); - } - commasep(s, consistent, v.node.args, print_variant_arg); - pclose(s); - } - alt v.node.disr_expr { - some(d) { - space(s.s); - word_space(s, "="); - print_expr(s, d); - } - _ {} - } -} - -fn print_ty_method(s: ps, m: ast::ty_method) { - hardbreak_if_not_bol(s); - maybe_print_comment(s, m.span.lo); - print_outer_attributes(s, m.attrs); - print_ty_fn(s, none, m.decl, some(m.ident), some(m.tps)); - word(s.s, ";"); -} - -fn print_method(s: ps, meth: @ast::method) { - hardbreak_if_not_bol(s); - maybe_print_comment(s, meth.span.lo); - print_outer_attributes(s, meth.attrs); - print_fn(s, meth.decl, meth.ident, meth.tps); - word(s.s, " "); - print_block_with_attrs(s, meth.body, meth.attrs); -} - -fn print_outer_attributes(s: ps, attrs: [ast::attribute]) { - let mut count = 0; - for attrs.each {|attr| - alt attr.node.style { - ast::attr_outer { print_attribute(s, attr); count += 1; } - _ {/* fallthrough */ } - } - } - if count > 0 { hardbreak_if_not_bol(s); } -} - -fn print_inner_attributes(s: ps, attrs: [ast::attribute]) { - let mut count = 0; - for attrs.each {|attr| - alt attr.node.style { - ast::attr_inner { - print_attribute(s, attr); - word(s.s, ";"); - count += 1; - } - _ {/* fallthrough */ } - } - } - if count > 0 { hardbreak_if_not_bol(s); } -} - -fn print_attribute(s: ps, attr: ast::attribute) { - hardbreak_if_not_bol(s); - maybe_print_comment(s, attr.span.lo); - word(s.s, "#["); - print_meta_item(s, @attr.node.value); - word(s.s, "]"); -} - - -fn print_stmt(s: ps, st: ast::stmt) { - maybe_print_comment(s, st.span.lo); - alt st.node { - ast::stmt_decl(decl, _) { - print_decl(s, decl); - } - ast::stmt_expr(expr, _) { - space_if_not_bol(s); - print_expr(s, expr); - } - ast::stmt_semi(expr, _) { - space_if_not_bol(s); - print_expr(s, expr); - word(s.s, ";"); - } - } - if parse::classify::stmt_ends_with_semi(st) { word(s.s, ";"); } - maybe_print_trailing_comment(s, st.span, none::<uint>); -} - -fn print_block(s: ps, blk: ast::blk) { - print_possibly_embedded_block(s, blk, block_normal, indent_unit); -} - -fn print_block_with_attrs(s: ps, blk: ast::blk, attrs: [ast::attribute]) { - print_possibly_embedded_block_(s, blk, block_normal, indent_unit, attrs); -} - -enum embed_type { block_macro, block_block_fn, block_normal, } - -fn print_possibly_embedded_block(s: ps, blk: ast::blk, embedded: embed_type, - indented: uint) { - print_possibly_embedded_block_( - s, blk, embedded, indented, []); -} - -fn print_possibly_embedded_block_(s: ps, blk: ast::blk, embedded: embed_type, - indented: uint, attrs: [ast::attribute]) { - alt blk.node.rules { - ast::unchecked_blk { word(s.s, "unchecked"); } - ast::unsafe_blk { word(s.s, "unsafe"); } - ast::default_blk { } - } - maybe_print_comment(s, blk.span.lo); - let ann_node = node_block(s, blk); - s.ann.pre(ann_node); - alt embedded { - block_macro { word(s.s, "#{"); end(s); } - block_block_fn { end(s); } - block_normal { bopen(s); } - } - - print_inner_attributes(s, attrs); - - for blk.node.view_items.each {|vi| print_view_item(s, vi); } - for blk.node.stmts.each {|st| - print_stmt(s, *st); - } - alt blk.node.expr { - some(expr) { - space_if_not_bol(s); - print_expr(s, expr); - maybe_print_trailing_comment(s, expr.span, some(blk.span.hi)); - } - _ { } - } - bclose_(s, blk.span, indented); - s.ann.post(ann_node); -} - -// ret and fail, without arguments cannot appear is the discriminant of if, -// alt, do, & while unambiguously without being parenthesized -fn print_maybe_parens_discrim(s: ps, e: @ast::expr) { - let disambig = alt e.node { - ast::expr_ret(none) | ast::expr_fail(none) { true } - _ { false } - }; - if disambig { popen(s); } - print_expr(s, e); - if disambig { pclose(s); } -} - -fn print_if(s: ps, test: @ast::expr, blk: ast::blk, - elseopt: option<@ast::expr>, chk: bool) { - head(s, "if"); - if chk { word_nbsp(s, "check"); } - print_maybe_parens_discrim(s, test); - space(s.s); - print_block(s, blk); - fn do_else(s: ps, els: option<@ast::expr>) { - alt els { - some(_else) { - alt _else.node { - // "another else-if" - ast::expr_if(i, t, e) { - cbox(s, indent_unit - 1u); - ibox(s, 0u); - word(s.s, " else if "); - print_maybe_parens_discrim(s, i); - space(s.s); - print_block(s, t); - do_else(s, e); - } - // "final else" - ast::expr_block(b) { - cbox(s, indent_unit - 1u); - ibox(s, 0u); - word(s.s, " else "); - print_block(s, b); - } - // BLEAH, constraints would be great here - _ { - fail "print_if saw if with weird alternative"; - } - } - } - _ {/* fall through */ } - } - } - do_else(s, elseopt); -} - -fn print_mac(s: ps, m: ast::mac) { - alt m.node { - ast::mac_invoc(path, arg, body) { - word(s.s, "#"); - print_path(s, path, false); - alt arg { - some(@{node: ast::expr_vec(_, _), _}) { } - _ { word(s.s, " "); } - } - option::iter(arg, bind print_expr(s, _)); - // FIXME: extension 'body' (#2339) - } - ast::mac_embed_type(ty) { - word(s.s, "#<"); - print_type(s, ty); - word(s.s, ">"); - } - ast::mac_embed_block(blk) { - print_possibly_embedded_block(s, blk, block_normal, indent_unit); - } - ast::mac_ellipsis { word(s.s, "..."); } - ast::mac_var(v) { word(s.s, #fmt("$%u", v)); } - _ { /* fixme */ } - } -} - -fn print_vstore(s: ps, t: ast::vstore) { - alt t { - ast::vstore_fixed(some(i)) { word_space(s, #fmt("/%u", i)); } - ast::vstore_fixed(none) { word_space(s, "/_"); } - ast::vstore_uniq { word_space(s, "/~"); } - ast::vstore_box { word_space(s, "/@"); } - ast::vstore_slice(r) { word(s.s, "/"); print_region(s, r); } - } -} - -fn print_expr(s: ps, &&expr: @ast::expr) { - maybe_print_comment(s, expr.span.lo); - ibox(s, indent_unit); - let ann_node = node_expr(s, expr); - s.ann.pre(ann_node); - alt expr.node { - ast::expr_vstore(e, v) { - print_expr(s, e); - print_vstore(s, v); - } - ast::expr_vec(exprs, mutbl) { - ibox(s, indent_unit); - word(s.s, "["); - if mutbl == ast::m_mutbl { - word(s.s, "mut"); - if vec::len(exprs) > 0u { nbsp(s); } - } - commasep_exprs(s, inconsistent, exprs); - word(s.s, "]"); - end(s); - } - ast::expr_rec(fields, wth) { - fn print_field(s: ps, field: ast::field) { - ibox(s, indent_unit); - if field.node.mutbl == ast::m_mutbl { word_nbsp(s, "mut"); } - word(s.s, field.node.ident); - word_space(s, ":"); - print_expr(s, field.node.expr); - end(s); - } - fn get_span(field: ast::field) -> codemap::span { ret field.span; } - word(s.s, "{"); - commasep_cmnt(s, consistent, fields, print_field, get_span); - alt wth { - some(expr) { - if vec::len(fields) > 0u { space(s.s); } - ibox(s, indent_unit); - word_space(s, "with"); - print_expr(s, expr); - end(s); - } - _ { word(s.s, ","); } - } - word(s.s, "}"); - } - ast::expr_tup(exprs) { - popen(s); - commasep_exprs(s, inconsistent, exprs); - pclose(s); - } - ast::expr_call(func, args, has_block) { - let mut base_args = args; - let blk = if has_block { - let blk_arg = vec::pop(base_args); - alt blk_arg.node { - ast::expr_loop_body(_) { word_nbsp(s, "for"); } - _ {} - } - some(blk_arg) - } else { none }; - print_expr_parens_if_not_bot(s, func); - if !has_block || vec::len(base_args) > 0u { - popen(s); - commasep_exprs(s, inconsistent, base_args); - pclose(s); - } - if has_block { - nbsp(s); - print_expr(s, option::get(blk)); - } - } - ast::expr_bind(func, args) { - fn print_opt(s: ps, expr: option<@ast::expr>) { - alt expr { - some(expr) { print_expr(s, expr); } - _ { word(s.s, "_"); } - } - } - - // "bind" keyword is only needed if there are no "_" arguments. - if !vec::any(args) {|arg| option::is_none(arg) } { - word_nbsp(s, "bind"); - } - - print_expr(s, func); - popen(s); - commasep(s, inconsistent, args, print_opt); - pclose(s); - } - ast::expr_binary(op, lhs, rhs) { - let prec = operator_prec(op); - print_op_maybe_parens(s, lhs, prec); - space(s.s); - word_space(s, ast_util::binop_to_str(op)); - print_op_maybe_parens(s, rhs, prec + 1u); - } - ast::expr_unary(op, expr) { - word(s.s, ast_util::unop_to_str(op)); - print_op_maybe_parens(s, expr, parse::prec::unop_prec); - } - ast::expr_addr_of(m, expr) { - word(s.s, "&"); - print_mutability(s, m); - print_expr(s, expr); - } - ast::expr_lit(lit) { print_literal(s, lit); } - ast::expr_cast(expr, ty) { - print_op_maybe_parens(s, expr, parse::prec::as_prec); - space(s.s); - word_space(s, "as"); - print_type_ex(s, ty, true); - } - ast::expr_if(test, blk, elseopt) { - print_if(s, test, blk, elseopt, false); - } - ast::expr_if_check(test, blk, elseopt) { - print_if(s, test, blk, elseopt, true); - } - ast::expr_while(test, blk) { - head(s, "while"); - print_maybe_parens_discrim(s, test); - space(s.s); - print_block(s, blk); - } - ast::expr_loop(blk) { - head(s, "loop"); - space(s.s); - print_block(s, blk); - } - ast::expr_alt(expr, arms, mode) { - cbox(s, alt_indent_unit); - ibox(s, 4u); - word_nbsp(s, "alt"); - if mode == ast::alt_check { word_nbsp(s, "check"); } - print_maybe_parens_discrim(s, expr); - space(s.s); - bopen(s); - for arms.each {|arm| - space(s.s); - cbox(s, alt_indent_unit); - ibox(s, 0u); - let mut first = true; - for arm.pats.each {|p| - if first { - first = false; - } else { space(s.s); word_space(s, "|"); } - print_pat(s, p); - } - space(s.s); - alt arm.guard { - some(e) { word_space(s, "if"); print_expr(s, e); space(s.s); } - none { } - } - print_possibly_embedded_block(s, arm.body, block_normal, - alt_indent_unit); - } - bclose_(s, expr.span, alt_indent_unit); - } - ast::expr_fn(proto, decl, body, cap_clause) { - // containing cbox, will be closed by print-block at } - cbox(s, indent_unit); - // head-box, will be closed by print-block at start - ibox(s, 0u); - print_purity(s, decl.purity); - word(s.s, proto_to_str(proto)); - print_fn_args_and_ret(s, decl, *cap_clause); - space(s.s); - print_block(s, body); - } - ast::expr_fn_block(decl, body, cap_clause) { - // containing cbox, will be closed by print-block at } - cbox(s, indent_unit); - // head-box, will be closed by print-block at start - ibox(s, 0u); - word(s.s, "{"); - print_fn_block_args(s, decl, *cap_clause); - print_possibly_embedded_block(s, body, block_block_fn, indent_unit); - } - ast::expr_loop_body(body) { - print_expr(s, body); - } - ast::expr_block(blk) { - // containing cbox, will be closed by print-block at } - cbox(s, indent_unit); - // head-box, will be closed by print-block after { - ibox(s, 0u); - print_block(s, blk); - } - ast::expr_copy(e) { word_space(s, "copy"); print_expr(s, e); } - ast::expr_move(lhs, rhs) { - print_expr(s, lhs); - space(s.s); - word_space(s, "<-"); - print_expr(s, rhs); - } - ast::expr_assign(lhs, rhs) { - print_expr(s, lhs); - space(s.s); - word_space(s, "="); - print_expr(s, rhs); - } - ast::expr_swap(lhs, rhs) { - print_expr(s, lhs); - space(s.s); - word_space(s, "<->"); - print_expr(s, rhs); - } - ast::expr_assign_op(op, lhs, rhs) { - print_expr(s, lhs); - space(s.s); - word(s.s, ast_util::binop_to_str(op)); - word_space(s, "="); - print_expr(s, rhs); - } - ast::expr_field(expr, id, tys) { - // Deal with '10.x' - if ends_in_lit_int(expr) { - popen(s); print_expr(s, expr); pclose(s); - } else { - print_expr_parens_if_not_bot(s, expr); - } - word(s.s, "."); - word(s.s, id); - if vec::len(tys) > 0u { - word(s.s, "::<"); - commasep(s, inconsistent, tys, print_type); - word(s.s, ">"); - } - } - ast::expr_index(expr, index) { - print_expr_parens_if_not_bot(s, expr); - word(s.s, "["); - print_expr(s, index); - word(s.s, "]"); - } - ast::expr_path(path) { print_path(s, path, true); } - ast::expr_fail(maybe_fail_val) { - word(s.s, "fail"); - alt maybe_fail_val { - some(expr) { word(s.s, " "); print_expr(s, expr); } - _ { } - } - } - ast::expr_break { word(s.s, "break"); } - ast::expr_cont { word(s.s, "cont"); } - ast::expr_ret(result) { - word(s.s, "ret"); - alt result { - some(expr) { word(s.s, " "); print_expr(s, expr); } - _ { } - } - } - ast::expr_log(lvl, lexp, expr) { - alt check lvl { - 1 { word_nbsp(s, "log"); print_expr(s, expr); } - 0 { word_nbsp(s, "log_err"); print_expr(s, expr); } - 2 { - word_nbsp(s, "log"); - popen(s); - print_expr(s, lexp); - word(s.s, ","); - space_if_not_bol(s); - print_expr(s, expr); - pclose(s); - } - } - } - ast::expr_check(m, expr) { - alt m { - ast::claimed_expr { word_nbsp(s, "claim"); } - ast::checked_expr { word_nbsp(s, "check"); } - } - popen(s); - print_expr(s, expr); - pclose(s); - } - ast::expr_assert(expr) { - word_nbsp(s, "assert"); - print_expr(s, expr); - } - ast::expr_new(p, _, v) { - word_nbsp(s, "new"); - popen(s); - print_expr(s, p); - pclose(s); - print_expr(s, v); - } - ast::expr_mac(m) { print_mac(s, m); } - } - s.ann.post(ann_node); - end(s); -} - -fn print_expr_parens_if_not_bot(s: ps, ex: @ast::expr) { - let parens = alt ex.node { - ast::expr_fail(_) | ast::expr_ret(_) | - ast::expr_binary(_, _, _) | ast::expr_unary(_, _) | - ast::expr_move(_, _) | ast::expr_copy(_) | - ast::expr_assign(_, _) | - ast::expr_assign_op(_, _, _) | ast::expr_swap(_, _) | - ast::expr_log(_, _, _) | ast::expr_assert(_) | - ast::expr_call(_, _, true) | - ast::expr_check(_, _) { true } - _ { false } - }; - if parens { popen(s); } - print_expr(s, ex); - if parens { pclose(s); } -} - -fn print_local_decl(s: ps, loc: @ast::local) { - print_pat(s, loc.node.pat); - alt loc.node.ty.node { - ast::ty_infer { } - _ { word_space(s, ":"); print_type(s, loc.node.ty); } - } -} - -fn print_decl(s: ps, decl: @ast::decl) { - maybe_print_comment(s, decl.span.lo); - alt decl.node { - ast::decl_local(locs) { - space_if_not_bol(s); - ibox(s, indent_unit); - word_nbsp(s, "let"); - - // if any are mut, all are mut - if vec::any(locs) {|l| l.node.is_mutbl } { - assert vec::all(locs) {|l| l.node.is_mutbl }; - word_nbsp(s, "mut"); - } - - fn print_local(s: ps, &&loc: @ast::local) { - ibox(s, indent_unit); - print_local_decl(s, loc); - end(s); - alt loc.node.init { - some(init) { - nbsp(s); - alt init.op { - ast::init_assign { word_space(s, "="); } - ast::init_move { word_space(s, "<-"); } - } - print_expr(s, init.expr); - } - _ { } - } - } - commasep(s, consistent, locs, print_local); - end(s); - } - ast::decl_item(item) { print_item(s, item); } - } -} - -fn print_ident(s: ps, ident: ast::ident) { word(s.s, ident); } - -fn print_for_decl(s: ps, loc: @ast::local, coll: @ast::expr) { - print_local_decl(s, loc); - space(s.s); - word_space(s, "in"); - print_expr(s, coll); -} - -fn print_path(s: ps, &&path: @ast::path, colons_before_params: bool) { - maybe_print_comment(s, path.span.lo); - if path.global { word(s.s, "::"); } - let mut first = true; - for path.idents.each {|id| - if first { first = false; } else { word(s.s, "::"); } - word(s.s, id); - } - if path.rp.is_some() || !path.types.is_empty() { - if colons_before_params { word(s.s, "::"); } - - alt path.rp { - none { /* ok */ } - some(r) { - word(s.s, "/"); - print_region(s, r); - } - } - - if !path.types.is_empty() { - word(s.s, "<"); - commasep(s, inconsistent, path.types, print_type); - word(s.s, ">"); - } - } -} - -fn print_pat(s: ps, &&pat: @ast::pat) { - maybe_print_comment(s, pat.span.lo); - let ann_node = node_pat(s, pat); - s.ann.pre(ann_node); - /* Pat isn't normalized, but the beauty of it - is that it doesn't matter */ - alt pat.node { - ast::pat_wild { word(s.s, "_"); } - ast::pat_ident(path, sub) { - print_path(s, path, true); - alt sub { - some(p) { word(s.s, "@"); print_pat(s, p); } - none {} - } - } - ast::pat_enum(path, args_) { - print_path(s, path, true); - alt args_ { - none { word(s.s, "(*)"); } - some(args) { - if vec::len(args) > 0u { - popen(s); - commasep(s, inconsistent, args, print_pat); - pclose(s); - } else { } - } - } - } - ast::pat_rec(fields, etc) { - word(s.s, "{"); - fn print_field(s: ps, f: ast::field_pat) { - cbox(s, indent_unit); - word(s.s, f.ident); - word_space(s, ":"); - print_pat(s, f.pat); - end(s); - } - fn get_span(f: ast::field_pat) -> codemap::span { ret f.pat.span; } - commasep_cmnt(s, consistent, fields, print_field, get_span); - if etc { - if vec::len(fields) != 0u { word_space(s, ","); } - word(s.s, "_"); - } - word(s.s, "}"); - } - ast::pat_tup(elts) { - popen(s); - commasep(s, inconsistent, elts, print_pat); - pclose(s); - } - ast::pat_box(inner) { word(s.s, "@"); print_pat(s, inner); } - ast::pat_uniq(inner) { word(s.s, "~"); print_pat(s, inner); } - ast::pat_lit(e) { print_expr(s, e); } - ast::pat_range(begin, end) { - print_expr(s, begin); - space(s.s); - word_space(s, "to"); - print_expr(s, end); - } - } - s.ann.post(ann_node); -} - -fn print_fn(s: ps, decl: ast::fn_decl, name: ast::ident, - typarams: [ast::ty_param]) { - alt decl.purity { - ast::impure_fn { head(s, "fn") } - _ { head(s, purity_to_str(decl.purity) + " fn") } - } - word(s.s, name); - print_type_params(s, typarams); - print_fn_args_and_ret(s, decl, []); -} - -fn print_fn_args(s: ps, decl: ast::fn_decl, - cap_items: [ast::capture_item]) { - commasep(s, inconsistent, decl.inputs, print_arg); - if cap_items.is_not_empty() { - let mut first = decl.inputs.is_empty(); - for cap_items.each { |cap_item| - if first { first = false; } else { word_space(s, ","); } - if cap_item.is_move { word_nbsp(s, "move") } - else { word_nbsp(s, "copy") } - word(s.s, cap_item.name); - } - } -} - -fn print_fn_args_and_ret(s: ps, decl: ast::fn_decl, - cap_items: [ast::capture_item]) { - popen(s); - print_fn_args(s, decl, cap_items); - pclose(s); - word(s.s, constrs_str(decl.constraints, {|c| - ast_fn_constr_to_str(decl, c) - })); - - maybe_print_comment(s, decl.output.span.lo); - if decl.output.node != ast::ty_nil { - space_if_not_bol(s); - word_space(s, "->"); - print_type(s, decl.output); - } -} - -fn print_fn_block_args(s: ps, decl: ast::fn_decl, - cap_items: [ast::capture_item]) { - word(s.s, "|"); - print_fn_args(s, decl, cap_items); - word(s.s, "|"); - if decl.output.node != ast::ty_infer { - space_if_not_bol(s); - word_space(s, "->"); - print_type(s, decl.output); - } - maybe_print_comment(s, decl.output.span.lo); -} - -fn mode_to_str(m: ast::mode) -> str { - alt m { - ast::expl(ast::by_mutbl_ref) { "&" } - ast::expl(ast::by_move) { "-" } - ast::expl(ast::by_ref) { "&&" } - ast::expl(ast::by_val) { "++" } - ast::expl(ast::by_copy) { "+" } - ast::infer(_) { "" } - } -} - -fn print_arg_mode(s: ps, m: ast::mode) { - let ms = mode_to_str(m); - if ms != "" { word(s.s, ms); } -} - -fn print_bounds(s: ps, bounds: @[ast::ty_param_bound]) { - if vec::len(*bounds) > 0u { - word(s.s, ":"); - for vec::each(*bounds) {|bound| - nbsp(s); - alt bound { - ast::bound_copy { word(s.s, "copy"); } - ast::bound_send { word(s.s, "send"); } - ast::bound_const { word(s.s, "const"); } - ast::bound_iface(t) { print_type(s, t); } - } - } - } -} - -fn print_region_param(s: ps, rp: ast::region_param) { - alt rp { - ast::rp_self { word(s.s, "/&") } - ast::rp_none { } - } -} - -fn print_type_params(s: ps, &¶ms: [ast::ty_param]) { - if vec::len(params) > 0u { - word(s.s, "<"); - fn printParam(s: ps, param: ast::ty_param) { - word(s.s, param.ident); - print_bounds(s, param.bounds); - } - commasep(s, inconsistent, params, printParam); - word(s.s, ">"); - } -} - -fn print_meta_item(s: ps, &&item: @ast::meta_item) { - ibox(s, indent_unit); - alt item.node { - ast::meta_word(name) { word(s.s, name); } - ast::meta_name_value(name, value) { - word_space(s, name); - word_space(s, "="); - print_literal(s, @value); - } - ast::meta_list(name, items) { - word(s.s, name); - popen(s); - commasep(s, consistent, items, print_meta_item); - pclose(s); - } - } - end(s); -} - -fn print_view_path(s: ps, &&vp: @ast::view_path) { - alt vp.node { - ast::view_path_simple(ident, path, _) { - if path.idents[vec::len(path.idents)-1u] != ident { - word_space(s, ident); - word_space(s, "="); - } - print_path(s, path, false); - } - - ast::view_path_glob(path, _) { - print_path(s, path, false); - word(s.s, "::*"); - } - - ast::view_path_list(path, idents, _) { - print_path(s, path, false); - word(s.s, "::{"); - commasep(s, inconsistent, idents) {|s, w| - word(s.s, w.node.name) - } - word(s.s, "}"); - } - } -} - -fn print_view_paths(s: ps, vps: [@ast::view_path]) { - commasep(s, inconsistent, vps, print_view_path); -} - -fn print_view_item(s: ps, item: @ast::view_item) { - hardbreak_if_not_bol(s); - maybe_print_comment(s, item.span.lo); - alt item.node { - ast::view_item_use(id, mta, _) { - head(s, "use"); - word(s.s, id); - if vec::len(mta) > 0u { - popen(s); - commasep(s, consistent, mta, print_meta_item); - pclose(s); - } - } - - ast::view_item_import(vps) { - head(s, "import"); - print_view_paths(s, vps); - } - - ast::view_item_export(vps) { - head(s, "export"); - print_view_paths(s, vps); - } - } - word(s.s, ";"); - end(s); // end inner head-block - end(s); // end outer head-block -} - -fn print_op_maybe_parens(s: ps, expr: @ast::expr, outer_prec: uint) { - let add_them = need_parens(expr, outer_prec); - if add_them { popen(s); } - print_expr(s, expr); - if add_them { pclose(s); } -} - -fn print_mutability(s: ps, mutbl: ast::mutability) { - alt mutbl { - ast::m_mutbl { word_nbsp(s, "mut"); } - ast::m_const { word_nbsp(s, "const"); } - ast::m_imm {/* nothing */ } - } -} - -fn print_mt(s: ps, mt: ast::mt) { - print_mutability(s, mt.mutbl); - print_type(s, mt.ty); -} - -fn print_arg(s: ps, input: ast::arg) { - ibox(s, indent_unit); - print_arg_mode(s, input.mode); - alt input.ty.node { - ast::ty_infer { - word(s.s, input.ident); - } - _ { - if str::len(input.ident) > 0u { - word_space(s, input.ident + ":"); - } - print_type(s, input.ty); - } - } - end(s); -} - -fn print_ty_fn(s: ps, opt_proto: option<ast::proto>, - decl: ast::fn_decl, id: option<ast::ident>, - tps: option<[ast::ty_param]>) { - ibox(s, indent_unit); - word(s.s, opt_proto_to_str(opt_proto)); - alt id { some(id) { word(s.s, " "); word(s.s, id); } _ { } } - alt tps { some(tps) { print_type_params(s, tps); } _ { } } - zerobreak(s.s); - popen(s); - commasep(s, inconsistent, decl.inputs, print_arg); - pclose(s); - maybe_print_comment(s, decl.output.span.lo); - if decl.output.node != ast::ty_nil { - space_if_not_bol(s); - ibox(s, indent_unit); - word_space(s, "->"); - if decl.cf == ast::noreturn { word_nbsp(s, "!"); } - else { print_type(s, decl.output); } - end(s); - } - word(s.s, constrs_str(decl.constraints, ast_ty_fn_constr_to_str)); - end(s); -} - -fn maybe_print_trailing_comment(s: ps, span: codemap::span, - next_pos: option<uint>) { - let mut cm; - alt s.cm { some(ccm) { cm = ccm; } _ { ret; } } - alt next_comment(s) { - some(cmnt) { - if cmnt.style != comments::trailing { ret; } - let span_line = codemap::lookup_char_pos(cm, span.hi); - let comment_line = codemap::lookup_char_pos(cm, cmnt.pos); - let mut next = cmnt.pos + 1u; - alt next_pos { none { } some(p) { next = p; } } - if span.hi < cmnt.pos && cmnt.pos < next && - span_line.line == comment_line.line { - print_comment(s, cmnt); - s.cur_cmnt += 1u; - } - } - _ { } - } -} - -fn print_remaining_comments(s: ps) { - // If there aren't any remaining comments, then we need to manually - // make sure there is a line break at the end. - if option::is_none(next_comment(s)) { hardbreak(s.s); } - loop { - alt next_comment(s) { - some(cmnt) { print_comment(s, cmnt); s.cur_cmnt += 1u; } - _ { break; } - } - } -} - -fn print_literal(s: ps, &&lit: @ast::lit) { - maybe_print_comment(s, lit.span.lo); - alt next_lit(s, lit.span.lo) { - some(lt) { - word(s.s, lt.lit); - ret; - } - _ {} - } - alt lit.node { - ast::lit_str(st) { print_string(s, st); } - ast::lit_int(ch, ast::ty_char) { - word(s.s, "'" + escape_str(str::from_char(ch as char), '\'') + "'"); - } - ast::lit_int(i, t) { - if i < 0_i64 { - word(s.s, - "-" + u64::to_str(-i as u64, 10u) - + ast_util::int_ty_to_str(t)); - } else { - word(s.s, - u64::to_str(i as u64, 10u) - + ast_util::int_ty_to_str(t)); - } - } - ast::lit_uint(u, t) { - word(s.s, - u64::to_str(u, 10u) - + ast_util::uint_ty_to_str(t)); - } - ast::lit_float(f, t) { - word(s.s, f + ast_util::float_ty_to_str(t)); - } - ast::lit_nil { word(s.s, "()"); } - ast::lit_bool(val) { - if val { word(s.s, "true"); } else { word(s.s, "false"); } - } - } -} - -fn lit_to_str(l: @ast::lit) -> str { ret to_str(l, print_literal); } - -fn next_lit(s: ps, pos: uint) -> option<comments::lit> { - alt s.literals { - some(lits) { - while s.cur_lit < vec::len(lits) { - let lt = lits[s.cur_lit]; - if lt.pos > pos { ret none; } - s.cur_lit += 1u; - if lt.pos == pos { ret some(lt); } - } - ret none; - } - _ { ret none; } - } -} - -fn maybe_print_comment(s: ps, pos: uint) { - loop { - alt next_comment(s) { - some(cmnt) { - if cmnt.pos < pos { - print_comment(s, cmnt); - s.cur_cmnt += 1u; - } else { break; } - } - _ { break; } - } - } -} - -fn print_comment(s: ps, cmnt: comments::cmnt) { - alt cmnt.style { - comments::mixed { - assert (vec::len(cmnt.lines) == 1u); - zerobreak(s.s); - word(s.s, cmnt.lines[0]); - zerobreak(s.s); - } - comments::isolated { - pprust::hardbreak_if_not_bol(s); - for cmnt.lines.each {|line| - // Don't print empty lines because they will end up as trailing - // whitespace - if str::is_not_empty(line) { word(s.s, line); } - hardbreak(s.s); - } - } - comments::trailing { - word(s.s, " "); - if vec::len(cmnt.lines) == 1u { - word(s.s, cmnt.lines[0]); - hardbreak(s.s); - } else { - ibox(s, 0u); - for cmnt.lines.each {|line| - if str::is_not_empty(line) { word(s.s, line); } - hardbreak(s.s); - } - end(s); - } - } - comments::blank_line { - // We need to do at least one, possibly two hardbreaks. - let is_semi = - alt s.s.last_token() { - pp::STRING(s, _) { s == ";" } - _ { false } - }; - if is_semi || is_begin(s) || is_end(s) { hardbreak(s.s); } - hardbreak(s.s); - } - } -} - -fn print_string(s: ps, st: str) { - word(s.s, "\""); - word(s.s, escape_str(st, '"')); - word(s.s, "\""); -} - -fn escape_str(st: str, to_escape: char) -> str { - let mut out: str = ""; - let len = str::len(st); - let mut i = 0u; - while i < len { - alt st[i] as char { - '\n' { out += "\\n"; } - '\t' { out += "\\t"; } - '\r' { out += "\\r"; } - '\\' { out += "\\\\"; } - cur { - if cur == to_escape { out += "\\"; } - // FIXME some (or all?) non-ascii things should be escaped - // (See #2306) - str::push_char(out, cur); - } - } - i += 1u; - } - ret out; -} - -fn to_str<T>(t: T, f: fn@(ps, T)) -> str { - let buffer = io::mem_buffer(); - let s = rust_printer(io::mem_buffer_writer(buffer)); - f(s, t); - eof(s.s); - io::mem_buffer_str(buffer) -} - -fn next_comment(s: ps) -> option<comments::cmnt> { - alt s.comments { - some(cmnts) { - if s.cur_cmnt < vec::len(cmnts) { - ret some(cmnts[s.cur_cmnt]); - } else { ret none::<comments::cmnt>; } - } - _ { ret none::<comments::cmnt>; } - } -} - -fn constr_args_to_str<T>(f: fn@(T) -> str, args: [@ast::sp_constr_arg<T>]) -> - str { - let mut comma = false; - let mut s = "("; - for args.each {|a| - if comma { s += ", "; } else { comma = true; } - s += constr_arg_to_str::<T>(f, a.node); - } - s += ")"; - ret s; -} - -fn constr_arg_to_str<T>(f: fn@(T) -> str, c: ast::constr_arg_general_<T>) -> - str { - alt c { - ast::carg_base { ret "*"; } - ast::carg_ident(i) { ret f(i); } - ast::carg_lit(l) { ret lit_to_str(l); } - } -} - -// needed b/c constr_args_to_str needs -// something that takes an alias -// (argh) -fn uint_to_str(&&i: uint) -> str { ret uint::str(i); } - -fn ast_ty_fn_constr_to_str(&&c: @ast::constr) -> str { - ret path_to_str(c.node.path) + - constr_args_to_str(uint_to_str, c.node.args); -} - -fn ast_fn_constr_to_str(decl: ast::fn_decl, &&c: @ast::constr) -> str { - let arg_to_str = bind fn_arg_idx_to_str(decl, _); - ret path_to_str(c.node.path) + - constr_args_to_str(arg_to_str, c.node.args); -} - -fn ty_constr_to_str(&&c: @ast::ty_constr) -> str { - fn ty_constr_path_to_str(&&p: @ast::path) -> str { "*." + path_to_str(p) } - - ret path_to_str(c.node.path) + - constr_args_to_str::<@ast::path>(ty_constr_path_to_str, - c.node.args); -} - -fn constrs_str<T>(constrs: [T], elt: fn(T) -> str) -> str { - let mut s = "", colon = true; - for constrs.each {|c| - if colon { s += " : "; colon = false; } else { s += ", "; } - s += elt(c); - } - ret s; -} - -fn fn_arg_idx_to_str(decl: ast::fn_decl, &&idx: uint) -> str { - decl.inputs[idx].ident -} - -fn opt_proto_to_str(opt_p: option<ast::proto>) -> str { - alt opt_p { - none { "fn" } - some(p) { proto_to_str(p) } - } -} - -fn purity_to_str(p: ast::purity) -> str { - alt p { - ast::impure_fn {"impure"} - ast::unsafe_fn {"unsafe"} - ast::pure_fn {"pure"} - ast::crust_fn {"crust"} - } -} - -fn print_purity(s: ps, p: ast::purity) { - alt p { - ast::impure_fn {} - _ { word_nbsp(s, purity_to_str(p)) } - } -} - -fn proto_to_str(p: ast::proto) -> str { - ret alt p { - ast::proto_bare { "native fn" } - ast::proto_any { "fn" } - ast::proto_block { "fn&" } - ast::proto_uniq { "fn~" } - ast::proto_box { "fn@" } - }; -} - -// -// Local Variables: -// mode: rust -// fill-column: 78; -// indent-tabs-mode: nil -// c-basic-offset: 4 -// buffer-file-coding-system: utf-8-unix -// End: -// |
