99dd5911a1
There's now one unified way to return things from a macro, instead of being able to choose the `AnyMacro` trait or the `MRItem`/`MRExpr` variants of the `MacResult` enum. This does simplify the logic handling the expansions, but the biggest value of this is it makes macros in (for example) type position easier to implement, as there's this single thing to modify. By my measurements (using `-Z time-passes` on libstd and librustc etc.), this appears to have little-to-no impact on expansion speed. There are presumably larger costs than the small number of extra allocations and virtual calls this adds (notably, all `macro_rules!`-defined macros have not changed in behaviour, since they had to use the `AnyMacro` trait anyway).
64 lines
2.2 KiB
Rust
64 lines
2.2 KiB
Rust
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
|
// file at the top-level directory of this distribution and at
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
// option. This file may not be copied, modified, or distributed
|
|
// except according to those terms.
|
|
|
|
use ast;
|
|
use codemap;
|
|
use ext::base;
|
|
use ext::build::AstBuilder;
|
|
use parse::token;
|
|
|
|
use std::char;
|
|
use std::strbuf::StrBuf;
|
|
|
|
pub fn expand_syntax_ext(cx: &mut base::ExtCtxt,
|
|
sp: codemap::Span,
|
|
tts: &[ast::TokenTree]) -> ~base::MacResult {
|
|
let es = match base::get_exprs_from_tts(cx, sp, tts) {
|
|
Some(e) => e,
|
|
None => return base::DummyResult::expr(sp)
|
|
};
|
|
let mut accumulator = StrBuf::new();
|
|
for e in es.move_iter() {
|
|
match e.node {
|
|
ast::ExprLit(lit) => {
|
|
match lit.node {
|
|
ast::LitStr(ref s, _) |
|
|
ast::LitFloat(ref s, _) |
|
|
ast::LitFloatUnsuffixed(ref s) => {
|
|
accumulator.push_str(s.get());
|
|
}
|
|
ast::LitChar(c) => {
|
|
accumulator.push_char(char::from_u32(c).unwrap());
|
|
}
|
|
ast::LitInt(i, _) | ast::LitIntUnsuffixed(i) => {
|
|
accumulator.push_str(format!("{}", i));
|
|
}
|
|
ast::LitUint(u, _) => {
|
|
accumulator.push_str(format!("{}", u));
|
|
}
|
|
ast::LitNil => {}
|
|
ast::LitBool(b) => {
|
|
accumulator.push_str(format!("{}", b));
|
|
}
|
|
ast::LitBinary(..) => {
|
|
cx.span_err(e.span, "cannot concatenate a binary literal");
|
|
}
|
|
}
|
|
}
|
|
_ => {
|
|
cx.span_err(e.span, "expected a literal");
|
|
}
|
|
}
|
|
}
|
|
base::MacExpr::new(cx.expr_str(
|
|
sp,
|
|
token::intern_and_get_ident(accumulator.into_owned())))
|
|
}
|