aboutsummaryrefslogtreecommitdiff
path: root/src/comp/pretty/pp.rs
diff options
context:
space:
mode:
authorBrian Anderson <[email protected]>2011-03-07 21:21:01 -0500
committerBrian Anderson <[email protected]>2011-03-07 21:21:01 -0500
commit9fc4db6b89213afdf45c02fc2bd2be62b0ddc40c (patch)
tree6c84574116273f91cbe89abd256b9f809adf97de /src/comp/pretty/pp.rs
parentAllow the else part of an expr_if to be either expr_if or expr_block (diff)
parentrustc: Cast the LLVM representations of tag types when constructing boxes. Un... (diff)
downloadrust-9fc4db6b89213afdf45c02fc2bd2be62b0ddc40c.tar.xz
rust-9fc4db6b89213afdf45c02fc2bd2be62b0ddc40c.zip
Merge branch 'master' into recursive-elseif
Conflicts: src/Makefile src/comp/front/ast.rs src/comp/front/parser.rs src/comp/middle/fold.rs src/comp/middle/trans.rs
Diffstat (limited to 'src/comp/pretty/pp.rs')
-rw-r--r--src/comp/pretty/pp.rs207
1 files changed, 207 insertions, 0 deletions
diff --git a/src/comp/pretty/pp.rs b/src/comp/pretty/pp.rs
new file mode 100644
index 00000000..43a9220f
--- /dev/null
+++ b/src/comp/pretty/pp.rs
@@ -0,0 +1,207 @@
+import std.io;
+import std._vec;
+import std._str;
+
+tag boxtype {box_h; box_v; box_hv; box_align;}
+tag contexttype {cx_h; cx_v;}
+
+tag token {
+ brk(uint);
+ word(str);
+ cword(str); // closing token
+ open(boxtype, uint);
+ close;
+}
+
+type context = rec(contexttype tp, uint indent);
+
+type ps = @rec(mutable vec[context] context,
+ uint width,
+ mutable vec[token] buffered,
+ mutable uint scandepth,
+ mutable uint bufferedcol,
+ mutable uint col,
+ mutable bool start_of_line);
+
+fn mkstate(uint width) -> ps {
+ let vec[context] stack = vec(rec(tp=cx_v, indent=0u));
+ let vec[token] buff = vec();
+ ret @rec(mutable context=stack,
+ width=width,
+ mutable buffered=buff,
+ mutable scandepth=0u,
+ mutable bufferedcol=0u,
+ mutable col=0u,
+ mutable start_of_line=true);
+}
+
+impure fn push_context(ps p, contexttype tp, uint indent) {
+ before_print(p, false);
+ p.context = _vec.push[context](p.context, rec(tp=tp, indent=base_indent(p)
+ + indent));
+}
+
+impure fn pop_context(ps p) {
+ p.context = _vec.pop[context](p.context);
+}
+
+impure fn add_token(ps p, token tok) {
+ if (p.scandepth == 0u) {do_token(p, tok);}
+ else {buffer_token(p, tok);}
+}
+
+impure fn buffer_token(ps p, token tok) {
+ p.buffered += vec(tok);
+ p.bufferedcol += token_size(tok);
+ alt (p.buffered.(0)) {
+ case (brk(_)) {
+ alt (tok) {
+ case (brk(_)) {
+ if (p.scandepth == 1u) {finish_break_scan(p);}
+ }
+ case (open(box_h,_)) {p.scandepth += 1u;}
+ case (open(_,_)) {finish_break_scan(p);}
+ case (close) {
+ p.scandepth -= 1u;
+ if (p.scandepth == 0u) {finish_break_scan(p);}
+ }
+ case (_) {}
+ }
+ }
+ case (open(_,_)) {
+ if (p.bufferedcol > p.width) {finish_block_scan(p, cx_v);}
+ else {
+ alt (tok) {
+ case (open(_,_)) {p.scandepth += 1u;}
+ case (close) {
+ p.scandepth -= 1u;
+ if (p.scandepth == 0u) {finish_block_scan(p, cx_h);}
+ }
+ case (_) {}
+ }
+ }
+ }
+ }
+}
+
+impure fn finish_block_scan(ps p, contexttype tp) {
+ auto indent;
+ alt (p.buffered.(0)){
+ case (open(box_hv,?ind)) {
+ indent = ind;
+ }
+ case (open(box_align, _)) {
+ indent = p.col - base_indent(p);
+ }
+ }
+ p.scandepth = 0u;
+ push_context(p, tp, indent);
+ for (token t in _vec.shift[token](p.buffered)) {add_token(p, t);}
+}
+
+impure fn finish_break_scan(ps p) {
+ if (p.bufferedcol > p.width) {
+ write_str("\n");
+ p.col = 0u;
+ }
+ else {
+ auto width;
+ alt (p.buffered.(0)) {case(brk(?w)) {width = w;}}
+ auto i = 0u;
+ while (i < width) {write_str(" "); i+=1u;}
+ p.col += width;
+ }
+ p.scandepth = 0u;
+ for (token t in _vec.shift[token](p.buffered)) {add_token(p, t);}
+}
+
+impure fn start_scan(ps p, token tok) {
+ p.buffered = vec(tok);
+ p.scandepth = 1u;
+ p.bufferedcol = p.col;
+}
+
+fn cur_context(ps p) -> context {
+ ret p.context.(_vec.len[context](p.context)-1u);
+}
+fn base_indent(ps p) -> uint {
+ auto i = _vec.len[context](p.context);
+ while (i > 0u) {
+ i -= 1u;
+ auto cx = p.context.(i);
+ if (cx.tp == cx_v) {ret cx.indent;}
+ }
+}
+
+impure fn do_token(ps p, token tok) {
+ alt (tok) {
+ case (brk(?sz)) {
+ alt (cur_context(p).tp) {
+ case (cx_h) {
+ before_print(p, false);
+ start_scan(p, tok);
+ }
+ case (cx_v) {
+ write_str("\n");
+ p.col = 0u;
+ p.start_of_line = true;
+ }
+ }
+ }
+ case (word(?w)) {
+ before_print(p, false);
+ write_str(w);
+ p.col += _str.byte_len(w); // TODO char_len
+ }
+ case (cword(?w)) {
+ before_print(p, true);
+ write_str(w);
+ p.col += _str.byte_len(w); // TODO char_len
+ }
+ case (open(?tp, ?indent)) {
+ alt (tp) {
+ case (box_hv) {start_scan(p, tok);}
+ case (box_align) {start_scan(p, tok);}
+ case (box_h) {push_context(p, cx_h, indent);}
+ case (box_v) {push_context(p, cx_v, indent);}
+ }
+ }
+ case (close) {pop_context(p);}
+ }
+}
+
+impure fn before_print(ps p, bool closing) {
+ if (p.start_of_line) {
+ p.start_of_line = false;
+ auto ind;
+ if (closing) {ind = base_indent(p);}
+ else {ind = cur_context(p).indent;}
+ p.col = ind;
+ while (ind > 0u) {write_str(" "); ind -= 1u;}
+ }
+}
+
+fn write_str(str s) {
+ io.writefd(1, _str.bytes(s));
+}
+
+fn token_size(token tok) -> uint {
+ alt (tok) {
+ case (brk(?sz)) {ret sz;}
+ case (word(?w)) {ret _str.byte_len(w);}
+ case (cword(?w)) {ret _str.byte_len(w);}
+ case (open(_, _)) {ret 0u;} // TODO exception for V blocks?
+ case (close) {ret 0u;}
+ }
+}
+
+impure fn box(ps p, uint indent) {add_token(p, open(box_hv, indent));}
+impure fn abox(ps p) {add_token(p, open(box_align, 0u));}
+impure fn vbox(ps p, uint indent) {add_token(p, open(box_v, indent));}
+impure fn hbox(ps p, uint indent) {add_token(p, open(box_h, indent));}
+impure fn end(ps p) {add_token(p, close);}
+impure fn wrd(ps p, str wrd) {add_token(p, word(wrd));}
+impure fn cwrd(ps p, str wrd) {add_token(p, cword(wrd));}
+impure fn space(ps p) {add_token(p, brk(1u));}
+impure fn spaces(ps p, uint n) {add_token(p, brk(n));}
+impure fn line(ps p) {add_token(p, brk(0u));}