about summary refs log tree commit diff
path: root/src/comp/syntax/ext
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2011-07-10 17:00:28 -0700
committerBrian Anderson <banderson@mozilla.com>2011-07-10 17:00:28 -0700
commit6d3513eaee512e0143cd75927b8ff56a5bf98152 (patch)
treed886a3039905edc8e6d8a71f90da8454260b9136 /src/comp/syntax/ext
parente494e73cdd30fda0a10d6b3c067ca3a2809527eb (diff)
downloadrust-6d3513eaee512e0143cd75927b8ff56a5bf98152.tar.gz
rust-6d3513eaee512e0143cd75927b8ff56a5bf98152.zip
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.
Diffstat (limited to 'src/comp/syntax/ext')
-rw-r--r--src/comp/syntax/ext/base.rs15
-rw-r--r--src/comp/syntax/ext/fmt.rs20
2 files changed, 25 insertions, 10 deletions
diff --git a/src/comp/syntax/ext/base.rs b/src/comp/syntax/ext/base.rs
index 7b0accb573b..0990b3bdacb 100644
--- a/src/comp/syntax/ext/base.rs
+++ b/src/comp/syntax/ext/base.rs
@@ -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);
 }
diff --git a/src/comp/syntax/ext/fmt.rs b/src/comp/syntax/ext/fmt.rs
index 0f3b38a808b..ffae97b1b0c 100644
--- a/src/comp/syntax/ext/fmt.rs
+++ b/src/comp/syntax/ext/fmt.rs
@@ -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);