New syntax extensions: #line[], #col[], #file[], #stringify[], #include[]

This commit is contained in:
Paul Stansifer 2012-05-14 17:43:31 -07:00
parent 9fe547d3a7
commit 88f4d06941
5 changed files with 77 additions and 0 deletions

View file

@ -43,6 +43,16 @@ fn syntax_expander_table() -> hashmap<str, syntax_extension> {
builtin(ext::log_syntax::expand_syntax_ext));
syntax_expanders.insert("ast",
builtin(ext::qquote::expand_ast));
syntax_expanders.insert("line",
builtin(ext::source_util::expand_line));
syntax_expanders.insert("col",
builtin(ext::source_util::expand_col));
syntax_expanders.insert("file",
builtin(ext::source_util::expand_file));
syntax_expanders.insert("stringify",
builtin(ext::source_util::expand_stringify));
syntax_expanders.insert("include",
builtin(ext::source_util::expand_include));
ret syntax_expanders;
}

View file

@ -0,0 +1,48 @@
import base::*;
import ast;
import codemap::span;
import print::pprust;
/* #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 {
get_mac_args(cx, sp, arg, 0u, option::some(0u), "line");
let loc = codemap::lookup_char_pos(cx.codemap(), sp.lo);
ret make_new_lit(cx, sp, ast::lit_uint(loc.line as u64, ast::ty_u));
}
/* #col(): expands to the current column number */
fn expand_col(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), "col");
let loc = codemap::lookup_char_pos(cx.codemap(), sp.lo);
ret make_new_lit(cx, sp, ast::lit_uint(loc.col as u64, ast::ty_u));
}
/* #file(): expands to the current filename */
/* The filemap (`loc.file`) contains a bunch more information we could spit
* out if we wanted. */
fn expand_file(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");
let loc = codemap::lookup_char_pos(cx.codemap(), sp.lo);
ret make_new_lit(cx, sp, ast::lit_str(loc.file.name));
}
fn expand_stringify(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), "stringify");
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)
}

View file

@ -66,4 +66,5 @@ mod ext {
mod include;
mod log_syntax;
mod auto_serialize;
mod source_util;
}

View file

@ -0,0 +1,7 @@
/* this is for run-pass/syntax-extension-source-utils.rs */
{
assert(#file[].ends_with("utils-files/includeme.fragment"));
assert(#line[] == 5u);
#fmt["victory robot %u", #line[]]
}

View file

@ -0,0 +1,11 @@
// This test is brittle!
// xfail-pretty - the pretty tests lose path information, breaking #include
fn main() {
assert(#line[] == 5u);
assert(#col[] == 12u);
assert(#file[].ends_with("syntax-extension-source-utils.rs"));
assert(#stringify[(2*3) + 5] == "2 * 3 + 5");
assert(#include["syntax-extension-source-utils-files/includeme.fragment"]
== "victory robot 6")
}