diff options
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 1 | ||||
| -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 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/parse.rs | 6 | ||||
| -rw-r--r-- | src/libsyntax/parse/attr.rs | 1 | ||||
| -rw-r--r-- | src/libsyntax/parse/common.rs | 9 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 17 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 3 | ||||
| -rw-r--r-- | src/libsyntax/syntax.rc | 2 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 1 |
12 files changed, 100 insertions, 9 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index a817faad069..4c0be731df4 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -704,6 +704,7 @@ enum item_ { item_trait(~[ty_param], region_param, ~[ty_method]), item_impl(~[ty_param], region_param, option<@trait_ref> /* trait */, @ty /* self */, ~[@method]), + item_mac(mac), } #[auto_serialize] 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 diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index ad55c85496b..75977ba6169 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -283,6 +283,10 @@ fn noop_fold_item_underscore(i: item_, fld: ast_fold) -> item_ { rp, /* FIXME (#2543) */ copy methods) } + item_mac(m) { + // TODO: we might actually want to do something here. + item_mac(m) + } }; } diff --git a/src/libsyntax/parse.rs b/src/libsyntax/parse.rs index 9c143257e9e..b2d06311e67 100644 --- a/src/libsyntax/parse.rs +++ b/src/libsyntax/parse.rs @@ -12,6 +12,9 @@ export parse_crate_from_source_str; export parse_expr_from_source_str, parse_item_from_source_str; export parse_from_source_str; +// this used to be `import common::parser_common`, but it was causing +// unresolved import errors. Maybe resolve3 will fix it. +import common::*; import parser::parser; //import attr::parser_attr; import attr::*; //resolve bug? @@ -20,8 +23,7 @@ import common::*; //resolve bug? import ast::node_id; import util::interner; // FIXME (#1935): resolve badness -import lexer::{string_reader_as_reader, tt_reader_as_reader, reader, - string_reader, tt_reader}; +import lexer::*; import diagnostic::{span_handler, mk_span_handler, mk_handler, emitter}; type parse_sess = @{ diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs index d7ae4995520..e62de46f5db 100644 --- a/src/libsyntax/parse/attr.rs +++ b/src/libsyntax/parse/attr.rs @@ -1,7 +1,6 @@ import either::{either, left, right}; import ast_util::spanned; import common::*; //resolve bug? -//import common::{parser_common, seq_sep_trailing_disallowed}; export attr_or_ext; export parser_attr; diff --git a/src/libsyntax/parse/common.rs b/src/libsyntax/parse/common.rs index d4331ee766f..16059b473bb 100644 --- a/src/libsyntax/parse/common.rs +++ b/src/libsyntax/parse/common.rs @@ -92,6 +92,15 @@ impl parser_common for parser { self.token_is_keyword(word, self.token) } + fn is_any_keyword(tok: token::token) -> bool { + alt tok { + token::IDENT(sid, false) { + self.keywords.contains_key(*self.get_str(sid)) + } + _ { false } + } + } + fn eat_keyword(word: str) -> bool { self.require_keyword(word); diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 8bac3e0d751..2f4fe783b49 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -9,7 +9,7 @@ import lexer::reader; import prec::{as_prec, token_to_binop}; import attr::parser_attr; import common::{seq_sep_trailing_disallowed, seq_sep_trailing_allowed, - seq_sep_none, token_to_str, parser_common}; + seq_sep_none, token_to_str}; import dvec::{dvec, extensions}; import vec::{push}; import ast::*; @@ -2595,6 +2595,21 @@ class parser { self.parse_item_impl() } else if self.eat_keyword("class") { self.parse_item_class() + } else if !self.is_any_keyword(copy self.token) + && self.look_ahead(1) == token::NOT + { + // item macro. + let pth = self.parse_path_without_tps(); + #error("parsing invocation of %s", *pth.idents[0]); + self.expect(token::NOT); + let id = self.parse_ident(); + let tt = self.parse_token_tree(); + let m = ast::mac_invoc_tt(pth, tt); + let m: ast::mac = {node: m, + span: {lo: self.span.lo, + hi: self.span.hi, + expn_info: none}}; + (id, item_mac(m), none) } else { ret none; }; some(self.mk_item(lo, self.last_span.hi, ident, item_, vis, alt extra_attrs { diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 8e85de17613..5220ecdce93 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -589,6 +589,9 @@ fn print_item(s: ps, &&item: @ast::item) { for methods.each |meth| { print_ty_method(s, meth); } bclose(s, item.span); } + ast::item_mac(_m) { + fail "item macros unimplemented" + } } s.ann.post(ann_node); } diff --git a/src/libsyntax/syntax.rc b/src/libsyntax/syntax.rc index 9cf5528e1a3..5a384f04cb3 100644 --- a/src/libsyntax/syntax.rc +++ b/src/libsyntax/syntax.rc @@ -78,4 +78,6 @@ mod ext { mod log_syntax; mod auto_serialize; mod source_util; + + mod pipes; } diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 25c61535fcf..ed54ad3308b 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -163,6 +163,7 @@ fn visit_item<E>(i: @item, e: E, v: vt<E>) { v.visit_ty(m.decl.output, e, v); } } + item_mac(_m) { fail "item macros unimplemented" } } } |
