Skip to content

Remove old syntax ext #4172

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Dec 13, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 24 additions & 11 deletions src/librustc/middle/astencode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1033,6 +1033,8 @@ fn decode_item_ast(par_doc: ebml::Doc) -> @ast::item {
trait fake_ext_ctxt {
fn cfg() -> ast::crate_cfg;
fn parse_sess() -> parse::parse_sess;
fn call_site() -> span;
fn ident_of(st: ~str) -> ast::ident;
}

#[cfg(test)]
Expand All @@ -1042,6 +1044,16 @@ type fake_session = parse::parse_sess;
impl fake_session: fake_ext_ctxt {
fn cfg() -> ast::crate_cfg { ~[] }
fn parse_sess() -> parse::parse_sess { self }
fn call_site() -> span {
codemap::span {
lo: codemap::BytePos(0),
hi: codemap::BytePos(0),
expn_info: None
}
}
fn ident_of(st: ~str) -> ast::ident {
self.interner.intern(@st)
}
}

#[cfg(test)]
Expand All @@ -1050,7 +1062,8 @@ fn mk_ctxt() -> fake_ext_ctxt {
}

#[cfg(test)]
fn roundtrip(in_item: @ast::item) {
fn roundtrip(in_item: Option<@ast::item>) {
let in_item = in_item.get();
let bytes = do io::with_bytes_writer |wr| {
let ebml_w = writer::Serializer(wr);
encode_item_ast(ebml_w, in_item);
Expand All @@ -1074,45 +1087,45 @@ fn roundtrip(in_item: @ast::item) {
#[test]
fn test_basic() {
let ext_cx = mk_ctxt();
roundtrip(#ast[item]{
roundtrip(quote_item!(
fn foo() {}
});
));
}

#[test]
fn test_smalltalk() {
let ext_cx = mk_ctxt();
roundtrip(#ast[item]{
roundtrip(quote_item!(
fn foo() -> int { 3 + 4 } // first smalltalk program ever executed.
});
));
}

#[test]
fn test_more() {
let ext_cx = mk_ctxt();
roundtrip(#ast[item]{
roundtrip(quote_item!(
fn foo(x: uint, y: uint) -> uint {
let z = x + y;
return z;
}
});
));
}

#[test]
fn test_simplification() {
let ext_cx = mk_ctxt();
let item_in = ast::ii_item(#ast[item] {
let item_in = ast::ii_item(quote_item!(
fn new_int_alist<B: Copy>() -> alist<int, B> {
fn eq_int(&&a: int, &&b: int) -> bool { a == b }
return {eq_fn: eq_int, mut data: ~[]};
}
});
).get());
let item_out = simplify_ast(item_in);
let item_exp = ast::ii_item(#ast[item] {
let item_exp = ast::ii_item(quote_item!(
fn new_int_alist<B: Copy>() -> alist<int, B> {
return {eq_fn: eq_int, mut data: ~[]};
}
});
).get());
match (item_out, item_exp) {
(ast::ii_item(item_out), ast::ii_item(item_exp)) => {
assert pprust::item_to_str(item_out, ext_cx.parse_sess().interner)
Expand Down
14 changes: 0 additions & 14 deletions src/libsyntax/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -831,24 +831,10 @@ enum matcher_ {

type mac = spanned<mac_>;

type mac_arg = Option<@expr>;

#[auto_serialize]
#[auto_deserialize]
type mac_body_ = {span: span};

type mac_body = Option<mac_body_>;

#[auto_serialize]
#[auto_deserialize]
enum mac_ {
mac_invoc(@path, mac_arg, mac_body), // old macro-invocation
mac_invoc_tt(@path,~[token_tree]), // new macro-invocation
mac_ellipsis, // old pattern-match (obsolete)

// the span is used by the quoter/anti-quoter ...
mac_aq(span /* span of quote */, @expr), // anti-quote
mac_var(uint)
}

type lit = spanned<lit_>;
Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/ext/auto_serialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ priv impl ext_ctxt {
fn lambda(blk: ast::blk) -> @ast::expr {
let ext_cx = self;
let blk_e = self.expr(blk.span, ast::expr_block(blk));
#ast{ || $(blk_e) }
quote_expr!( || $blk_e )
}

fn blk(span: span, stmts: ~[@ast::stmt]) -> ast::blk {
Expand Down
168 changes: 52 additions & 116 deletions src/libsyntax/ext/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,32 +13,19 @@ use parse::parser;
use diagnostic::span_handler;
use codemap::{CodeMap, span, ExpnInfo, ExpandedFrom};
use ast_util::dummy_sp;
use parse::token;

// obsolete old-style #macro code:
//
// syntax_expander, normal, macro_defining, macro_definer,
// builtin
//
// new-style macro! tt code:
//
// syntax_expander_tt, syntax_expander_tt_item, mac_result,
// normal_tt, item_tt
//
// also note that ast::mac has way too many cases and can probably
// be trimmed down substantially.

// second argument is the span to blame for general argument problems
type syntax_expander_ =
fn@(ext_ctxt, span, ast::mac_arg, ast::mac_body) -> @ast::expr;
// second argument is the origin of the macro, if user-defined
type syntax_expander = {expander: syntax_expander_, span: Option<span>};
// also note that ast::mac used to have a bunch of extraneous cases and
// is now probably a redundant AST node, can be merged with
// ast::mac_invoc_tt.

type macro_def = {name: ~str, ext: syntax_extension};

// macro_definer is obsolete, remove when #old_macros go away.
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];

Expand All @@ -60,13 +47,7 @@ enum mac_result {

enum syntax_extension {

// normal() is obsolete, remove when #old_macros go away.
normal(syntax_expander),

// macro_defining() is obsolete, remove when #old_macros go away.
macro_defining(macro_definer),

// #[auto_serialize] and such. will probably survive death of #old_macros
// #[auto_serialize] and such
item_decorator(item_decorator),

// Token-tree expanders
Expand All @@ -80,37 +61,32 @@ enum syntax_extension {
// A temporary hard-coded map of methods for expanding syntax extension
// AST nodes into full ASTs
fn syntax_expander_table() -> HashMap<~str, syntax_extension> {
fn builtin(f: syntax_expander_) -> syntax_extension
{normal({expander: f, span: None})}
fn builtin_normal_tt(f: syntax_expander_tt_) -> syntax_extension {
normal_tt({expander: f, span: None})
}
fn builtin_item_tt(f: syntax_expander_tt_item_) -> syntax_extension {
item_tt({expander: f, span: None})
}
let syntax_expanders = HashMap();
syntax_expanders.insert(~"macro",
macro_defining(ext::simplext::add_new_extension));
syntax_expanders.insert(~"macro_rules",
builtin_item_tt(
ext::tt::macro_rules::add_new_extension));
syntax_expanders.insert(~"fmt", builtin(ext::fmt::expand_syntax_ext));
syntax_expanders.insert(~"fmt",
builtin_normal_tt(ext::fmt::expand_syntax_ext));
syntax_expanders.insert(
~"auto_serialize",
item_decorator(ext::auto_serialize::expand_auto_serialize));
syntax_expanders.insert(
~"auto_deserialize",
item_decorator(ext::auto_serialize::expand_auto_deserialize));
syntax_expanders.insert(~"env", builtin(ext::env::expand_syntax_ext));
syntax_expanders.insert(~"env",
builtin_normal_tt(ext::env::expand_syntax_ext));
syntax_expanders.insert(~"concat_idents",
builtin(ext::concat_idents::expand_syntax_ext));
syntax_expanders.insert(~"ident_to_str",
builtin(ext::ident_to_str::expand_syntax_ext));
builtin_normal_tt(
ext::concat_idents::expand_syntax_ext));
syntax_expanders.insert(~"log_syntax",
builtin_normal_tt(
ext::log_syntax::expand_syntax_ext));
syntax_expanders.insert(~"ast",
builtin(ext::qquote::expand_ast));
syntax_expanders.insert(~"deriving_eq",
item_decorator(
ext::deriving::expand_deriving_eq));
Expand All @@ -133,21 +109,29 @@ fn syntax_expander_table() -> HashMap<~str, syntax_extension> {
builtin_normal_tt(ext::quote::expand_quote_stmt));

syntax_expanders.insert(~"line",
builtin(ext::source_util::expand_line));
builtin_normal_tt(
ext::source_util::expand_line));
syntax_expanders.insert(~"col",
builtin(ext::source_util::expand_col));
builtin_normal_tt(
ext::source_util::expand_col));
syntax_expanders.insert(~"file",
builtin(ext::source_util::expand_file));
builtin_normal_tt(
ext::source_util::expand_file));
syntax_expanders.insert(~"stringify",
builtin(ext::source_util::expand_stringify));
builtin_normal_tt(
ext::source_util::expand_stringify));
syntax_expanders.insert(~"include",
builtin(ext::source_util::expand_include));
builtin_normal_tt(
ext::source_util::expand_include));
syntax_expanders.insert(~"include_str",
builtin(ext::source_util::expand_include_str));
builtin_normal_tt(
ext::source_util::expand_include_str));
syntax_expanders.insert(~"include_bin",
builtin(ext::source_util::expand_include_bin));
builtin_normal_tt(
ext::source_util::expand_include_bin));
syntax_expanders.insert(~"module_path",
builtin(ext::source_util::expand_mod));
builtin_normal_tt(
ext::source_util::expand_mod));
syntax_expanders.insert(~"proto",
builtin_item_tt(ext::pipes::expand_proto));
syntax_expanders.insert(
Expand Down Expand Up @@ -303,87 +287,39 @@ fn expr_to_ident(cx: ext_ctxt,
}
}

