Add #concat_idents[] and #ident_to_str[]

This commit is contained in:
Paul Stansifer
2011-08-03 11:46:32 -07:00
parent 4a636b06f6
commit 513276e595
6 changed files with 65 additions and 9 deletions

View File

@@ -57,10 +57,13 @@ mod syntax {
} }
mod ext { mod ext {
mod base; mod base;
mod expand;
mod fmt; mod fmt;
mod env; mod env;
mod simplext; mod simplext;
mod expand; mod concat_idents;
mod ident_to_str;
} }
mod print { mod print {
mod pprust; mod pprust;

View File

@@ -25,6 +25,10 @@ fn syntax_expander_table() -> hashmap[str, syntax_extension] {
syntax_expanders.insert("env", normal(ext::env::expand_syntax_ext)); syntax_expanders.insert("env", normal(ext::env::expand_syntax_ext));
syntax_expanders.insert("macro", syntax_expanders.insert("macro",
macro_defining(ext::simplext::add_new_extension)); macro_defining(ext::simplext::add_new_extension));
syntax_expanders.insert("concat_idents",
normal(ext::concat_idents::expand_syntax_ext));
syntax_expanders.insert("ident_to_str",
normal(ext::ident_to_str::expand_syntax_ext));
ret syntax_expanders; ret syntax_expanders;
} }
@@ -107,6 +111,12 @@ fn expr_to_ident(cx: &ext_ctxt, expr: @ast::expr, error: str) -> ast::ident {
} }
} }
fn make_new_lit(cx: &ext_ctxt, sp: codemap::span, lit: ast::lit_) ->
@ast::expr {
let sp_lit = @{node: lit, span: sp};
ret @{id: cx.next_id(), node: ast::expr_lit(sp_lit), span: sp};
}
// //

View File

@@ -0,0 +1,22 @@
import std::ivec;
import std::option;
import base::*;
import syntax::ast;
fn expand_syntax_ext(cx: &ext_ctxt, sp: codemap::span, arg: @ast::expr,
body: option::t[str]) -> @ast::expr {
let args: (@ast::expr)[] = alt arg.node {
ast::expr_vec(elts, _, _) { elts }
_ { cx.span_fatal(sp, "#concat_idents requires a vector argument .") }
};
let res: ast::ident = "";
for e: @ast::expr in args {
res += expr_to_ident(cx, e, "expected an ident");
}
ret @{id: cx.next_id(),
node: ast::expr_path( {
node: {global: false, idents: ~[res], types: ~[]},
span: sp}),
span: sp};
}

View File

@@ -1,12 +1,10 @@
/* /*
* The compiler code necessary to support the #env extension. Eventually this * The compiler code necessary to support the #env extension. Eventually this
* should all get sucked into either the compiler syntax extension plugin * should all get sucked into either the compiler syntax extension plugin
* interface. * interface.
*/ */
import std::ivec; import std::ivec;
import std::str;
import std::option; import std::option;
import std::generic_os; import std::generic_os;
import base::*; import base::*;
@@ -31,12 +29,6 @@ fn expand_syntax_ext(cx: &ext_ctxt, sp: codemap::span, arg: @ast::expr,
} }
} }
fn make_new_lit(cx: &ext_ctxt, sp: codemap::span, lit: ast::lit_) ->
@ast::expr {
let sp_lit = @{node: lit, span: sp};
ret @{id: cx.next_id(), node: ast::expr_lit(sp_lit), span: sp};
}
fn make_new_str(cx: &ext_ctxt, sp: codemap::span, s: str) -> @ast::expr { fn make_new_str(cx: &ext_ctxt, sp: codemap::span, s: str) -> @ast::expr {
ret make_new_lit(cx, sp, ast::lit_str(s, ast::sk_rc)); ret make_new_lit(cx, sp, ast::lit_str(s, ast::sk_rc));
} }

View File

@@ -0,0 +1,21 @@
import std::ivec;
import std::option;
import base::*;
import syntax::ast;
fn expand_syntax_ext(cx: &ext_ctxt, sp: codemap::span, arg: @ast::expr,
body: option::t[str]) -> @ast::expr {
let args: (@ast::expr)[] = alt arg.node {
ast::expr_vec(elts, _, _) { elts }
_ { cx.span_fatal(sp, "#ident_to_str requires a vector argument .") }
};
if ivec::len[@ast::expr](args) != 1u {
cx.span_fatal(sp, "malformed #ident_to_str call");
}
ret make_new_lit(cx, sp,
ast::lit_str(expr_to_ident(cx, args.(0u),
"expected an ident"),
ast::sk_rc));
}

View File

@@ -0,0 +1,8 @@
fn main() {
let asdf_fdsa = "<.<";
assert(#concat_idents[asd,f_f,dsa] == "<.<");
assert(#ident_to_str[use_mention_distinction]
== "use_mention_distinction");
}