From d12ea3989649616437a7c1434f5c5a6438235eb7 Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Mon, 30 May 2011 14:10:54 -0700 Subject: [PATCH] Improve comment handling in pp. --- src/comp/front/lexer.rs | 219 +++++++++++++++++++++++-------- src/comp/front/parser.rs | 2 +- src/comp/pretty/pp.rs | 47 +++++-- src/comp/pretty/pprust.rs | 270 +++++++++++++++++++------------------- 4 files changed, 333 insertions(+), 205 deletions(-) diff --git a/src/comp/front/lexer.rs b/src/comp/front/lexer.rs index ef70688010ee4..d87df08745320 100644 --- a/src/comp/front/lexer.rs +++ b/src/comp/front/lexer.rs @@ -22,6 +22,7 @@ state type reader = state obj { fn get_mark_chpos() -> uint; fn get_interner() -> @interner::interner[str]; fn get_chpos() -> uint; + fn get_col() -> uint; fn get_filemap() -> codemap::filemap; fn err(str m); }; @@ -33,6 +34,7 @@ fn new_reader(session sess, io::reader rdr, state obj reader(session sess, str file, uint len, + mutable uint col, mutable uint pos, mutable char ch, mutable uint mark_chpos, @@ -68,9 +70,11 @@ fn new_reader(session sess, io::reader rdr, fn bump() { if (pos < len) { + col += 1u; chpos += 1u; if (ch == '\n') { codemap::next_line(fm, chpos); + col = 0u; } auto next = str::char_range_at(file, pos); pos = next._1; @@ -82,6 +86,10 @@ fn new_reader(session sess, io::reader rdr, fn get_interner() -> @interner::interner[str] { ret itr; } + fn get_col() -> uint { + ret col; + } + fn get_filemap() -> codemap::filemap { ret fm; } @@ -92,7 +100,8 @@ fn new_reader(session sess, io::reader rdr, } auto file = str::unsafe_from_bytes(rdr.read_whole_stream()); let vec[str] strs = []; - auto rd = reader(sess, file, str::byte_len(file), 0u, -1 as char, + auto rd = reader(sess, file, str::byte_len(file), 0u, 0u, + -1 as char, filemap.start_pos, filemap.start_pos, strs, filemap, itr); rd.init(); @@ -155,7 +164,7 @@ fn is_whitespace(char c) -> bool { ret c == ' ' || c == '\t' || c == '\r' || c == '\n'; } -fn consume_any_whitespace(&reader rdr) { +fn consume_whitespace_and_comments(&reader rdr) { while (is_whitespace(rdr.curr())) { rdr.bump(); } @@ -170,7 +179,7 @@ fn consume_any_line_comment(&reader rdr) { rdr.bump(); } // Restart whitespace munch. - be consume_any_whitespace(rdr); + be consume_whitespace_and_comments(rdr); } case ('*') { rdr.bump(); @@ -207,7 +216,7 @@ fn consume_block_comment(&reader rdr) { } } // restart whitespace munch. - be consume_any_whitespace(rdr); + be consume_whitespace_and_comments(rdr); } fn digits_to_string(str s) -> int { @@ -430,7 +439,7 @@ fn scan_numeric_escape(&reader rdr, uint n_hex_digits) -> char { fn next_token(&reader rdr) -> token::token { auto accum_str = ""; - consume_any_whitespace(rdr); + consume_whitespace_and_comments(rdr); if (rdr.is_eof()) { ret token::EOF; } @@ -720,70 +729,161 @@ fn next_token(&reader rdr) -> token::token { fail; } -tag cmnt_ { - cmnt_line(str); - cmnt_block(vec[str]); + +tag cmnt_style { + isolated; // No code on either side of each line of the comment + trailing; // Code exists to the left of the comment + mixed; // Code before /* foo */ and after the comment } -type cmnt = rec(cmnt_ val, uint pos, bool space_after); +type cmnt = rec(cmnt_style style, vec[str] lines, uint pos); -fn consume_whitespace(&reader rdr) -> uint { - auto lines = 0u; - while (is_whitespace(rdr.curr())) { - if (rdr.curr() == '\n') {lines += 1u;} +fn read_to_eol(&reader rdr) -> str { + auto val = ""; + while (rdr.curr() != '\n' && !rdr.is_eof()) { + str::push_char(val, rdr.curr()); + rdr.bump(); + } + if (rdr.curr() == '\n') { rdr.bump(); + } else { + assert rdr.is_eof(); } - ret lines; + ret val; } -fn read_line_comment(&reader rdr) -> cmnt { - auto p = rdr.get_chpos(); - rdr.bump(); rdr.bump(); - while (rdr.curr() == ' ') {rdr.bump();} - auto val = ""; - while (rdr.curr() != '\n' && !rdr.is_eof()) { - str::push_char(val, rdr.curr()); +fn read_one_line_comment(&reader rdr) -> str { + auto val = read_to_eol(rdr); + assert val.(0) == ('/' as u8) && val.(1) == ('/' as u8); + ret val; +} + +fn consume_whitespace(&reader rdr) { + while (is_whitespace(rdr.curr()) && !rdr.is_eof()) { rdr.bump(); } - ret rec(val=cmnt_line(val), - pos=p, - space_after=consume_whitespace(rdr) > 1u); } -fn read_block_comment(&reader rdr) -> cmnt { + +fn consume_non_eol_whitespace(&reader rdr) { + while (is_whitespace(rdr.curr()) && + rdr.curr() != '\n' && !rdr.is_eof()) { + rdr.bump(); + } +} + + +fn read_line_comments(&reader rdr, bool code_to_the_left) -> cmnt { + log ">>> line comments"; auto p = rdr.get_chpos(); - rdr.bump(); rdr.bump(); - while (rdr.curr() == ' ') {rdr.bump();} let vec[str] lines = []; - auto val = ""; - auto level = 1; - while (true) { - if (rdr.curr() == '\n') { - vec::push[str](lines, val); - val = ""; - consume_whitespace(rdr); + while (rdr.curr() == '/' && rdr.next() == '/') { + lines += [read_one_line_comment(rdr)]; + consume_non_eol_whitespace(rdr); + } + log "<<< line comments"; + ret rec(style = if (code_to_the_left) { trailing } else { isolated }, + lines = lines, + pos=p); +} + +fn all_whitespace(&str s, uint begin, uint end) -> bool { + let uint i = begin; + while (i != end) { + if (!is_whitespace(s.(i) as char)) { + ret false; + } + i += 1u; + } + ret true; +} + +fn trim_whitespace_prefix_and_push_line(&mutable vec[str] lines, + &str s, uint col) { + auto s1; + if (all_whitespace(s, 0u, col)) { + if (col < str::byte_len(s)) { + s1 = str::slice(s, col, str::byte_len(s)); } else { - if (rdr.curr() == '*' && rdr.next() == '/') { - level -= 1; - if (level == 0) { - rdr.bump(); rdr.bump(); - vec::push[str](lines, val); - break; - } - } else if (rdr.curr() == '/' && rdr.next() == '*') { - level += 1; - } - str::push_char(val, rdr.curr()); - rdr.bump(); + s1 = ""; } + } else { + s1 = s; + } + log "pushing line: " + s1; + lines += [s1]; +} + +fn read_block_comment(&reader rdr, + bool code_to_the_left) -> cmnt { + log ">>> block comment"; + auto p = rdr.get_chpos(); + let vec[str] lines = []; + let uint col = rdr.get_col(); + rdr.bump(); + rdr.bump(); + auto curr_line = "/*"; + let int level = 1; + while (level > 0) { + log #fmt("=== block comment level %d", level); if (rdr.is_eof()) { - rdr.err("Unexpected end of file in block comment"); + rdr.err("unterminated block comment"); fail; } + if (rdr.curr() == '\n') { + trim_whitespace_prefix_and_push_line(lines, curr_line, col); + curr_line = ""; + rdr.bump(); + } else { + str::push_char(curr_line, rdr.curr()); + if (rdr.curr() == '/' && rdr.next() == '*') { + rdr.bump(); + rdr.bump(); + curr_line += "*"; + level += 1; + } else { + if (rdr.curr() == '*' && rdr.next() == '/') { + rdr.bump(); + rdr.bump(); + curr_line += "/"; + level -= 1; + } else { + rdr.bump(); + } + } + } } - ret rec(val=cmnt_block(lines), - pos=p, - space_after=consume_whitespace(rdr) > 1u); + if (str::byte_len(curr_line) != 0u) { + trim_whitespace_prefix_and_push_line(lines, curr_line, col); + } + + auto style = if (code_to_the_left) { trailing } else { isolated }; + consume_non_eol_whitespace(rdr); + if (!rdr.is_eof() && + rdr.curr() != '\n' && + vec::len(lines) == 1u) { + style = mixed; + } + log "<<< block comment"; + ret rec(style = style, lines = lines, pos=p); +} + +fn peeking_at_comment(&reader rdr) -> bool { + ret (rdr.curr() == '/' && rdr.next() == '/') || + (rdr.curr() == '/' && rdr.next() == '*'); +} + +fn consume_comment(&reader rdr, bool code_to_the_left, + &mutable vec[cmnt] comments) { + log ">>> consume comment"; + if (rdr.curr() == '/' && rdr.next() == '/') { + vec::push[cmnt](comments, + read_line_comments(rdr, code_to_the_left)); + } else if (rdr.curr() == '/' && rdr.next() == '*') { + vec::push[cmnt](comments, + read_block_comment(rdr, code_to_the_left)); + } else { fail; } + log "<<< consume comment"; } fn gather_comments(session sess, str path) -> vec[cmnt] { @@ -793,17 +893,22 @@ fn gather_comments(session sess, str path) -> vec[cmnt] { let vec[cmnt] comments = []; while (!rdr.is_eof()) { while (true) { - consume_whitespace(rdr); - if (rdr.curr() == '/' && rdr.next() == '/') { - vec::push[cmnt](comments, read_line_comment(rdr)); - } else if (rdr.curr() == '/' && rdr.next() == '*') { - vec::push[cmnt](comments, read_block_comment(rdr)); - } else { break; } + auto code_to_the_left = true; + consume_non_eol_whitespace(rdr); + if (rdr.next() == '\n') { + code_to_the_left = false; + consume_whitespace(rdr); + } + while (peeking_at_comment(rdr)) { + consume_comment(rdr, code_to_the_left, comments); + consume_whitespace(rdr); + } + break; } next_token(rdr); } ret comments; -} + } // diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs index e48b1f4c52e6b..803d75250ac56 100644 --- a/src/comp/front/parser.rs +++ b/src/comp/front/parser.rs @@ -164,7 +164,7 @@ fn new_parser(session::session sess, auto itr = @interner::mk[str](str::hash, str::eq); auto rdr = lexer::new_reader(sess, srdr, filemap, itr); // Make sure npos points at first actual token: - lexer::consume_any_whitespace(rdr); + lexer::consume_whitespace_and_comments(rdr); auto npos = rdr.get_chpos(); ret stdio_parser(sess, env, ftype, lexer::next_token(rdr), npos, npos, npos, initial_def._1, UNRESTRICTED, diff --git a/src/comp/pretty/pp.rs b/src/comp/pretty/pp.rs index 961cc68d17b4f..98b002a904d9e 100644 --- a/src/comp/pretty/pp.rs +++ b/src/comp/pretty/pp.rs @@ -34,6 +34,25 @@ import std::str; * I also inverted the indentation arithmetic used in the print stack, since * the Mesa implementation (somewhat randomly) stores the offset on the print * stack in terms of margin-col rather than col itself. I store col. + * + * I also implemented a small change in the STRING token, in that I store an + * explicit length for the string. For most tokens this is just the length of + * the accompanying string. But it's necessary to permit it to differ, for + * encoding things that are supposed to "go on their own line" -- certain + * classes of comment and blank-line -- where relying on adjacent + * hardbreak-like BREAK tokens with long blankness indication doesn't actually + * work. To see why, consider when there is a "thing that should be on its own + * line" between two long blocks, say functions. If you put a hardbreak after + * each function (or before each) and the breaking algorithm decides to break + * there anyways (because the functions themselves are long) you wind up with + * extra blank lines. If you don't put hardbreaks you can wind up with the + * "thing which should be on its own line" not getting its own line in the + * rare case of "really small functions" or such. This re-occurs with comments + * and explicit blank lines. So in those cases we use a string with a payload + * we want isolated to a line and an explicit length that's huge, surrounded + * by two zero-length breaks. The algorithm will try its best to fit it on a + * line (which it can't) and so naturally place the content on its own line to + * avoid combining it with other lines and making matters even worse. */ tag breaks { consistent; inconsistent; } @@ -41,7 +60,7 @@ type break_t = rec(int offset, int blank_space); type begin_t = rec(int offset, breaks breaks); tag token { - STRING(str); + STRING(str,int); BREAK(break_t); BEGIN(begin_t); END; @@ -51,7 +70,7 @@ tag token { fn tok_str(token t) -> str { alt (t) { - case (STRING(?s)) { ret "STR(" + s + ")"; } + case (STRING(?s, ?len)) { ret #fmt("STR(%s,%d)", s, len); } case (BREAK(_)) { ret "BREAK"; } case (BEGIN(_)) { ret "BEGIN"; } case (END) { ret "END"; } @@ -279,8 +298,7 @@ obj printer(io::writer out, right_total += b.blank_space; } - case (STRING(?s)) { - auto len = str::char_len(s) as int; + case (STRING(?s, ?len)) { if (scan_stack_empty) { log #fmt("pp STRING/print [%u,%u]", left, right); self.print(t, len); @@ -370,10 +388,9 @@ obj printer(io::writer out, case (BREAK(?b)) { left_total += b.blank_space; } - case (STRING(?s)) { - // I think? paper says '1' here but 1 and L look same in - // it. - left_total += L; + case (STRING(_, ?len)) { + assert len == L; + left_total += len; } case (_) {} } @@ -486,11 +503,11 @@ obj printer(io::writer out, } } - case (STRING(?s)) { + case (STRING(?s, ?len)) { log "print STRING"; - assert L as uint == str::char_len(s); + assert L == len; // assert L <= space; - space -= L; + space -= len; out.write_str(s); } @@ -527,8 +544,14 @@ fn break_offset(printer p, uint n, int off) { fn end(printer p) { p.pretty_print(END); } fn eof(printer p) { p.pretty_print(EOF); } -fn wrd(printer p, str wrd) { p.pretty_print(STRING(wrd)); } +fn word(printer p, str wrd) { + p.pretty_print(STRING(wrd, str::char_len(wrd) as int)); +} +fn word_and_eol(printer p, str wrd) { + p.pretty_print(STRING(wrd, 0xffff)); +} fn spaces(printer p, uint n) { break_offset(p, n, 0); } +fn zerobreak(printer p) { spaces(p, 0u); } fn space(printer p) { spaces(p, 1u); } fn hardbreak(printer p) { spaces(p, 0xffffu); } diff --git a/src/comp/pretty/pprust.rs b/src/comp/pretty/pprust.rs index a39e42be605aa..e9275e4b4bfe8 100644 --- a/src/comp/pretty/pprust.rs +++ b/src/comp/pretty/pprust.rs @@ -14,8 +14,10 @@ import pp::break_offset; import pp::box; import pp::cbox; import pp::ibox; -import pp::wrd; +import pp::word; +import pp::word_and_eol; import pp::space; +import pp::zerobreak; import pp::hardbreak; import pp::breaks; import pp::consistent; @@ -82,42 +84,42 @@ fn pat_to_str(&@ast::pat p) -> str { ret writer.get_str(); } -fn word_nbsp(ps s, str word) { - wrd(s.s, word); - wrd(s.s, " "); +fn word_nbsp(ps s, str w) { + word(s.s, w); + word(s.s, " "); } -fn word_space(ps s, str word) { - wrd(s.s, word); +fn word_space(ps s, str w) { + word(s.s, w); space(s.s); } fn popen(ps s) { - wrd(s.s, "("); + word(s.s, "("); } fn pclose(ps s) { - wrd(s.s, ")"); + word(s.s, ")"); } -fn head(ps s, str word) { +fn head(ps s, str w) { // outer-box is consistent cbox(s.s, indent_unit); // head-box is inconsistent - ibox(s.s, str::char_len(word) + 1u); + ibox(s.s, str::char_len(w) + 1u); // keyword that starts the head - word_nbsp(s, word); + word_nbsp(s, w); } fn bopen(ps s) { - wrd(s.s, "{"); + word(s.s, "{"); end(s.s); // close the head-box } fn bclose(ps s, common::span span) { maybe_print_comment(s, span.hi); break_offset(s.s, 1u, -(indent_unit as int)); - wrd(s.s, "}"); + word(s.s, "}"); end(s.s); // close the outer-box } @@ -141,7 +143,7 @@ fn commasep_cmnt[IN](ps s, breaks b, vec[IN] elts, fn(ps, &IN) op, op(s, elt); i += 1u; if (i < len) { - wrd(s.s, ","); + word(s.s, ","); if (!maybe_print_line_comment(s, get_span(elt))) {space(s.s);} } } @@ -172,41 +174,41 @@ fn print_type(ps s, &@ast::ty ty) { maybe_print_comment(s, ty.span.lo); ibox(s.s, 0u); alt (ty.node) { - case (ast::ty_nil) {wrd(s.s, "()");} - case (ast::ty_bool) {wrd(s.s, "bool");} - case (ast::ty_bot) {wrd(s.s, "_|_");} - case (ast::ty_int) {wrd(s.s, "int");} - case (ast::ty_uint) {wrd(s.s, "uint");} - case (ast::ty_float) {wrd(s.s, "float");} - case (ast::ty_machine(?tm)) {wrd(s.s, common::ty_mach_to_str(tm));} - case (ast::ty_char) {wrd(s.s, "char");} - case (ast::ty_str) {wrd(s.s, "str");} - case (ast::ty_box(?mt)) {wrd(s.s, "@"); print_mt(s, mt);} + case (ast::ty_nil) {word(s.s, "()");} + case (ast::ty_bool) {word(s.s, "bool");} + case (ast::ty_bot) {word(s.s, "_|_");} + case (ast::ty_int) {word(s.s, "int");} + case (ast::ty_uint) {word(s.s, "uint");} + case (ast::ty_float) {word(s.s, "float");} + case (ast::ty_machine(?tm)) {word(s.s, common::ty_mach_to_str(tm));} + case (ast::ty_char) {word(s.s, "char");} + case (ast::ty_str) {word(s.s, "str");} + case (ast::ty_box(?mt)) {word(s.s, "@"); print_mt(s, mt);} case (ast::ty_vec(?mt)) { - wrd(s.s, "vec["); print_mt(s, mt); wrd(s.s, "]"); + word(s.s, "vec["); print_mt(s, mt); word(s.s, "]"); } case (ast::ty_port(?t)) { - wrd(s.s, "port["); print_type(s, t); wrd(s.s, "]"); + word(s.s, "port["); print_type(s, t); word(s.s, "]"); } case (ast::ty_chan(?t)) { - wrd(s.s, "chan["); print_type(s, t); wrd(s.s, "]"); + word(s.s, "chan["); print_type(s, t); word(s.s, "]"); } - case (ast::ty_type) {wrd(s.s, "type");} + case (ast::ty_type) {word(s.s, "type");} case (ast::ty_tup(?elts)) { - wrd(s.s, "tup"); + word(s.s, "tup"); popen(s); auto f = print_mt; commasep[ast::mt](s, inconsistent, elts, f); pclose(s); } case (ast::ty_rec(?fields)) { - wrd(s.s, "rec"); + word(s.s, "rec"); popen(s); fn print_field(ps s, &ast::ty_field f) { cbox(s.s, indent_unit); print_mt(s, f.mt); space(s.s); - wrd(s.s, f.ident); + word(s.s, f.ident); end(s.s); } fn get_span(&ast::ty_field f) -> common::span { @@ -227,7 +229,7 @@ fn print_type(ps s, &@ast::ty ty) { cbox(s.s, indent_unit); print_ty_fn(s, m.proto, option::some[str](m.ident), m.inputs, m.output, m.cf); - wrd(s.s, ";"); + word(s.s, ";"); end(s.s); } bclose(s, ty.span); @@ -255,12 +257,12 @@ fn print_item(ps s, @ast::item item) { end(s.s); // end the head-ibox word_space(s, "="); print_expr(s, expr); - wrd(s.s, ";"); + word(s.s, ";"); end(s.s); // end the outer cbox } case (ast::item_fn(?name,?_fn,?typarams,_,_)) { print_fn(s, _fn.decl, name, typarams); - wrd(s.s, " "); + word(s.s, " "); print_block(s, _fn.body); } case (ast::item_mod(?id,?_mod,_)) { @@ -287,7 +289,7 @@ fn print_item(ps s, @ast::item item) { alt (item.node) { case (ast::native_item_ty(?id,_)) { word_nbsp(s, "type"); - wrd(s.s, id); + word(s.s, id); } case (ast::native_item_fn(?id,?lname,?decl, ?typarams,_,_)) { @@ -301,7 +303,7 @@ fn print_item(ps s, @ast::item item) { } } } - wrd(s.s, ";"); + word(s.s, ";"); end(s.s); } bclose(s, item.span); @@ -310,26 +312,26 @@ fn print_item(ps s, @ast::item item) { ibox(s.s, indent_unit); ibox(s.s, 0u); word_nbsp(s, "type"); - wrd(s.s, id); + word(s.s, id); print_type_params(s, params); end(s.s); // end the inner ibox space(s.s); word_space(s, "="); print_type(s, ty); - wrd(s.s, ";"); + word(s.s, ";"); end(s.s); // end the outer ibox break_offset(s.s, 0u, 0); } case (ast::item_tag(?id,?variants,?params,_,_)) { head(s, "tag"); - wrd(s.s, id); + word(s.s, id); print_type_params(s, params); space(s.s); bopen(s); for (ast::variant v in variants) { space(s.s); maybe_print_comment(s, v.span.lo); - wrd(s.s, v.node.name); + word(s.s, v.node.name); if (vec::len[ast::variant_arg](v.node.args) > 0u) { popen(s); fn print_variant_arg(ps s, &ast::variant_arg arg) { @@ -339,21 +341,21 @@ fn print_item(ps s, @ast::item item) { commasep[ast::variant_arg](s, consistent, v.node.args, f); pclose(s); } - wrd(s.s, ";"); + word(s.s, ";"); maybe_print_line_comment(s, v.span); } bclose(s, item.span); } case (ast::item_obj(?id,?_obj,?params,_,_)) { head(s, "obj"); - wrd(s.s, id); + word(s.s, id); print_type_params(s, params); popen(s); fn print_field(ps s, &ast::obj_field field) { ibox(s.s, indent_unit); print_type(s, field.ty); space(s.s); - wrd(s.s, field.ident); + word(s.s, field.ident); end(s.s); } fn get_span(&ast::obj_field f) -> common::span {ret f.ty.span;} @@ -368,7 +370,7 @@ fn print_item(ps s, @ast::item item) { hardbreak(s.s); maybe_print_comment(s, meth.span.lo); print_fn(s, meth.node.meth.decl, meth.node.ident, typarams); - wrd(s.s, " "); + word(s.s, " "); print_block(s, meth.node.meth.body); } alt (_obj.dtor) { @@ -398,7 +400,7 @@ fn print_block(ps s, ast::block blk) { print_expr(s, expr); } } - if (front::parser::stmt_ends_with_semi(st)) {wrd(s.s, ";");} + if (front::parser::stmt_ends_with_semi(st)) {word(s.s, ";");} maybe_print_line_comment(s, st.span); } alt (blk.node.expr) { @@ -417,30 +419,30 @@ fn print_literal(ps s, @ast::lit lit) { alt (lit.node) { case (ast::lit_str(?st)) {print_string(s, st);} case (ast::lit_char(?ch)) { - wrd(s.s, "'" + escape_str(str::from_bytes([ch as u8]), '\'') + word(s.s, "'" + escape_str(str::from_bytes([ch as u8]), '\'') + "'"); } case (ast::lit_int(?val)) { - wrd(s.s, common::istr(val)); + word(s.s, common::istr(val)); } case (ast::lit_uint(?val)) { // FIXME clipping? uistr? - wrd(s.s, common::istr(val as int) + "u"); + word(s.s, common::istr(val as int) + "u"); } case (ast::lit_float(?fstr)) { - wrd(s.s, fstr); + word(s.s, fstr); } case (ast::lit_mach_int(?mach,?val)) { - wrd(s.s, common::istr(val as int)); - wrd(s.s, common::ty_mach_to_str(mach)); + word(s.s, common::istr(val as int)); + word(s.s, common::ty_mach_to_str(mach)); } case (ast::lit_mach_float(?mach,?val)) { // val is already a str - wrd(s.s, val); - wrd(s.s, common::ty_mach_to_str(mach)); + word(s.s, val); + word(s.s, common::ty_mach_to_str(mach)); } - case (ast::lit_nil) {wrd(s.s, "()");} + case (ast::lit_nil) {word(s.s, "()");} case (ast::lit_bool(?val)) { - if (val) {wrd(s.s, "true");} else {wrd(s.s, "false");} + if (val) {word(s.s, "true");} else {word(s.s, "false");} } } } @@ -460,9 +462,9 @@ fn print_expr(ps s, &@ast::expr expr) { word_nbsp(s, "mutable"); } ibox(s.s, indent_unit); - wrd(s.s, "["); + word(s.s, "["); commasep_exprs(s, inconsistent, exprs); - wrd(s.s, "]"); + word(s.s, "]"); end(s.s); } case (ast::expr_tup(?exprs,_)) { @@ -473,7 +475,7 @@ fn print_expr(ps s, &@ast::expr expr) { end(s.s); } fn get_span(&ast::elt elt) -> common::span {ret elt.expr.span;} - wrd(s.s, "tup"); + word(s.s, "tup"); popen(s); auto f = printElt; auto gs = get_span; @@ -484,15 +486,15 @@ fn print_expr(ps s, &@ast::expr expr) { fn print_field(ps s, &ast::field field) { ibox(s.s, indent_unit); if (field.mut == ast::mut) {word_nbsp(s, "mutable");} - wrd(s.s, field.ident); - wrd(s.s, "="); + word(s.s, field.ident); + word(s.s, "="); print_expr(s, field.expr); end(s.s); } fn get_span(&ast::field field) -> common::span { ret field.expr.span; } - wrd(s.s, "rec"); + word(s.s, "rec"); popen(s); auto f = print_field; auto gs = get_span; @@ -516,7 +518,7 @@ fn print_expr(ps s, &@ast::expr expr) { pclose(s); } case (ast::expr_self_method(?ident,_)) { - wrd(s.s, "self."); + word(s.s, "self."); print_ident(s, ident); } case (ast::expr_bind(?func,?args,_)) { @@ -525,7 +527,7 @@ fn print_expr(ps s, &@ast::expr expr) { case (option::some[@ast::expr](?expr)) { print_expr(s, expr); } - case (_) {wrd(s.s, "_");} + case (_) {word(s.s, "_");} } } word_nbsp(s, "bind"); @@ -550,7 +552,7 @@ fn print_expr(ps s, &@ast::expr expr) { print_maybe_parens(s, rhs, prec + 1); } case (ast::expr_unary(?op,?expr,_)) { - wrd(s.s, ast::unop_to_str(op)); + word(s.s, ast::unop_to_str(op)); print_expr(s, expr); } case (ast::expr_lit(?lit,_)) { @@ -576,7 +578,7 @@ fn print_expr(ps s, &@ast::expr expr) { // wrong column. cbox(s.s, indent_unit-1u); ibox(s.s, 0u); - wrd(s.s, " else "); + word(s.s, " else "); alt (_else.node) { case (ast::expr_block(?b, _)) { print_block(s, block); @@ -658,7 +660,7 @@ fn print_expr(ps s, &@ast::expr expr) { case (ast::expr_assign_op(?op,?lhs,?rhs,_)) { print_expr(s, lhs); space(s.s); - wrd(s.s, ast::binop_to_str(op)); + word(s.s, ast::binop_to_str(op)); word_space(s, "="); print_expr(s, rhs); } @@ -676,12 +678,12 @@ fn print_expr(ps s, &@ast::expr expr) { } case (ast::expr_field(?expr,?id,_)) { print_expr(s, expr); - wrd(s.s, "."); - wrd(s.s, id); + word(s.s, "."); + word(s.s, id); } case (ast::expr_index(?expr,?index,_)) { print_expr(s, expr); - wrd(s.s, "."); + word(s.s, "."); popen(s); print_expr(s, index); pclose(s); @@ -690,29 +692,29 @@ fn print_expr(ps s, &@ast::expr expr) { print_path(s, path); } case (ast::expr_fail(_)) { - wrd(s.s, "fail"); + word(s.s, "fail"); } case (ast::expr_break(_)) { - wrd(s.s, "break"); + word(s.s, "break"); } case (ast::expr_cont(_)) { - wrd(s.s, "cont"); + word(s.s, "cont"); } case (ast::expr_ret(?result,_)) { - wrd(s.s, "ret"); + word(s.s, "ret"); alt (result) { case (option::some[@ast::expr](?expr)) { - wrd(s.s, " "); + word(s.s, " "); print_expr(s, expr); } case (_) {} } } case (ast::expr_put(?result,_)) { - wrd(s.s, "put"); + word(s.s, "put"); alt (result) { case (option::some[@ast::expr](?expr)) { - wrd(s.s, " "); + word(s.s, " "); print_expr(s, expr); } case (_) {} @@ -742,7 +744,7 @@ fn print_expr(ps s, &@ast::expr expr) { pclose(s); } case (ast::expr_ext(?path, ?args, ?body, _, _)) { - wrd(s.s, "#"); + word(s.s, "#"); print_path(s, path); if (vec::len[@ast::expr](args) > 0u) { popen(s); @@ -752,19 +754,19 @@ fn print_expr(ps s, &@ast::expr expr) { // FIXME: extension 'body' } case (ast::expr_port(_)) { - wrd(s.s, "port"); + word(s.s, "port"); popen(s); pclose(s); } case (ast::expr_chan(?expr, _)) { - wrd(s.s, "chan"); + word(s.s, "chan"); popen(s); print_expr(s, expr); pclose(s); } case (ast::expr_anon_obj(_,_,_,_)) { - wrd(s.s, "anon obj"); + word(s.s, "anon obj"); // TODO: nicer pretty-printing of anon objs } } @@ -774,9 +776,9 @@ fn print_expr(ps s, &@ast::expr expr) { case (mo_untyped) { /* no-op */ } case (mo_typed(?tcx)) { space(s.s); - wrd(s.s, "as"); + word(s.s, "as"); space(s.s); - wrd(s.s, ty::ty_to_str(tcx, ty::expr_ty(tcx, expr))); + word(s.s, ty::ty_to_str(tcx, ty::expr_ty(tcx, expr))); pclose(s); } } @@ -810,7 +812,7 @@ fn print_decl(ps s, @ast::decl decl) { } } } - wrd(s.s, loc.ident); + word(s.s, loc.ident); alt (loc.init) { case (option::some[ast::initializer](?init)) { space(s.s); @@ -835,7 +837,7 @@ fn print_decl(ps s, @ast::decl decl) { } fn print_ident(ps s, ast::ident ident) { - wrd(s.s, ident); + word(s.s, ident); } fn print_for_decl(ps s, @ast::decl decl) { @@ -843,7 +845,7 @@ fn print_for_decl(ps s, @ast::decl decl) { case (ast::decl_local(?loc)) { print_type(s, option::get[@ast::ty](loc.ty)); space(s.s); - wrd(s.s, loc.ident); + word(s.s, loc.ident); } } } @@ -853,22 +855,22 @@ fn print_path(ps s, ast::path path) { auto first = true; for (str id in path.node.idents) { if (first) {first = false;} - else {wrd(s.s, "::");} - wrd(s.s, id); + else {word(s.s, "::");} + word(s.s, id); } if (vec::len[@ast::ty](path.node.types) > 0u) { - wrd(s.s, "["); + word(s.s, "["); auto f = print_type; commasep[@ast::ty](s, inconsistent, path.node.types, f); - wrd(s.s, "]"); + word(s.s, "]"); } } fn print_pat(ps s, &@ast::pat pat) { maybe_print_comment(s, pat.span.lo); alt (pat.node) { - case (ast::pat_wild(_)) {wrd(s.s, "_");} - case (ast::pat_bind(?id,_,_)) {wrd(s.s, "?" + id);} + case (ast::pat_wild(_)) {word(s.s, "_");} + case (ast::pat_bind(?id,_,_)) {word(s.s, "?" + id);} case (ast::pat_lit(?lit,_)) {print_literal(s, lit);} case (ast::pat_tag(?path,?args,_)) { print_path(s, path); @@ -892,15 +894,15 @@ fn print_fn(ps s, ast::fn_decl decl, str name, head(s, "pred"); } } - wrd(s.s, name); + word(s.s, name); print_type_params(s, typarams); popen(s); fn print_arg(ps s, &ast::arg x) { ibox(s.s, indent_unit); - if (x.mode == ast::alias) {wrd(s.s, "&");} + if (x.mode == ast::alias) {word(s.s, "&");} print_type(s, x.ty); space(s.s); - wrd(s.s, x.ident); + word(s.s, x.ident); end(s.s); } auto f = print_arg; @@ -916,13 +918,13 @@ fn print_fn(ps s, ast::fn_decl decl, str name, fn print_type_params(ps s, vec[ast::ty_param] params) { if (vec::len[ast::ty_param](params) > 0u) { - wrd(s.s, "["); + word(s.s, "["); fn printParam(ps s, &ast::ty_param param) { - wrd(s.s, param); + word(s.s, param); } auto f = printParam; commasep[ast::ty_param](s, inconsistent, params, f); - wrd(s.s, "]"); + word(s.s, "]"); } } @@ -932,7 +934,7 @@ fn print_view_item(ps s, @ast::view_item item) { alt (item.node) { case (ast::view_item_use(?id,?mta,_,_)) { head(s, "use"); - wrd(s.s, id); + word(s.s, id); if (vec::len[@ast::meta_item](mta) > 0u) { popen(s); fn print_meta(ps s, &@ast::meta_item item) { @@ -956,16 +958,16 @@ fn print_view_item(ps s, @ast::view_item item) { auto first = true; for (str elt in ids) { if (first) {first = false;} - else {wrd(s.s, "::");} - wrd(s.s, elt); + else {word(s.s, "::");} + word(s.s, elt); } } case (ast::view_item_export(?id)) { head(s, "export"); - wrd(s.s, id); + word(s.s, id); } } - wrd(s.s, ";"); + word(s.s, ";"); end(s.s); // end inner head-block end(s.s); // end outer head-block } @@ -1028,21 +1030,21 @@ fn print_mt(ps s, &ast::mt mt) { } fn print_string(ps s, str st) { - wrd(s.s, "\""); wrd(s.s, escape_str(st, '"')); wrd(s.s, "\""); + word(s.s, "\""); word(s.s, escape_str(st, '"')); word(s.s, "\""); } fn print_ty_fn(ps s, ast::proto proto, option::t[str] id, vec[ast::ty_arg] inputs, @ast::ty output, ast::controlflow cf) { - if (proto == ast::proto_fn) {wrd(s.s, "fn");} - else {wrd(s.s, "iter");} + if (proto == ast::proto_fn) {word(s.s, "fn");} + else {word(s.s, "iter");} alt (id) { - case (option::some[str](?id)) {space(s.s); wrd(s.s, id);} + case (option::some[str](?id)) {space(s.s); word(s.s, id);} case (_) {} } popen(s); fn print_arg(ps s, &ast::ty_arg input) { - if (input.mode == ast::alias) {wrd(s.s, "&");} + if (input.mode == ast::alias) {word(s.s, "&");} print_type(s, input.ty); } auto f = print_arg; @@ -1086,7 +1088,7 @@ fn maybe_print_comment(ps s, uint pos) { first = false; break_offset(s.s, 0u, 0); } - print_comment(s, cmnt.val); + print_comment(s, cmnt); s.cur_cmnt += 1u; } else { break; } } @@ -1099,8 +1101,8 @@ fn maybe_print_line_comment(ps s, common::span span) -> bool { alt (next_comment(s)) { case (option::some[lexer::cmnt](?cmnt)) { if (span.hi + 4u >= cmnt.pos) { - wrd(s.s, " "); - print_comment(s, cmnt.val); + word(s.s, " "); + print_comment(s, cmnt); s.cur_cmnt += 1u; ret true; } @@ -1111,15 +1113,10 @@ fn maybe_print_line_comment(ps s, common::span span) -> bool { } fn print_remaining_comments(ps s) { - auto first = true; while (true) { alt (next_comment(s)) { case (option::some[lexer::cmnt](?cmnt)) { - if (first) { - first = false; - break_offset(s.s, 0u, 0); - } - print_comment(s, cmnt.val); + print_comment(s, cmnt); s.cur_cmnt += 1u; } case (_) {break;} @@ -1127,27 +1124,30 @@ fn print_remaining_comments(ps s) { } } -fn print_comment(ps s, lexer::cmnt_ cmnt) { - alt (cmnt) { - case (lexer::cmnt_line(?val)) { - wrd(s.s, "// " + val); - hardbreak(s.s); - } - case (lexer::cmnt_block(?lines)) { - cbox(s.s, 1u); - wrd(s.s, "/*"); - auto first = true; - for (str ln in lines) { - if (first) { - first = false; - } else { - hardbreak(s.s); - } - wrd(s.s, ln); +fn print_comment(ps s, lexer::cmnt cmnt) { + alt (cmnt.style) { + case (lexer::isolated) { + cbox(s.s, 0u); + for (str line in cmnt.lines) { + zerobreak(s.s); + word_and_eol(s.s, line); } - wrd(s.s, "*/"); + zerobreak(s.s); end(s.s); - hardbreak(s.s); + } + case (lexer::trailing) { + cbox(s.s, 0u); + for (str line in cmnt.lines) { + word_and_eol(s.s, line); + zerobreak(s.s); + } + end(s.s); + } + case (lexer::mixed) { + assert vec::len(cmnt.lines) == 1u; + zerobreak(s.s); + word(s.s, cmnt.lines.(0)); + zerobreak(s.s); } } }