fn get_mac_args_no_max(cx: ext_ctxt, sp: span, arg: ast::mac_arg,
min: uint, name: ~str) -> ~[@ast::expr] {
return get_mac_args(cx, sp, arg, min, None, name);
fn check_zero_tts(cx: ext_ctxt, sp: span, tts: &[ast::token_tree],
name: &str) {
if tts.len() != 0 {
cx.span_fatal(sp, fmt!("%s takes no arguments", name));
}
}

fn get_mac_args(cx: ext_ctxt, sp: span, arg: ast::mac_arg,
min: uint, max: Option<uint>, name: ~str) -> ~[@ast::expr] {
match arg {
Some(expr) => match expr.node {
ast::expr_vec(elts, _) => {
let elts_len = vec::len(elts);
match max {
Some(max) if ! (min <= elts_len && elts_len <= max) => {
cx.span_fatal(sp,
fmt!("%s! takes between %u and %u arguments.",
name, min, max));
}
None if ! (min <= elts_len) => {
cx.span_fatal(sp, fmt!("%s! needs at least %u arguments.",
name, min));
}
_ => return elts /* we are good */
}
}
_ => {
cx.span_fatal(sp, fmt!("%s!: malformed invocation", name))
}
},
None => cx.span_fatal(sp, fmt!("%s!: missing arguments", name))
fn get_single_str_from_tts(cx: ext_ctxt, sp: span, tts: &[ast::token_tree],
name: &str) -> ~str {
if tts.len() != 1 {
cx.span_fatal(sp, fmt!("%s takes 1 argument.", name));
}
}

fn get_mac_body(cx: ext_ctxt, sp: span, args: ast::mac_body)
-> ast::mac_body_
{
match (args) {
Some(body) => body,
None => cx.span_fatal(sp, ~"missing macro body")
match tts[0] {
ast::tt_tok(_, token::LIT_STR(ident)) => cx.str_of(ident),
_ =>
cx.span_fatal(sp, fmt!("%s requires a string.", name))
}
}

// Massage syntactic form of new-style arguments to internal representation
// of old-style macro args, such that old-style macro can be run and invoked
// using new syntax. This will be obsolete when #old_macros go away.
fn tt_args_to_original_flavor(cx: ext_ctxt, sp: span, arg: ~[ast::token_tree])
-> ast::mac_arg {
use ast::{matcher, matcher_, match_tok, match_seq, match_nonterminal};
use parse::lexer::{new_tt_reader, reader};
use tt::macro_parser::{parse_or_else, matched_seq,
matched_nonterminal};

// these spans won't matter, anyways
fn ms(m: matcher_) -> matcher {
{node: m, span: dummy_sp()}
fn get_exprs_from_tts(cx: ext_ctxt, tts: ~[ast::token_tree])
-> ~[@ast::expr] {
let p = parse::new_parser_from_tts(cx.parse_sess(),
cx.cfg(),
tts);
let mut es = ~[];
while p.token != token::EOF {
if es.len() != 0 {
p.eat(token::COMMA);
}
es.push(p.parse_expr());
}
let arg_nm = cx.parse_sess().interner.gensym(@~"arg");

let argument_gram = ~[ms(match_seq(~[
ms(match_nonterminal(arg_nm, parse::token::special_idents::expr, 0u))
], Some(parse::token::COMMA), true, 0u, 1u))];

let arg_reader = new_tt_reader(cx.parse_sess().span_diagnostic,
cx.parse_sess().interner, None, arg);
let args =
match parse_or_else(cx.parse_sess(), cx.cfg(), arg_reader as reader,
argument_gram).get(arg_nm) {
@matched_seq(s, _) => {
do s.map() |lf| {
match *lf {
@matched_nonterminal(parse::token::nt_expr(arg)) =>
arg, /* whew! list of exprs, here we come! */
_ => fail ~"badly-structured parse result"
}
}
},
_ => fail ~"badly-structured parse result"
};

return Some(@{id: parse::next_node_id(cx.parse_sess()),
callee_id: parse::next_node_id(cx.parse_sess()),
node: ast::expr_vec(args, ast::m_imm), span: sp});
es
}

//
Expand Down
Loading