Skip to content

Commit 0624f9d

Browse files
marijnhgraydon
authored andcommitted
Add a pretty-printer
Adds a -pp option to the compiler which will cause it to simply pretty-print the given file.
1 parent 8047957 commit 0624f9d

File tree

9 files changed

+1013
-25
lines changed

9 files changed

+1013
-25
lines changed

src/comp/driver/rustc.rs

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,14 @@ impure fn compile_input(session.session sess,
6161
trans.trans_crate(sess, crate, output, shared);
6262
}
6363

64+
impure fn pretty_print_input(session.session sess,
65+
eval.env env,
66+
str input) {
67+
auto p = front.parser.new_parser(sess, env, 0, input);
68+
auto crate = front.parser.parse_crate_from_source_file(p);
69+
pretty.pprust.print_ast(crate.node.module);
70+
}
71+
6472
fn warn_wrong_compiler() {
6573
log "This is the rust 'self-hosted' compiler.";
6674
log "The one written in rust.";
@@ -75,6 +83,7 @@ fn usage(session.session sess, str argv0) {
7583
log " -o <filename> write output to <filename>";
7684
log " -nowarn suppress wrong-compiler warning";
7785
log " -shared compile a shared-library crate";
86+
log " -pp pretty-print the input instead of compiling";
7887
log " -h display this message";
7988
log "";
8089
log "";
@@ -101,6 +110,7 @@ impure fn main(vec[str] args) {
101110
let option.t[str] output_file = none[str];
102111
let bool do_warn = true;
103112
let bool shared = false;
113+
let bool pretty = false;
104114

105115
auto i = 1u;
106116
auto len = _vec.len[str](args);
@@ -113,6 +123,8 @@ impure fn main(vec[str] args) {
113123
do_warn = false;
114124
} else if (_str.eq(arg, "-shared")) {
115125
shared = true;
126+
} else if (_str.eq(arg, "-pp")) {
127+
pretty = true;
116128
} else if (_str.eq(arg, "-o")) {
117129
if (i+1u < len) {
118130
output_file = some(args.(i+1u));
@@ -153,24 +165,27 @@ impure fn main(vec[str] args) {
153165
case (some[str](?ifile)) {
154166

155167
auto env = default_environment(sess, args.(0), ifile);
156-
157-
alt (output_file) {
158-
case (none[str]) {
159-
let vec[str] parts = _str.split(ifile, '.' as u8);
160-
parts = _vec.pop[str](parts);
161-
parts += ".bc";
162-
auto ofile = _str.concat(parts);
163-
compile_input(sess, env, ifile, ofile, shared);
164-
}
165-
case (some[str](?ofile)) {
166-
compile_input(sess, env, ifile, ofile, shared);
168+
if (pretty) {
169+
pretty_print_input(sess, env, ifile);
170+
}
171+
else {
172+
alt (output_file) {
173+
case (none[str]) {
174+
let vec[str] parts = _str.split(ifile, '.' as u8);
175+
parts = _vec.pop[str](parts);
176+
parts += ".bc";
177+
auto ofile = _str.concat(parts);
178+
compile_input(sess, env, ifile, ofile, shared);
179+
}
180+
case (some[str](?ofile)) {
181+
compile_input(sess, env, ifile, ofile, shared);
182+
}
167183
}
168184
}
169185
}
170186
}
171187
}
172188

173-
174189
// Local Variables:
175190
// mode: rust
176191
// fill-column: 78;

src/comp/front/ast.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,31 @@ tag binop {
122122
gt;
123123
}
124124

125+
fn binop_to_str(binop op) -> str {
126+
alt (op) {
127+
case (add) {ret "+";}
128+
case (sub) {ret "-";}
129+
case (mul) {ret "*";}
130+
case (div) {ret "/";}
131+
case (rem) {ret "%";}
132+
case (and) {ret "&&";}
133+
case (or) {ret "||";}
134+
case (bitxor) {ret "^";}
135+
case (bitand) {ret "&";}
136+
case (bitor) {ret "|";}
137+
case (lsl) {ret "<<";}
138+
case (lsr) {ret ">>";}
139+
case (asr) {ret ">>>";}
140+
case (eq) {ret "==";}
141+
case (lt) {ret "<";}
142+
case (le) {ret "<=";}
143+
case (ne) {ret "!=";}
144+
case (ge) {ret ">=";}
145+
case (gt) {ret ">";}
146+
}
147+
}
148+
149+
125150
tag unop {
126151
box;
127152
deref;
@@ -131,6 +156,17 @@ tag unop {
131156
_mutable;
132157
}
133158
159+
fn unop_to_str(unop op) -> str {
160+
alt (op) {
161+
case (box) {ret "@";}
162+
case (deref) {ret "*";}
163+
case (bitnot) {ret "~";}
164+
case (not) {ret "!";}
165+
case (neg) {ret "-";}
166+
case (_mutable) {ret "mutable";}
167+
}
168+
}
169+
134170
tag mode {
135171
val;
136172
alias;

src/comp/front/parser.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -983,6 +983,7 @@ impure fn parse_prefix_expr(parser p) -> @ast.expr {
983983

984984
type op_spec = rec(token.token tok, ast.binop op, int prec);
985985

986+
// FIXME make this a const, don't store it in parser state
986987
fn prec_table() -> vec[op_spec] {
987988
ret vec(rec(tok=token.BINOP(token.STAR), op=ast.mul, prec=11),
988989
rec(tok=token.BINOP(token.SLASH), op=ast.div, prec=11),

src/comp/front/pretty.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import std._vec;
55

66
export print_expr;
77

8+
// FIXME this is superseded by ../pretty/pprust.rs. can it be dropped?
9+
810
fn unknown() -> str {
911
ret "<unknown ast node>";
1012
}

src/comp/middle/ty.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,8 @@ fn path_to_str(&ast.path pth) -> str {
169169
ret result;
170170
}
171171

172+
// FIXME use the pretty-printer for this once it has a concept of an
173+
// abstract stream
172174
fn ty_to_str(&@t typ) -> str {
173175

174176
fn fn_input_to_str(&rec(ast.mode mode, @t ty) input) -> str {

src/comp/pretty/pp.rs

Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
import std.io;
2+
import std._vec;
3+
import std._str;
4+
5+
tag boxtype {box_h; box_v; box_hv; box_align;}
6+
tag contexttype {cx_h; cx_v;}
7+
8+
tag token {
9+
brk(uint);
10+
word(str);
11+
cword(str); // closing token
12+
open(boxtype, uint);
13+
close;
14+
}
15+
16+
type context = rec(contexttype tp, uint indent);
17+
18+
type ps = @rec(mutable vec[context] context,
19+
uint width,
20+
mutable vec[token] buffered,
21+
mutable uint scandepth,
22+
mutable uint bufferedcol,
23+
mutable uint col,
24+
mutable bool start_of_line);
25+
26+
fn mkstate(uint width) -> ps {
27+
let vec[context] stack = vec(rec(tp=cx_v, indent=0u));
28+
let vec[token] buff = vec();
29+
ret @rec(mutable context=stack,
30+
width=width,
31+
mutable buffered=buff,
32+
mutable scandepth=0u,
33+
mutable bufferedcol=0u,
34+
mutable col=0u,
35+
mutable start_of_line=true);
36+
}
37+
38+
impure fn push_context(ps p, contexttype tp, uint indent) {
39+
before_print(p, false);
40+
p.context = _vec.push[context](p.context, rec(tp=tp, indent=base_indent(p)
41+
+ indent));
42+
}
43+
44+
impure fn pop_context(ps p) {
45+
p.context = _vec.pop[context](p.context);
46+
}
47+
48+
impure fn add_token(ps p, token tok) {
49+
if (p.scandepth == 0u) {do_token(p, tok);}
50+
else {buffer_token(p, tok);}
51+
}
52+
53+
impure fn buffer_token(ps p, token tok) {
54+
p.buffered += vec(tok);
55+
p.bufferedcol += token_size(tok);
56+
alt (p.buffered.(0)) {
57+
case (brk(_)) {
58+
alt (tok) {
59+
case (brk(_)) {
60+
if (p.scandepth == 1u) {finish_break_scan(p);}
61+
}
62+
case (open(box_h,_)) {p.scandepth += 1u;}
63+
case (open(_,_)) {finish_break_scan(p);}
64+
case (close) {
65+
p.scandepth -= 1u;
66+
if (p.scandepth == 0u) {finish_break_scan(p);}
67+
}
68+
case (_) {}
69+
}
70+
}
71+
case (open(_,_)) {
72+
if (p.bufferedcol > p.width) {finish_block_scan(p, cx_v);}
73+
else {
74+
alt (tok) {
75+
case (open(_,_)) {p.scandepth += 1u;}
76+
case (close) {
77+
p.scandepth -= 1u;
78+
if (p.scandepth == 0u) {finish_block_scan(p, cx_h);}
79+
}
80+
case (_) {}
81+
}
82+
}
83+
}
84+
}
85+
}
86+
87+
impure fn finish_block_scan(ps p, contexttype tp) {
88+
auto indent;
89+
alt (p.buffered.(0)){
90+
case (open(box_hv,?ind)) {
91+
indent = ind;
92+
}
93+
case (open(box_align, _)) {
94+
indent = p.col - base_indent(p);
95+
}
96+
}
97+
p.scandepth = 0u;
98+
push_context(p, tp, indent);
99+
for (token t in _vec.shift[token](p.buffered)) {add_token(p, t);}
100+
}
101+
102+
impure fn finish_break_scan(ps p) {
103+
if (p.bufferedcol > p.width) {
104+
write_str("\n");
105+
p.col = 0u;
106+
}
107+
else {
108+
auto width;
109+
alt (p.buffered.(0)) {case(brk(?w)) {width = w;}}
110+
auto i = 0u;
111+
while (i < width) {write_str(" "); i+=1u;}
112+
p.col += width;
113+
}
114+
p.scandepth = 0u;
115+
for (token t in _vec.shift[token](p.buffered)) {add_token(p, t);}
116+
}
117+
118+
impure fn start_scan(ps p, token tok) {
119+
p.buffered = vec(tok);
120+
p.scandepth = 1u;
121+
p.bufferedcol = p.col;
122+
}
123+
124+
fn cur_context(ps p) -> context {
125+
ret p.context.(_vec.len[context](p.context)-1u);
126+
}
127+
fn base_indent(ps p) -> uint {
128+
auto i = _vec.len[context](p.context);
129+
while (i > 0u) {
130+
i -= 1u;
131+
auto cx = p.context.(i);
132+
if (cx.tp == cx_v) {ret cx.indent;}
133+
}
134+
}
135+
136+
impure fn do_token(ps p, token tok) {
137+
alt (tok) {
138+
case (brk(?sz)) {
139+
alt (cur_context(p).tp) {
140+
case (cx_h) {
141+
before_print(p, false);
142+
start_scan(p, tok);
143+
}
144+
case (cx_v) {
145+
write_str("\n");
146+
p.col = 0u;
147+
p.start_of_line = true;
148+
}
149+
}
150+
}
151+
case (word(?w)) {
152+
before_print(p, false);
153+
write_str(w);
154+
p.col += _str.byte_len(w); // TODO char_len
155+
}
156+
case (cword(?w)) {
157+
before_print(p, true);
158+
write_str(w);
159+
p.col += _str.byte_len(w); // TODO char_len
160+
}
161+
case (open(?tp, ?indent)) {
162+
alt (tp) {
163+
case (box_hv) {start_scan(p, tok);}
164+
case (box_align) {start_scan(p, tok);}
165+
case (box_h) {push_context(p, cx_h, indent);}
166+
case (box_v) {push_context(p, cx_v, indent);}
167+
}
168+
}
169+
case (close) {pop_context(p);}
170+
}
171+
}
172+
173+
impure fn before_print(ps p, bool closing) {
174+
if (p.start_of_line) {
175+
p.start_of_line = false;
176+
auto ind;
177+
if (closing) {ind = base_indent(p);}
178+
else {ind = cur_context(p).indent;}
179+
p.col = ind;
180+
while (ind > 0u) {write_str(" "); ind -= 1u;}
181+
}
182+
}
183+
184+
fn write_str(str s) {
185+
io.writefd(1, _str.bytes(s));
186+
}
187+
188+
fn token_size(token tok) -> uint {
189+
alt (tok) {
190+
case (brk(?sz)) {ret sz;}
191+
case (word(?w)) {ret _str.byte_len(w);}
192+
case (cword(?w)) {ret _str.byte_len(w);}
193+
case (open(_, _)) {ret 0u;} // TODO exception for V blocks?
194+
case (close) {ret 0u;}
195+
}
196+
}
197+
198+
impure fn box(ps p, uint indent) {add_token(p, open(box_hv, indent));}
199+
impure fn abox(ps p) {add_token(p, open(box_align, 0u));}
200+
impure fn vbox(ps p, uint indent) {add_token(p, open(box_v, indent));}
201+
impure fn hbox(ps p, uint indent) {add_token(p, open(box_h, indent));}
202+
impure fn end(ps p) {add_token(p, close);}
203+
impure fn wrd(ps p, str wrd) {add_token(p, word(wrd));}
204+
impure fn cwrd(ps p, str wrd) {add_token(p, cword(wrd));}
205+
impure fn space(ps p) {add_token(p, brk(1u));}
206+
impure fn spaces(ps p, uint n) {add_token(p, brk(n));}
207+
impure fn line(ps p) {add_token(p, brk(0u));}

0 commit comments

Comments
 (0)