Skip to content

Commit 4257323

Browse files
committed
Move macro expansion to a separate phase, change macro syntax, and add parse_sess to session.
1 parent 80cf4ec commit 4257323

File tree

21 files changed

+336
-174
lines changed

21 files changed

+336
-174
lines changed

src/comp/driver/rustc.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,10 @@ fn parse_input(session::session sess, &ast::crate_cfg cfg, str input)
8080
-> @ast::crate {
8181
ret if (str::ends_with(input, ".rc")) {
8282
parser::parse_crate_from_crate_file
83-
(input, cfg, sess.get_codemap())
83+
(input, cfg, sess.get_parse_sess())
8484
} else if (str::ends_with(input, ".rs")) {
8585
parser::parse_crate_from_source_file
86-
(input, cfg, sess.get_codemap())
86+
(input, cfg, sess.get_parse_sess())
8787
} else { sess.fatal("unknown input file type: " + input); fail };
8888
}
8989

@@ -110,6 +110,9 @@ fn compile_input(session::session sess, ast::crate_cfg cfg, str input,
110110
crate = time(time_passes, "building test harness",
111111
bind front::test::modify_for_testing(crate));
112112
}
113+
crate = time(time_passes, "expansion",
114+
bind syntax::ext::expand::expand_crate(sess, crate));
115+
113116
auto ast_map = time(time_passes, "ast indexing",
114117
bind middle::ast_map::map_crate(*crate));
115118
time(time_passes, "external crate/lib resolution",
@@ -357,7 +360,8 @@ fn build_session(@session::options sopts) -> session::session {
357360
auto target_cfg = build_target_config();
358361
auto cstore = cstore::mk_cstore();
359362
ret session::session(target_cfg, sopts, cstore,
360-
codemap::new_codemap(), 0u);
363+
@rec(cm=codemap::new_codemap(), mutable next_id=0),
364+
0u);
361365
}
362366

