Fold #include_str into the other source_utils.rs syntax extensions.

This commit is contained in:
Paul Stansifer 2012-05-18 10:02:21 -07:00
parent 07e775404f
commit ac2faad26e
5 changed files with 58 additions and 63 deletions

View file

@ -31,8 +31,6 @@ fn syntax_expander_table() -> hashmap<str, syntax_extension> {
syntax_expanders.insert("auto_serialize",
item_decorator(ext::auto_serialize::expand));
syntax_expanders.insert("env", builtin(ext::env::expand_syntax_ext));
syntax_expanders.insert("include_str",
builtin(ext::include::str::expand_syntax_ext));
syntax_expanders.insert("macro",
macro_defining(ext::simplext::add_new_extension));
syntax_expanders.insert("concat_idents",
@ -53,6 +51,8 @@ fn syntax_expander_table() -> hashmap<str, syntax_extension> {
builtin(ext::source_util::expand_stringify));
syntax_expanders.insert("include",
builtin(ext::source_util::expand_include));
syntax_expanders.insert("include_str",
builtin(ext::source_util::expand_include_str));
syntax_expanders.insert("mod",
builtin(ext::source_util::expand_mod));
ret syntax_expanders;

View file

@ -1,49 +0,0 @@
/*
* The compiler code necessary to support the #include and #include_str
* extensions. Eventually this should all get sucked into either the compiler
* syntax extension plugin interface.
*/
import diagnostic::span_handler;
import base::*;
export str;
// FIXME: implement plain #include, restarting the parser on the included
// file. Currently only implement #include_str.
mod str {
fn expand_syntax_ext(cx: ext_ctxt, sp: codemap::span, arg: ast::mac_arg,
_body: ast::mac_body) -> @ast::expr {
let args = get_mac_args(cx,sp,arg,1u,option::some(1u),"include_str");
let mut path = expr_to_str(cx, args[0], "#include_str requires \
a string");
// NB: relative paths are resolved relative to the compilation unit
if !path::path_is_absolute(path) {
let cu = codemap::span_to_filename(sp, cx.codemap());
let dir = path::dirname(cu);
path = path::connect(dir, path);
}
alt io::read_whole_file_str(path) {
result::ok(src) { ret make_new_str(cx, sp, src); }
result::err(e) {
cx.parse_sess().span_diagnostic.handler().fatal(e)
}
}
}
}
fn make_new_str(cx: ext_ctxt, sp: codemap::span, s: str) -> @ast::expr {
ret make_new_lit(cx, sp, ast::lit_str(s));
}
//
// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
//

View file

@ -3,6 +3,14 @@ import ast;
import codemap::span;
import print::pprust;
export expand_line;
export expand_col;
export expand_file;
export expand_stringify;
export expand_mod;
export expand_include;
export expand_include_str;
/* #line(): expands to the current line number */
fn expand_line(cx: ext_ctxt, sp: span, arg: ast::mac_arg,
_body: ast::mac_body) -> @ast::expr {
@ -35,19 +43,53 @@ fn expand_stringify(cx: ext_ctxt, sp: span, arg: ast::mac_arg,
ret make_new_lit(cx, sp, ast::lit_str(pprust::expr_to_str(args[0])));
}
fn expand_include(cx: ext_ctxt, sp: span, arg: ast::mac_arg,
_body: ast::mac_body) -> @ast::expr {
let args = get_mac_args(cx, sp, arg, 1u, option::some(1u), "include");
let loc = codemap::lookup_char_pos(cx.codemap(), sp.lo);
let path = path::connect(path::dirname(loc.file.name),
expr_to_str(cx, args[0], "#include requires a string literal"));
let p = parse::new_parser_from_file(cx.parse_sess(), cx.cfg(), path,
parse::parser::SOURCE_FILE);
ret parse::parser::parse_expr(p)
}
fn expand_mod(cx: ext_ctxt, sp: span, arg: ast::mac_arg, _body: ast::mac_body)
-> @ast::expr {
get_mac_args(cx, sp, arg, 0u, option::some(0u), "file");
ret make_new_lit(cx, sp, ast::lit_str(str::connect(cx.mod_path(), "::")));
}
fn expand_include(cx: ext_ctxt, sp: span, arg: ast::mac_arg,
_body: ast::mac_body) -> @ast::expr {
let args = get_mac_args(cx, sp, arg, 1u, option::some(1u), "include");
let file = expr_to_str(cx, args[0], "#include_str requires a string");
let p = parse::new_parser_from_file(cx.parse_sess(), cx.cfg(),
res_rel_file(cx, sp, file),
parse::parser::SOURCE_FILE);
ret parse::parser::parse_expr(p)
}
fn expand_include_str(cx: ext_ctxt, sp: codemap::span, arg: ast::mac_arg,
_body: ast::mac_body) -> @ast::expr {
let args = get_mac_args(cx,sp,arg,1u,option::some(1u),"include_str");
let file = expr_to_str(cx, args[0], "#include_str requires a string");
alt io::read_whole_file_str(res_rel_file(cx, sp, file)) {
result::ok(src) { ret make_new_lit(cx, sp, ast::lit_str(src)); }
result::err(e) {
cx.parse_sess().span_diagnostic.handler().fatal(e)
}
}
}
fn res_rel_file(cx: ext_ctxt, sp: codemap::span, arg: path) -> path {
// NB: relative paths are resolved relative to the compilation unit
if !path::path_is_absolute(arg) {
let cu = codemap::span_to_filename(sp, cx.codemap());
let dir = path::dirname(cu);
ret path::connect(dir, arg);
} else {
ret arg;
}
}
//
// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
//

View file

@ -63,7 +63,6 @@ mod ext {
mod simplext;
mod concat_idents;
mod ident_to_str;
mod include;
mod log_syntax;
mod auto_serialize;
mod source_util;

View file

@ -14,6 +14,9 @@ fn main() {
assert(#stringify[(2*3) + 5] == "2 * 3 + 5");
assert(#include["syntax-extension-source-utils-files/includeme.fragment"]
== "victory robot 6");
assert(
#include_str["syntax-extension-source-utils-files/includeme.fragment"]
.starts_with("/* this is for "));
// The Windows tests are wrapped in an extra module for some reason
assert(m1::m2::where_am_i().ends_with("m1::m2"));
}