about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPaul Stansifer <paul.stansifer@gmail.com>2012-05-14 17:43:31 -0700
committerPaul Stansifer <paul.stansifer@gmail.com>2012-05-18 10:05:24 -0700
commit88f4d0694187a451173d40e9c44db4499a6c04f4 (patch)
tree107432014221fcad80e309635668f649d599e2fe
parent9fe547d3a795f59217c0093c82aa5a5b86c65f72 (diff)
downloadrust-88f4d0694187a451173d40e9c44db4499a6c04f4.tar.gz
rust-88f4d0694187a451173d40e9c44db4499a6c04f4.zip
New syntax extensions: #line[], #col[], #file[], #stringify[], #include[]
-rw-r--r--src/librustsyntax/ext/base.rs10
-rw-r--r--src/librustsyntax/ext/source_util.rs48
-rw-r--r--src/librustsyntax/rustsyntax.rc1
-rw-r--r--src/test/run-pass/syntax-extension-source-utils-files/includeme.fragment7
-rw-r--r--src/test/run-pass/syntax-extension-source-utils.rs11
5 files changed, 77 insertions, 0 deletions
diff --git a/src/librustsyntax/ext/base.rs b/src/librustsyntax/ext/base.rs
index 92b6acba5b0..8cc388c7b1b 100644
--- a/src/librustsyntax/ext/base.rs
+++ b/src/librustsyntax/ext/base.rs
@@ -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;
 }
 
diff --git a/src/librustsyntax/ext/source_util.rs b/src/librustsyntax/ext/source_util.rs
new file mode 100644
index 00000000000..7b3471d03b4
--- /dev/null
+++ b/src/librustsyntax/ext/source_util.rs
@@ -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)
+}
diff --git a/src/librustsyntax/rustsyntax.rc b/src/librustsyntax/rustsyntax.rc
index 293238aac3c..91f1463fc19 100644
--- a/src/librustsyntax/rustsyntax.rc
+++ b/src/librustsyntax/rustsyntax.rc
@@ -66,4 +66,5 @@ mod ext {
     mod include;
     mod log_syntax;
     mod auto_serialize;
+    mod source_util;
 }
diff --git a/src/test/run-pass/syntax-extension-source-utils-files/includeme.fragment b/src/test/run-pass/syntax-extension-source-utils-files/includeme.fragment
new file mode 100644
index 00000000000..5db5b0f6ff5
--- /dev/null
+++ b/src/test/run-pass/syntax-extension-source-utils-files/includeme.fragment
@@ -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[]]
+}
\ No newline at end of file
diff --git a/src/test/run-pass/syntax-extension-source-utils.rs b/src/test/run-pass/syntax-extension-source-utils.rs
new file mode 100644
index 00000000000..926228534cc
--- /dev/null
+++ b/src/test/run-pass/syntax-extension-source-utils.rs
@@ -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")
+}