363367
fn parse_pretty(session::session sess, &str name) -> pp_mode {

src/comp/driver/session.rs

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import std::option::some;
1111
import std::option::none;
1212
import std::str;
1313
import std::vec;
14+
import syntax::parse::parser::parse_sess;
1415

1516
tag os { os_win32; os_macos; os_linux; }
1617

@@ -47,26 +48,26 @@ type crate_metadata = rec(str name, vec[u8] data);
4748
obj session(@config targ_cfg,
4849
@options opts,
4950
metadata::cstore::cstore cstore,
50-
codemap::codemap cm,
51+
parse_sess parse_sess,
5152
mutable uint err_count) {
5253
fn get_targ_cfg() -> @config { ret targ_cfg; }
5354
fn get_opts() -> @options { ret opts; }
5455
fn get_cstore() -> metadata::cstore::cstore { cstore }
5556
fn span_fatal(span sp, str msg) -> ! {
5657
// FIXME: Use constants, but rustboot doesn't know how to export them.
57-
codemap::emit_error(some(sp), msg, cm);
58+
codemap::emit_error(some(sp), msg, parse_sess.cm);
5859
fail;
5960
}
6061
fn fatal(str msg) -> ! {
61-
codemap::emit_error(none, msg, cm);
62+
codemap::emit_error(none, msg, parse_sess.cm);
6263
fail;
6364
}
6465
fn span_err(span sp, str msg) {
65-
codemap::emit_error(some(sp), msg, cm);
66+
codemap::emit_error(some(sp), msg, parse_sess.cm);
6667
err_count += 1u;
6768
}
6869
fn err(str msg) {
69-
codemap::emit_error(none, msg, cm);
70+
codemap::emit_error(none, msg, parse_sess.cm);
7071
err_count += 1u;
7172
}
7273
fn abort_if_errors() {
@@ -76,17 +77,17 @@ obj session(@config targ_cfg,
7677
}
7778
fn span_warn(span sp, str msg) {
7879
// FIXME: Use constants, but rustboot doesn't know how to export them.
79-
codemap::emit_warning(some(sp), msg, cm);
80+
codemap::emit_warning(some(sp), msg, parse_sess.cm);
8081
}
8182
fn warn(str msg) {
82-
codemap::emit_warning(none, msg, cm);
83+
codemap::emit_warning(none, msg, parse_sess.cm);
8384
}
8485
fn span_note(span sp, str msg) {
8586
// FIXME: Use constants, but rustboot doesn't know how to export them.
86-
codemap::emit_note(some(sp), msg, cm);
87+
codemap::emit_note(some(sp), msg, parse_sess.cm);
8788
}
8889
fn note(str msg) {
89-
codemap::emit_note(none, msg, cm);
90+
codemap::emit_note(none, msg, parse_sess.cm);
9091
}
9192
fn span_bug(span sp, str msg) -> ! {
9293
self.span_fatal(sp, #fmt("internal compiler error %s", msg));
@@ -98,9 +99,13 @@ obj session(@config targ_cfg,
9899
self.span_bug(sp, "unimplemented " + msg);
99100
}
100101
fn unimpl(str msg) -> ! { self.bug("unimplemented " + msg); }
101-
fn get_codemap() -> codemap::codemap { ret cm; }
102+
fn get_codemap() -> codemap::codemap { ret parse_sess.cm; }
102103
fn lookup_pos(uint pos) -> codemap::loc {
103-
ret codemap::lookup_pos(cm, pos);
104+
ret codemap::lookup_pos(parse_sess.cm, pos);
105+
}
106+
fn get_parse_sess() -> parse_sess { ret parse_sess; }
107+
fn next_node_id() -> ast::node_id {
108+
ret syntax::parse::parser::next_node_id(parse_sess);
104109
}
105110
fn span_str(span sp) -> str {
106111
ret codemap::span_to_str(sp, self.get_codemap());

src/comp/middle/trans.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6378,8 +6378,8 @@ fn trans_expr_out(&@block_ctxt cx, &@ast::expr e, out_method output) ->
63786378
case (ast::expr_rec(?args, ?base)) {
63796379
ret trans_rec(cx, args, base, e.id);
63806380
}
6381-
case (ast::expr_ext(_, _, _, ?expanded)) {
6382-
ret trans_expr(cx, expanded);
6381+
case (ast::expr_ext(_, _, _)) {
6382+
ret cx.fcx.lcx.ccx.sess.bug("unexpanded macro");
63836383
}
63846384
case (ast::expr_fail(?expr)) {
63856385
ret trans_fail_expr(cx, some(e.span), expr);

src/comp/middle/tstate/pre_post_conditions.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -570,9 +570,8 @@ fn find_pre_post_expr(&fn_ctxt fcx, @expr e) {
570570
case (expr_break) { clear_pp(expr_pp(fcx.ccx, e)); }
571571
case (expr_cont) { clear_pp(expr_pp(fcx.ccx, e)); }
572572
case (expr_port(_)) { clear_pp(expr_pp(fcx.ccx, e)); }
573-
case (expr_ext(_, _, _, ?expanded)) {
574-
find_pre_post_expr(fcx, expanded);
575-
copy_pre_post(fcx.ccx, e.id, expanded);
573+
case (expr_ext(_, _, _)) {
574+
fcx.ccx.tcx.sess.bug("unexpanded macro");
576575
}
577576
case (expr_anon_obj(?anon_obj, _)) {
578577
alt (anon_obj.with_obj) {

src/comp/middle/tstate/states.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -367,8 +367,8 @@ fn find_pre_post_state_expr(&fn_ctxt fcx, &prestate pres, @expr e) -> bool {
367367
case (expr_chan(?ex)) {
368368
ret find_pre_post_state_sub(fcx, pres, ex, e.id, none);
369369
}
370-
case (expr_ext(_, _, _, ?expanded)) {
371-
ret find_pre_post_state_sub(fcx, pres, expanded, e.id, none);
370+
case (expr_ext(_, _, _)) {
371+
fcx.ccx.tcx.sess.bug("unexpanded macro");
372372
}
373373
case (expr_put(?maybe_e)) {
374374
alt (maybe_e) {

src/comp/middle/typeck.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1780,10 +1780,8 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) {
17801780
}
17811781
write::ty_only_fixup(fcx, id, tpt._1);
17821782
}
1783-
case (ast::expr_ext(?p, ?args, ?body, ?expanded)) {
1784-
check_expr(fcx, expanded);
1785-
auto t = expr_ty(fcx.ccx.tcx, expanded);
1786-
write::ty_only_fixup(fcx, id, t);
1783+
case (ast::expr_ext(_,_,_)) {
1784+
fcx.ccx.tcx.sess.bug("unexpanded macro");
17871785
}
17881786
case (ast::expr_fail(?expr_opt)) {
17891787
alt (expr_opt) {

src/comp/rustc.rc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ mod syntax {
5353
mod fmt;
5454
mod env;
5555
mod simplext;
56+
mod expand;
5657
}
5758
mod print {
5859
mod pprust;

src/comp/syntax/ast.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ tag expr_ {
305305
expr_field(@expr, ident);
306306
expr_index(@expr, @expr);
307307
expr_path(path);
308-
expr_ext(path, (@expr)[], option::t[str], @expr);
308+
expr_ext(path, (@expr)[], option::t[str]);
309309
expr_fail(option::t[@expr]);
310310
expr_break;
311311
expr_cont;

src/comp/syntax/ext/base.rs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import std::ivec;
22
import std::vec;
33
import std::option;
44
import std::map::hashmap;
5-
import parse::parser::parse_sess;
5+
import driver::session::session;
66
import codemap::span;
77
import std::map::new_str_hash;
88
import codemap;
@@ -41,14 +41,14 @@ type ext_ctxt =
4141
span_msg_fn span_unimpl,
4242
next_id_fn next_id);
4343

44-
fn mk_ctxt(&parse_sess sess) -> ext_ctxt {
45-
fn ext_span_fatal_(&codemap::codemap cm, span sp, str msg) -> ! {
46-
codemap::emit_error(option::some(sp), msg, cm);
44+
fn mk_ctxt(&session sess) -> ext_ctxt {
45+
fn ext_span_fatal_(&session sess, span sp, str msg) -> ! {
46+
sess.span_err(sp, msg);
4747
fail;
4848
}
49-
auto ext_span_fatal = bind ext_span_fatal_(sess.cm, _, _);
50-
fn ext_span_unimpl_(&codemap::codemap cm, span sp, str msg) -> ! {
51-
codemap::emit_error(option::some(sp), "unimplemented " + msg, cm);
49+
auto ext_span_fatal = bind ext_span_fatal_(sess, _, _);
50+
fn ext_span_unimpl_(&session sess, span sp, str msg) -> ! {
51+
sess.span_err(sp, "unimplemented " + msg);
5252
fail;
5353
}
5454

@@ -59,9 +59,12 @@ fn mk_ctxt(&parse_sess sess) -> ext_ctxt {
5959
// the extensions the file name of the crate being compiled so they can
6060
// use it to guess whether paths should be prepended with "std::". This is
6161
// super-ugly and needs a better solution.
62-
auto crate_file_name_hack = sess.cm.files.(0).name;
63-
auto ext_span_unimpl = bind ext_span_unimpl_(sess.cm, _, _);
64-
auto ext_next_id = bind parse::parser::next_node_id(sess);
62+
auto crate_file_name_hack = sess.get_codemap().files.(0).name;
63+
auto ext_span_unimpl = bind ext_span_unimpl_(sess, _, _);
64+
fn ext_next_id_(&session sess) -> ast::node_id {
65+
ret sess.next_node_id(); // temporary, until bind works better
66+
}
67+
auto ext_next_id = bind ext_next_id_(sess);
6568
ret rec(crate_file_name_hack=crate_file_name_hack,
6669
span_fatal=ext_span_fatal,
6770
span_unimpl=ext_span_unimpl,

src/comp/syntax/ext/expand.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
2+
import codemap::emit_error;
3+
import driver::session;
4+
import syntax::ast::crate;
5+
import syntax::ast::expr_;
6+
import syntax::ast::expr_ext;
7+
import syntax::fold::*;
8+
9+
import std::option::none;
10+
import std::option::some;
11+
12+
import std::map::hashmap;
13+
import std::ivec;
14+
15+
fn expand_expr(&hashmap[str, base::syntax_extension] exts,
16+
&session::session sess, &expr_ e, ast_fold fld,
17+
&fn(&ast::expr_, ast_fold) -> expr_ orig) -> expr_ {
18+
ret alt(e) {
19+
case (expr_ext(?pth, ?args, ?body)) {
20+
assert(ivec::len(pth.node.idents) > 0u);
21+
auto extname = pth.node.idents.(0);
22+
auto ext_cx = base::mk_ctxt(sess);
23+
alt (exts.find(extname)) {
24+
case (none) {
25+
emit_error(some(pth.span), "unknown syntax expander: '"
26+
+ extname + "'", sess.get_codemap());
27+
fail
28+
}
29+
case (some(base::normal(?ext))) {
30+
//keep going, outside-in
31+
fld.fold_expr(ext(ext_cx, pth.span, args, body)).node
32+
}
33+
case (some(base::macro_defining(?ext))) {
34+
auto named_extension = ext(ext_cx, pth.span, args, body);
35+
exts.insert(named_extension._0, named_extension._1);
36+
ast::expr_tup([])
37+
}
38+
}
39+
40+
}
41+
case (_) { orig(e, fld) }
42+
};
43+
}
44+
45+
fn expand_crate(&session::session sess, &@crate c) -> @crate {
46+
auto exts = ext::base::syntax_expander_table();
47+
auto afp = default_ast_fold();
48+
auto f_pre =
49+
rec(fold_expr = bind expand_expr(exts, sess, _, _, afp.fold_expr)
50+
with *afp);
51+
auto f = make_fold(f_pre);
52+
auto res = @f.fold_crate(*c);
53+
dummy_out(f); //temporary: kill circular reference
54+
ret res;
55+
56+
}
57+
58+
// Local Variables:
59+
// mode: rust
60+
// fill-column: 78;
61+
// indent-tabs-mode: nil
62+
// c-basic-offset: 4
63+
// buffer-file-coding-system: utf-8-unix
64+
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
65+
// End:

0 commit comments

Comments
 (0)