diff options
| author | Eric Holk <eric.holk@gmail.com> | 2012-07-05 12:10:33 -0700 |
|---|---|---|
| committer | Eric Holk <eric.holk@gmail.com> | 2012-07-06 10:42:40 -0700 |
| commit | 05cdda3a2c147fdc8caef4e6c662f518ec325e0a (patch) | |
| tree | fba957706d8588512bfd259d7873edd615854d36 /src/libsyntax/ext | |
| parent | a787f4001388a394d5219b74113a718d980e4c90 (diff) | |
| download | rust-05cdda3a2c147fdc8caef4e6c662f518ec325e0a.tar.gz rust-05cdda3a2c147fdc8caef4e6c662f518ec325e0a.zip | |
Plumbing and parsing for item-position macros.
Diffstat (limited to 'src/libsyntax/ext')
| -rw-r--r-- | src/libsyntax/ext/base.rs | 13 | ||||
| -rw-r--r-- | src/libsyntax/ext/expand.rs | 42 | ||||
| -rw-r--r-- | src/libsyntax/ext/pipes.rs | 10 |
3 files changed, 60 insertions, 5 deletions
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 28e5c2c5f17..0e6cce27b2b 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -17,12 +17,18 @@ type item_decorator = type syntax_expander_tt = {expander: syntax_expander_tt_, span: option<span>}; type syntax_expander_tt_ = fn@(ext_ctxt, span, ast::token_tree) -> @ast::expr; +type syntax_expander_tt_item + = {expander: syntax_expander_tt_item_, span: option<span>}; +type syntax_expander_tt_item_ + = fn@(ext_ctxt, span, ast::ident, ast::token_tree) -> @ast::item; + enum syntax_extension { normal(syntax_expander), macro_defining(macro_definer), item_decorator(item_decorator), - normal_tt(syntax_expander_tt) + normal_tt(syntax_expander_tt), + item_tt(syntax_expander_tt_item), } // A temporary hard-coded map of methods for expanding syntax extension @@ -30,6 +36,9 @@ enum syntax_extension { fn syntax_expander_table() -> hashmap<str, syntax_extension> { fn builtin(f: syntax_expander_) -> syntax_extension {normal({expander: f, span: none})} + fn builtin_item_tt(f: syntax_expander_tt_item_) -> syntax_extension { + item_tt({expander: f, span: none}) + } let syntax_expanders = str_hash::<syntax_extension>(); syntax_expanders.insert("fmt", builtin(ext::fmt::expand_syntax_ext)); syntax_expanders.insert("auto_serialize", @@ -61,6 +70,8 @@ fn syntax_expander_table() -> hashmap<str, syntax_extension> { builtin(ext::source_util::expand_include_bin)); syntax_expanders.insert("mod", builtin(ext::source_util::expand_mod)); + syntax_expanders.insert("proto", + builtin_item_tt(ext::pipes::expand_proto)); ret syntax_expanders; } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index a037d87166a..63b3c0881e1 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -1,7 +1,7 @@ import std::map::hashmap; import ast::{crate, expr_, expr_mac, mac_invoc, mac_invoc_tt, - tt_delim, tt_flat}; + tt_delim, tt_flat, item_mac}; import fold::*; import ext::base::*; import ext::qquote::{qq_helper}; @@ -52,6 +52,10 @@ fn expand_expr(exts: hashmap<str, syntax_extension>, cx: ext_ctxt, #fmt["this tt-style macro should be \ invoked '%s!{...}'", *extname]) } + some(item_tt(*)) { + cx.span_fatal(pth.span, + "cannot use item macros in this context"); + } } } mac_invoc_tt(pth, tt) { @@ -109,7 +113,7 @@ fn expand_mod_items(exts: hashmap<str, syntax_extension>, cx: ext_ctxt, }; alt exts.find(*mname) { none | some(normal(_)) | some(macro_defining(_)) - | some(normal_tt(_)) { + | some(normal_tt(_)) | some(item_tt(*)) { items } @@ -124,7 +128,8 @@ fn expand_mod_items(exts: hashmap<str, syntax_extension>, cx: ext_ctxt, } /* record module we enter for `#mod` */ -fn expand_item(cx: ext_ctxt, &&it: @ast::item, fld: ast_fold, +fn expand_item(exts: hashmap<str, syntax_extension>, + cx: ext_ctxt, &&it: @ast::item, fld: ast_fold, orig: fn@(&&@ast::item, ast_fold) -> @ast::item) -> @ast::item { @@ -132,12 +137,41 @@ fn expand_item(cx: ext_ctxt, &&it: @ast::item, fld: ast_fold, ast::item_mod(_) | ast::item_foreign_mod(_) {true} _ {false} }; + let it = alt it.node { + ast::item_mac(*) { + expand_item_mac(exts, cx, it) + } + _ { it } + }; if is_mod { cx.mod_push(it.ident); } let ret_val = orig(it, fld); if is_mod { cx.mod_pop(); } ret ret_val; } +fn expand_item_mac(exts: hashmap<str, syntax_extension>, + cx: ext_ctxt, &&it: @ast::item) -> @ast::item { + alt it.node { + item_mac({node: mac_invoc_tt(pth, tt), span}) { + let extname = pth.idents[0]; + alt exts.find(*extname) { + none { + cx.span_fatal(pth.span, + #fmt("macro undefined: '%s'", *extname)) + } + some(item_tt(expand)) { + expand.expander(cx, it.span, it.ident, tt) + } + _ { cx.span_fatal(it.span, + #fmt("%s is not a legal here", *extname)) } + } + } + _ { + cx.span_bug(it.span, "invalid item macro invocation"); + } + } +} + fn new_span(cx: ext_ctxt, sp: span) -> span { /* this discards information in the case of macro-defining macros */ ret {lo: sp.lo, hi: sp.hi, expn_info: cx.backtrace()}; @@ -166,7 +200,7 @@ fn expand_crate(parse_sess: parse::parse_sess, let f_pre = @{fold_expr: |a,b,c| expand_expr(exts, cx, a, b, c, afp.fold_expr), fold_mod: |a,b| expand_mod_items(exts, cx, a, b, afp.fold_mod), - fold_item: |a,b| expand_item(cx, a, b, afp.fold_item), + fold_item: |a,b| expand_item(exts, cx, a, b, afp.fold_item), new_span: |a|new_span(cx, a) with *afp}; let f = make_fold(f_pre); diff --git a/src/libsyntax/ext/pipes.rs b/src/libsyntax/ext/pipes.rs new file mode 100644 index 00000000000..23bd95226c3 --- /dev/null +++ b/src/libsyntax/ext/pipes.rs @@ -0,0 +1,10 @@ + +import codemap::span; +import ext::base::ext_ctxt; + +fn expand_proto(cx: ext_ctxt, span: span, id: ast::ident, tt: ast::token_tree) + -> @ast::item +{ + cx.span_unimpl(span, + "Protocol compiler") +} \ No newline at end of file |
