mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-03 20:23:59 +00:00
Make it possible to make built-in tt syntax extensions
This commit is contained in:
parent
4f104954a6
commit
4df2654f82
@ -6,19 +6,23 @@ import std::map::str_hash;
|
||||
|
||||
type syntax_expander_ =
|
||||
fn@(ext_ctxt, span, ast::mac_arg, ast::mac_body) -> @ast::expr;
|
||||
type syntax_expander = {
|
||||
expander: syntax_expander_,
|
||||
span: option<span>};
|
||||
type syntax_expander = {expander: syntax_expander_, span: option<span>};
|
||||
|
||||
type macro_def = {ident: ast::ident, ext: syntax_extension};
|
||||
type macro_definer =
|
||||
fn@(ext_ctxt, span, ast::mac_arg, ast::mac_body) -> macro_def;
|
||||
type item_decorator =
|
||||
fn@(ext_ctxt, span, ast::meta_item, [@ast::item]) -> [@ast::item];
|
||||
|
||||
type syntax_expander_tt = {expander: syntax_expander_tt_, span: option<span>};
|
||||
type syntax_expander_tt_ = fn@(ext_ctxt, span, ast::token_tree) -> @ast::expr;
|
||||
|
||||
enum syntax_extension {
|
||||
normal(syntax_expander),
|
||||
macro_defining(macro_definer),
|
||||
item_decorator(item_decorator),
|
||||
|
||||
normal_tt(syntax_expander_tt)
|
||||
}
|
||||
|
||||
// A temporary hard-coded map of methods for expanding syntax extension
|
||||
|
@ -47,6 +47,39 @@ fn expand_expr(exts: hashmap<str, syntax_extension>, cx: ext_ctxt,
|
||||
exts.insert(*named_extension.ident, named_extension.ext);
|
||||
(ast::expr_rec([], none), s)
|
||||
}
|
||||
some(normal_tt(_)) {
|
||||
cx.span_fatal(pth.span,
|
||||
#fmt["this tt-style macro should be \
|
||||
invoked '%s!{...}'", *extname])
|
||||
}
|
||||
}
|
||||
}
|
||||
mac_invoc_tt(pth, tt) {
|
||||
assert (vec::len(pth.idents) > 0u);
|
||||
let extname = pth.idents[0];
|
||||
alt exts.find(*extname) {
|
||||
none {
|
||||
cx.span_fatal(pth.span,
|
||||
#fmt["macro undefined: '%s'", *extname])
|
||||
}
|
||||
some(normal_tt({expander: exp, span: exp_sp})) {
|
||||
let expanded = exp(cx, pth.span, tt);
|
||||
|
||||
cx.bt_push(expanded_from({call_site: s,
|
||||
callie: {name: *extname, span: exp_sp}}));
|
||||
//keep going, outside-in
|
||||
let fully_expanded = fld.fold_expr(expanded).node;
|
||||
cx.bt_pop();
|
||||
|
||||
(fully_expanded, s)
|
||||
|
||||
}
|
||||
_ {
|
||||
cx.span_fatal(pth.span,
|
||||
#fmt["'%s' is not a tt-style macro",
|
||||
*extname])
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
_ { cx.span_bug(mac.span, "naked syntactic bit") }
|
||||
@ -75,7 +108,8 @@ fn expand_mod_items(exts: hashmap<str, syntax_extension>, cx: ext_ctxt,
|
||||
ast::meta_list(n, _) { n }
|
||||
};
|
||||
alt exts.find(*mname) {
|
||||
none | some(normal(_)) | some(macro_defining(_)) {
|
||||
none | some(normal(_)) | some(macro_defining(_))
|
||||
| some(normal_tt(_)) {
|
||||
items
|
||||
}
|
||||
|
||||
|
@ -883,8 +883,17 @@ class parser {
|
||||
is_ident(self.token) && !self.is_keyword("true") &&
|
||||
!self.is_keyword("false") {
|
||||
let pth = self.parse_path_with_tps(true);
|
||||
hi = pth.span.hi;
|
||||
ex = expr_path(pth);
|
||||
|
||||
/* `!`, as an operator, is prefix, so we know this isn't that */
|
||||
if self.token == token::NOT {
|
||||
self.bump();
|
||||
let m_body = self.parse_token_tree();
|
||||
let hi = self.span.hi;
|
||||
ret pexpr(self.mk_mac_expr(lo, hi, mac_invoc_tt(pth,m_body)));
|
||||
} else {
|
||||
hi = pth.span.hi;
|
||||
ex = expr_path(pth);
|
||||
}
|
||||
} else {
|
||||
let lit = self.parse_lit();
|
||||
hi = lit.span.hi;
|
||||
|
Loading…
Reference in New Issue
Block a user