mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-20 10:55:14 +00:00
Make #fmt work from inside std. Issue #175
At long last, this patch makes #fmt usable from inside the standard library. The way it does it us very hackish, but at least it works now.
This commit is contained in:
parent
e494e73cdd
commit
6d3513eaee
@ -36,7 +36,8 @@ type next_id_fn = fn() -> ast::node_id ;
|
||||
// Provides a limited set of services necessary for syntax extensions
|
||||
// to do their thing
|
||||
type ext_ctxt =
|
||||
rec(span_msg_fn span_fatal,
|
||||
rec(str crate_file_name_hack,
|
||||
span_msg_fn span_fatal,
|
||||
span_msg_fn span_unimpl,
|
||||
next_id_fn next_id);
|
||||
|
||||
@ -50,9 +51,19 @@ fn mk_ctxt(&parse_sess sess) -> ext_ctxt {
|
||||
codemap::emit_error(option::some(sp), "unimplemented " + msg, cm);
|
||||
fail;
|
||||
}
|
||||
|
||||
// FIXME: Some extensions work by building ASTs with paths to functions
|
||||
// they need to call at runtime. As those functions live in the std crate,
|
||||
// the paths are prefixed with "std::". Unfortunately, these paths can't
|
||||
// work for code called from inside the stdard library, so here we pass
|
||||
// the extensions the file name of the crate being compiled so they can
|
||||
// use it to guess whether paths should be prepended with "std::". This is
|
||||
// super-ugly and needs a better solution.
|
||||
auto crate_file_name_hack = sess.cm.files.(0).name;
|
||||
auto ext_span_unimpl = bind ext_span_unimpl_(sess.cm, _, _);
|
||||
auto ext_next_id = bind parse::parser::next_node_id(sess);
|
||||
ret rec(span_fatal=ext_span_fatal,
|
||||
ret rec(crate_file_name_hack=crate_file_name_hack,
|
||||
span_fatal=ext_span_fatal,
|
||||
span_unimpl=ext_span_unimpl,
|
||||
next_id=ext_next_id);
|
||||
}
|
||||
|
@ -92,15 +92,19 @@ fn pieces_to_expr(&ext_ctxt cx, span sp, vec[piece] pieces,
|
||||
auto recexpr = ast::expr_rec(astfields, option::none[@ast::expr]);
|
||||
ret @rec(id=cx.next_id(), node=recexpr, span=sp);
|
||||
}
|
||||
fn make_path_vec(str ident) -> str[] {
|
||||
// FIXME: #fmt can't currently be used from within std
|
||||
// because we're explicitly referencing the 'std' crate here
|
||||
|
||||
ret ~["std", "extfmt", "rt", ident];
|
||||
fn make_path_vec(&ext_ctxt cx, str ident) -> str[] {
|
||||
fn compiling_std(&ext_ctxt cx) -> bool {
|
||||
ret str::find(cx.crate_file_name_hack, "std.rc") >= 0;
|
||||
}
|
||||
if (compiling_std(cx)) {
|
||||
ret ~["extfmt", "rt", ident];
|
||||
} else {
|
||||
ret ~["std", "extfmt", "rt", ident];
|
||||
}
|
||||
}
|
||||
fn make_rt_path_expr(&ext_ctxt cx, span sp, str ident) ->
|
||||
@ast::expr {
|
||||
auto path = make_path_vec(ident);
|
||||
auto path = make_path_vec(cx, ident);
|
||||
ret make_path_expr(cx, sp, path);
|
||||
}
|
||||
// Produces an AST expression that represents a RT::conv record,
|
||||
@ -141,7 +145,7 @@ fn pieces_to_expr(&ext_ctxt cx, span sp, vec[piece] pieces,
|
||||
}
|
||||
case (count_is(?c)) {
|
||||
auto count_lit = make_new_int(cx, sp, c);
|
||||
auto count_is_path = make_path_vec("count_is");
|
||||
auto count_is_path = make_path_vec(cx, "count_is");
|
||||
auto count_is_args = ~[count_lit];
|
||||
ret make_call(cx, sp, count_is_path, count_is_args);
|
||||
}
|
||||
@ -184,7 +188,7 @@ fn pieces_to_expr(&ext_ctxt cx, span sp, vec[piece] pieces,
|
||||
fn make_conv_call(&ext_ctxt cx, span sp, str conv_type, &conv cnv,
|
||||
@ast::expr arg) -> @ast::expr {
|
||||
auto fname = "conv_" + conv_type;
|
||||
auto path = make_path_vec(fname);
|
||||
auto path = make_path_vec(cx, fname);
|
||||
auto cnv_expr = make_rt_conv_expr(cx, sp, cnv);
|
||||
auto args = ~[cnv_expr, arg];
|
||||
ret make_call(cx, arg.span, path, args);
|
||||
|
Loading…
Reference in New Issue
Block a user