From 9cced55b93a14cdca9bb86ae99b22021fac8685f Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Wed, 12 Dec 2012 10:44:01 -0800 Subject: [PATCH 1/3] syntax: remove all remaining uses of #ast, and #ast / qquote itself. --- src/librustc/middle/astencode.rs | 35 ++- src/libsyntax/ext/auto_serialize.rs | 2 +- src/libsyntax/ext/base.rs | 2 - src/libsyntax/ext/expand.rs | 8 +- src/libsyntax/ext/qquote.rs | 370 ----------------------- src/libsyntax/parse/parser.rs | 7 - src/libsyntax/syntax.rc | 3 - src/test/compile-fail/qquote-1.rs | 34 ++- src/test/compile-fail/qquote-2.rs | 35 ++- src/test/run-pass-fulldeps/issue-1926.rs | 6 +- src/test/run-pass-fulldeps/qquote.rs | 59 ++-- 11 files changed, 95 insertions(+), 466 deletions(-) delete mode 100644 src/libsyntax/ext/qquote.rs diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index ea018bd528e20..781ac7809e70c 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -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)] @@ -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)] @@ -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); @@ -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() -> alist { 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() -> alist { 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) diff --git a/src/libsyntax/ext/auto_serialize.rs b/src/libsyntax/ext/auto_serialize.rs index 44fa8ac7a1bc6..9830a5b1434fb 100644 --- a/src/libsyntax/ext/auto_serialize.rs +++ b/src/libsyntax/ext/auto_serialize.rs @@ -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 { diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 312c6cc16f7a5..10e42a6facfa5 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -109,8 +109,6 @@ fn syntax_expander_table() -> HashMap<~str, syntax_extension> { 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)); diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index e9d871752aae3..489a1cb3c2205 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -14,7 +14,6 @@ use ast::{crate, expr_, expr_mac, mac_invoc, mac_invoc_tt, tt_delim, tt_tok, item_mac, stmt_, stmt_mac, stmt_expr, stmt_semi}; use fold::*; use ext::base::*; -use ext::qquote::{qq_helper}; use parse::{parser, parse_expr_from_source_str, new_parser_from_tts}; @@ -169,7 +168,12 @@ fn expand_mod_items(exts: HashMap<~str, syntax_extension>, cx: ext_ctxt, None | Some(normal(_)) | Some(macro_defining(_)) | Some(normal_tt(_)) | Some(item_tt(*)) => items, Some(item_decorator(dec_fn)) => { - dec_fn(cx, attr.span, attr.node.value, items) + cx.bt_push(ExpandedFrom({call_site: attr.span, + callie: {name: copy mname, + span: None}})); + let r = dec_fn(cx, attr.span, attr.node.value, items); + cx.bt_pop(); + r } } } diff --git a/src/libsyntax/ext/qquote.rs b/src/libsyntax/ext/qquote.rs deleted file mode 100644 index e13dfe750b790..0000000000000 --- a/src/libsyntax/ext/qquote.rs +++ /dev/null @@ -1,370 +0,0 @@ -// Copyright 2012 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use ast::{crate, expr_, mac_invoc, - mac_aq, mac_var}; -use parse::parser; -use parse::parser::{Parser, parse_from_source_str}; -use dvec::DVec; -use parse::token::ident_interner; -use codemap::{CharPos, BytePos}; - -use fold::*; -use visit::*; -use ext::base::*; -use ext::build::*; -use print::*; -use io::*; - -use codemap::span; - -struct gather_item { - lo: BytePos, - hi: BytePos, - e: @ast::expr, - constr: ~str -} - -type aq_ctxt = @{lo: BytePos, gather: DVec}; -enum fragment { - from_expr(@ast::expr), - from_ty(@ast::Ty) -} - -fn ids_ext(cx: ext_ctxt, strs: ~[~str]) -> ~[ast::ident] { - strs.map(|str| cx.parse_sess().interner.intern(@*str)) -} -fn id_ext(cx: ext_ctxt, str: ~str) -> ast::ident { - cx.parse_sess().interner.intern(@str) -} - - -trait qq_helper { - fn span() -> span; - fn visit(aq_ctxt, vt); - fn extract_mac() -> Option; - fn mk_parse_fn(ext_ctxt,span) -> @ast::expr; - fn get_fold_fn() -> ~str; -} - -impl @ast::crate: qq_helper { - fn span() -> span {self.span} - fn visit(cx: aq_ctxt, v: vt) {visit_crate(*self, cx, v);} - fn extract_mac() -> Option {fail} - fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr { - mk_path(cx, sp, - ids_ext(cx, ~[~"syntax", ~"ext", ~"qquote", ~"parse_crate"])) - } - fn get_fold_fn() -> ~str {~"fold_crate"} -} -impl @ast::expr: qq_helper { - fn span() -> span {self.span} - fn visit(cx: aq_ctxt, v: vt) {visit_expr(self, cx, v);} - fn extract_mac() -> Option { - match (self.node) { - ast::expr_mac({node: ref mac, _}) => Some((*mac)), - _ => None - } - } - fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr { - mk_path(cx, sp, - ids_ext(cx, ~[~"syntax", ~"ext", ~"qquote", ~"parse_expr"])) - } - fn get_fold_fn() -> ~str {~"fold_expr"} -} -impl @ast::Ty: qq_helper { - fn span() -> span {self.span} - fn visit(cx: aq_ctxt, v: vt) {visit_ty(self, cx, v);} - fn extract_mac() -> Option { - match (self.node) { - ast::ty_mac({node: ref mac, _}) => Some((*mac)), - _ => None - } - } - fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr { - mk_path(cx, sp, - ids_ext(cx, ~[~"syntax", ~"ext", ~"qquote", ~"parse_ty"])) - } - fn get_fold_fn() -> ~str {~"fold_ty"} -} -impl @ast::item: qq_helper { - fn span() -> span {self.span} - fn visit(cx: aq_ctxt, v: vt) {visit_item(self, cx, v);} - fn extract_mac() -> Option {fail} - fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr { - mk_path(cx, sp, - ids_ext(cx, ~[~"syntax", ~"ext", ~"qquote", ~"parse_item"])) - } - fn get_fold_fn() -> ~str {~"fold_item"} -} -impl @ast::stmt: qq_helper { - fn span() -> span {self.span} - fn visit(cx: aq_ctxt, v: vt) {visit_stmt(self, cx, v);} - fn extract_mac() -> Option {fail} - fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr { - mk_path(cx, sp, - ids_ext(cx, ~[~"syntax", ~"ext", ~"qquote", ~"parse_stmt"])) - } - fn get_fold_fn() -> ~str {~"fold_stmt"} -} -impl @ast::pat: qq_helper { - fn span() -> span {self.span} - fn visit(cx: aq_ctxt, v: vt) {visit_pat(self, cx, v);} - fn extract_mac() -> Option {fail} - fn mk_parse_fn(cx: ext_ctxt, sp: span) -> @ast::expr { - mk_path(cx, sp, ids_ext(cx, ~[~"syntax", ~"ext", ~"qquote", - ~"parse_pat"])) - } - fn get_fold_fn() -> ~str {~"fold_pat"} -} - -fn gather_anti_quotes(lo: BytePos, node: N) -> aq_ctxt -{ - let v = @{visit_expr: |node, &&cx, v| visit_aq(node, ~"from_expr", cx, v), - visit_ty: |node, &&cx, v| visit_aq(node, ~"from_ty", cx, v), - .. *default_visitor()}; - let cx = @{lo:lo, gather: DVec()}; - node.visit(cx, mk_vt(v)); - // FIXME (#2250): Maybe this is an overkill (merge_sort), it might - // be better to just keep the gather array in sorted order. - do cx.gather.swap |v| { - pure fn by_lo(a: &gather_item, b: &gather_item) -> bool { - a.lo < b.lo - } - std::sort::merge_sort(v, by_lo) - }; - return cx; -} - -fn visit_aq(node: T, constr: ~str, &&cx: aq_ctxt, v: vt) -{ - match (node.extract_mac()) { - Some(mac_aq(sp, e)) => { - cx.gather.push(gather_item { - lo: sp.lo - cx.lo, - hi: sp.hi - cx.lo, - e: e, - constr: constr}); - } - _ => node.visit(cx, v) - } -} - -fn is_space(c: char) -> bool { - parse::lexer::is_whitespace(c) -} - -fn expand_ast(ecx: ext_ctxt, _sp: span, - arg: ast::mac_arg, body: ast::mac_body) - -> @ast::expr -{ - let mut what = ~"expr"; - do arg.iter |arg| { - let args: ~[@ast::expr] = - match arg.node { - ast::expr_vec(elts, _) => elts, - _ => { - ecx.span_fatal - (_sp, ~"#ast requires arguments of the form `~[...]`.") - } - }; - if vec::len::<@ast::expr>(args) != 1u { - ecx.span_fatal(_sp, ~"#ast requires exactly one arg"); - } - match (args[0].node) { - ast::expr_path(@{idents: id, _}) if vec::len(id) == 1u - => what = *ecx.parse_sess().interner.get(id[0]), - _ => ecx.span_fatal(args[0].span, ~"expected an identifier") - } - } - let body = get_mac_body(ecx,_sp,body); - - return match what { - ~"crate" => finish(ecx, body, parse_crate), - ~"expr" => finish(ecx, body, parse_expr), - ~"ty" => finish(ecx, body, parse_ty), - ~"item" => finish(ecx, body, parse_item), - ~"stmt" => finish(ecx, body, parse_stmt), - ~"pat" => finish(ecx, body, parse_pat), - _ => ecx.span_fatal(_sp, ~"unsupported ast type") - }; -} - -fn parse_crate(p: Parser) -> @ast::crate { p.parse_crate_mod(~[]) } -fn parse_ty(p: Parser) -> @ast::Ty { p.parse_ty(false) } -fn parse_stmt(p: Parser) -> @ast::stmt { p.parse_stmt(~[]) } -fn parse_expr(p: Parser) -> @ast::expr { p.parse_expr() } -fn parse_pat(p: Parser) -> @ast::pat { p.parse_pat(true) } - -fn parse_item(p: Parser) -> @ast::item { - match p.parse_item(~[]) { - Some(item) => item, - None => fail ~"parse_item: parsing an item failed" - } -} - -fn finish - (ecx: ext_ctxt, body: ast::mac_body_, f: fn (p: Parser) -> T) - -> @ast::expr -{ - let cm = ecx.codemap(); - let str = @cm.span_to_snippet(body.span); - debug!("qquote--str==%?", str); - let fname = cm.mk_substr_filename(body.span); - let node = parse_from_source_str - (f, fname, codemap::FssInternal(body.span), str, - ecx.cfg(), ecx.parse_sess()); - let loc = cm.lookup_char_pos(body.span.lo); - - let sp = node.span(); - let qcx = gather_anti_quotes(sp.lo, node); - let cx = qcx; - - for uint::range(1u, cx.gather.len()) |i| { - assert cx.gather[i-1u].lo < cx.gather[i].lo; - // ^^ check that the vector is sorted - assert cx.gather[i-1u].hi <= cx.gather[i].lo; - // ^^ check that the spans are non-overlapping - } - - let mut str2 = ~""; - enum state {active, skip(uint), blank}; - let mut state = active; - let mut i = BytePos(0u); - let mut j = 0u; - let g_len = cx.gather.len(); - for str::chars_each(*str) |ch| { - if (j < g_len && i == cx.gather[j].lo) { - assert ch == '$'; - let repl = fmt!("$%u ", j); - state = skip(str::char_len(repl)); - str2 += repl; - } - match copy state { - active => str::push_char(&mut str2, ch), - skip(1u) => state = blank, - skip(sk) => state = skip (sk-1u), - blank if is_space(ch) => str::push_char(&mut str2, ch), - blank => str::push_char(&mut str2, ' ') - } - i += BytePos(1u); - if (j < g_len && i == cx.gather[j].hi) { - assert ch == ')'; - state = active; - j += 1u; - } - } - - let cx = ecx; - - let cfg_call = || mk_call_( - cx, sp, mk_access(cx, sp, ids_ext(cx, ~[~"ext_cx"]), - id_ext(cx, ~"cfg")), ~[]); - - let parse_sess_call = || mk_call_( - cx, sp, mk_access(cx, sp, ids_ext(cx, ~[~"ext_cx"]), - id_ext(cx, ~"parse_sess")), ~[]); - - let pcall = mk_call(cx,sp, - ids_ext(cx, ~[~"syntax", ~"parse", ~"parser", - ~"parse_from_source_str"]), - ~[node.mk_parse_fn(cx,sp), - mk_uniq_str(cx,sp, fname), - mk_call(cx,sp, - ids_ext(cx, ~[~"syntax",~"ext", - ~"qquote", ~"mk_file_substr"]), - ~[mk_uniq_str(cx,sp, loc.file.name), - mk_uint(cx,sp, loc.line), - mk_uint(cx,sp, loc.col.to_uint())]), - mk_unary(cx,sp, ast::box(ast::m_imm), - mk_uniq_str(cx,sp, str2)), - cfg_call(), - parse_sess_call()] - ); - let mut rcall = pcall; - if (g_len > 0u) { - rcall = mk_call(cx,sp, - ids_ext(cx, ~[~"syntax", ~"ext", ~"qquote", - ~"replace"]), - ~[pcall, - mk_uniq_vec_e(cx,sp, qcx.gather.map_to_vec(|g| { - mk_call(cx,sp, - ids_ext(cx, ~[~"syntax", ~"ext", - ~"qquote", g.constr]), - ~[g.e])})), - mk_path(cx,sp, - ids_ext(cx, ~[~"syntax", ~"ext", ~"qquote", - node.get_fold_fn()]))]); - } - return rcall; -} - -fn replace(node: T, repls: ~[fragment], ff: fn (ast_fold, T) -> T) - -> T -{ - let aft = default_ast_fold(); - let f_pre = @{fold_expr: |a,b,c|replace_expr(repls, a, b, c, - aft.fold_expr), - fold_ty: |a,b,c|replace_ty(repls, a, b, c, - aft.fold_ty), - .. *aft}; - return ff(make_fold(f_pre), node); -} -fn fold_crate(f: ast_fold, &&n: @ast::crate) -> @ast::crate { - @f.fold_crate(*n) -} -fn fold_expr(f: ast_fold, &&n: @ast::expr) -> @ast::expr {f.fold_expr(n)} -fn fold_ty(f: ast_fold, &&n: @ast::Ty) -> @ast::Ty {f.fold_ty(n)} -fn fold_item(f: ast_fold, &&n: @ast::item) -> @ast::item { - f.fold_item(n).get() //HACK: we know we don't drop items -} -fn fold_stmt(f: ast_fold, &&n: @ast::stmt) -> @ast::stmt {f.fold_stmt(n)} -fn fold_pat(f: ast_fold, &&n: @ast::pat) -> @ast::pat {f.fold_pat(n)} - -fn replace_expr(repls: ~[fragment], - e: ast::expr_, s: span, fld: ast_fold, - orig: fn@(ast::expr_, span, ast_fold)->(ast::expr_, span)) - -> (ast::expr_, span) -{ - match e { - ast::expr_mac({node: mac_var(i), _}) => match (repls[i]) { - from_expr(r) => (r.node, r.span), - _ => fail /* fixme error message */ - }, - _ => orig(e,s,fld) - } -} - -fn replace_ty(repls: ~[fragment], - e: ast::ty_, s: span, fld: ast_fold, - orig: fn@(ast::ty_, span, ast_fold)->(ast::ty_, span)) - -> (ast::ty_, span) -{ - match e { - ast::ty_mac({node: mac_var(i), _}) => match (repls[i]) { - from_ty(r) => (r.node, r.span), - _ => fail /* fixme error message */ - }, - _ => orig(e,s,fld) - } -} - -fn mk_file_substr(fname: ~str, line: uint, col: uint) -> - codemap::FileSubstr { - codemap::FssExternal({filename: fname, line: line, col: CharPos(col)}) -} - -// Local Variables: -// mode: rust -// fill-column: 78; -// indent-tabs-mode: nil -// c-basic-offset: 4 -// buffer-file-coding-system: utf-8-unix -// End: diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 709d1537d4178..ead0de78f6e7f 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -81,13 +81,6 @@ use ast::{_mod, add, arg, arm, attribute, export Parser; -// FIXME (#3726): #ast expects to find this here but it's actually -// defined in `parse` Fixing this will be easier when we have export -// decls on individual items -- then parse can export this publicly, and -// everything else crate-visibly. -use parse::parse_from_source_str; -export parse_from_source_str; - export item_or_view_item, iovi_none, iovi_view_item, iovi_item; enum restriction { diff --git a/src/libsyntax/syntax.rc b/src/libsyntax/syntax.rc index 66052767bd4d7..c85b033be84e4 100644 --- a/src/libsyntax/syntax.rc +++ b/src/libsyntax/syntax.rc @@ -75,9 +75,6 @@ mod ext { #[legacy_exports] #[path = "ext/expand.rs"] mod expand; - #[legacy_exports] - #[path = "ext/qquote.rs"] - mod qquote; #[path = "ext/quote.rs"] mod quote; diff --git a/src/test/compile-fail/qquote-1.rs b/src/test/compile-fail/qquote-1.rs index 2f854c57a0755..a343158337d09 100644 --- a/src/test/compile-fail/qquote-1.rs +++ b/src/test/compile-fail/qquote-1.rs @@ -21,36 +21,44 @@ use syntax::codemap; use syntax::parse; use syntax::print::*; -fn new_parse_sess() -> parse::parse_sess { - fail; -} trait fake_ext_ctxt { - fn session() -> fake_session; + fn cfg() -> ast::crate_cfg; + fn parse_sess() -> parse::parse_sess; + fn call_site() -> span; + fn ident_of(st: ~str) -> ast::ident; } -type fake_options = {cfg: ast::crate_cfg}; - -type fake_session = {opts: @fake_options, - parse_sess: parse::parse_sess}; +type fake_session = parse::parse_sess; impl fake_session: fake_ext_ctxt { - fn session() -> fake_session {self} + 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) + } } fn mk_ctxt() -> fake_ext_ctxt { - let opts : fake_options = {cfg: ~[]}; - {opts: @opts, parse_sess: new_parse_sess()} as fake_ext_ctxt + parse::new_parse_sess(None) as fake_ext_ctxt } + fn main() { let ext_cx = mk_ctxt(); - let abc = #ast{23}; + let abc = quote_expr!(23); check_pp(abc, pprust::print_expr, "23"); - let expr3 = #ast{2 - $(abcd) + 7}; //~ ERROR unresolved name: abcd + let expr3 = quote_expr!(2 - $abcd + 7); //~ ERROR unresolved name: abcd check_pp(expr3, pprust::print_expr, "2 - 23 + 7"); } diff --git a/src/test/compile-fail/qquote-2.rs b/src/test/compile-fail/qquote-2.rs index 1abb8a8fa696a..b7e33f99e3b48 100644 --- a/src/test/compile-fail/qquote-2.rs +++ b/src/test/compile-fail/qquote-2.rs @@ -8,9 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// xfail-test Can't use syntax crate here extern mod std; -use syntax; +extern mod syntax; use std::io::*; @@ -20,33 +21,39 @@ use syntax::codemap; use syntax::parse::parser; use syntax::print::*; -fn new_parse_sess() -> parser::parse_sess { - fail; -} - trait fake_ext_ctxt { - fn session() -> fake_session; + fn cfg() -> ast::crate_cfg; + fn parse_sess() -> parse::parse_sess; + fn call_site() -> span; + fn ident_of(st: ~str) -> ast::ident; } -type fake_options = {cfg: ast::crate_cfg}; - -type fake_session = {opts: @fake_options, - parse_sess: parser::parse_sess}; +type fake_session = parse::parse_sess; impl fake_session: fake_ext_ctxt { - fn session() -> fake_session {self} + 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) + } } fn mk_ctxt() -> fake_ext_ctxt { - let opts : fake_options = {cfg: ~[]}; - {opts: @opts, parse_sess: new_parse_sess()} as fake_ext_ctxt + parse::new_parse_sess(None) as fake_ext_ctxt } fn main() { let ext_cx = mk_ctxt(); - let stmt = #ast[stmt]{let x int = 20;}; //~ ERROR expected end-of-string + let stmt = quote_stmt!(let x int = 20;); //~ ERROR expected end-of-string check_pp(*stmt, pprust::print_stmt, ""); } diff --git a/src/test/run-pass-fulldeps/issue-1926.rs b/src/test/run-pass-fulldeps/issue-1926.rs index 03cd6d3fed41b..7d52f13b0750a 100644 --- a/src/test/run-pass-fulldeps/issue-1926.rs +++ b/src/test/run-pass-fulldeps/issue-1926.rs @@ -55,8 +55,8 @@ fn mk_ctxt() -> fake_ext_ctxt { fn main() { let ext_cx = mk_ctxt(); - let s = #ast[expr]{__s}; - let e = #ast[expr]{__e}; - let f = #ast[expr]{$(s).foo {|__e| $(e)}}; + let s = quote_expr!(__s); + let e = quote_expr!(__e); + let f = quote_expr!($s.foo {|__e| $e}); log(error, pprust::expr_to_str(f)); } diff --git a/src/test/run-pass-fulldeps/qquote.rs b/src/test/run-pass-fulldeps/qquote.rs index e3b7928b7ac5a..3345dcaaad02a 100644 --- a/src/test/run-pass-fulldeps/qquote.rs +++ b/src/test/run-pass-fulldeps/qquote.rs @@ -20,12 +20,16 @@ use io::*; use syntax::diagnostic; use syntax::ast; use syntax::codemap; +use syntax::codemap::span; use syntax::parse; use syntax::print::*; + 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; } type fake_session = parse::parse_sess; @@ -33,66 +37,41 @@ 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(@copy st) + } } fn mk_ctxt() -> fake_ext_ctxt { parse::new_parse_sess(None) as fake_ext_ctxt } - fn main() { let ext_cx = mk_ctxt(); - let abc = #ast{23}; + let abc = quote_expr!(23); check_pp(ext_cx, abc, pprust::print_expr, ~"23"); - let expr3 = #ast{2 - $(abc) + 7}; - check_pp(ext_cx, expr3, pprust::print_expr, ~"2 - 23 + 7"); - - let expr4 = #ast{2 - $(#ast{3}) + 9}; - check_pp(ext_cx, expr4, pprust::print_expr, ~"2 - 3 + 9"); - let ty = #ast[ty]{int}; + let ty = quote_ty!(int); check_pp(ext_cx, ty, pprust::print_type, ~"int"); - let ty2 = #ast[ty]{option<$(ty)>}; - check_pp(ext_cx, ty2, pprust::print_type, ~"option"); - - let item = #ast[item]{const x : int = 10;}; + let item = quote_item!(const x : int = 10;).get(); check_pp(ext_cx, item, pprust::print_item, ~"const x: int = 10;"); - let item2: @ast::item = #ast[item]{const x : int = $(abc);}; - check_pp(ext_cx, item2, pprust::print_item, ~"const x: int = 23;"); - - let stmt = #ast[stmt]{let x = 20;}; + let stmt = quote_stmt!(let x = 20;); check_pp(ext_cx, *stmt, pprust::print_stmt, ~"let x = 20;"); - let stmt2 = #ast[stmt]{let x : $(ty) = $(abc);}; - check_pp(ext_cx, *stmt2, pprust::print_stmt, ~"let x: int = 23;"); - - let pat = #ast[pat]{some(_)}; + let pat = quote_pat!(some(_)); check_pp(ext_cx, pat, pprust::print_refutable_pat, ~"some(_)"); - // issue #1785 - let x = #ast{1}; - let test1 = #ast{1+$(x)}; - check_pp(ext_cx, test1, pprust::print_expr, ~"1 + 1"); - - let test2 = #ast{$(x)+1}; - check_pp(ext_cx, test2, pprust::print_expr, ~"1 + 1"); - - let y = #ast{2}; - let test3 = #ast{$(x) + $(y)}; - check_pp(ext_cx, test3, pprust::print_expr, ~"1 + 2"); - - let crate = #ast[crate] { fn a() { } }; - check_pp(ext_cx, crate, pprust::print_crate_, ~"fn a() { }\n"); - - // issue #1926 - let s = #ast[expr]{__s}; - let e = #ast[expr]{__e}; - let call = #ast[expr]{$(s).foo(|__e| $(e) )}; - check_pp(ext_cx, call, pprust::print_expr, ~"__s.foo(|__e| __e)") } fn check_pp(cx: fake_ext_ctxt, From e24ae85025e40aa17915f6c604d89aefbca274bd Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Wed, 12 Dec 2012 12:25:40 -0800 Subject: [PATCH 2/3] syntax: remove most code handling old-style syntax extensions. --- src/libsyntax/ast.rs | 6 - src/libsyntax/ext/base.rs | 17 +- src/libsyntax/ext/expand.rs | 97 +-- src/libsyntax/ext/quote.rs | 1 - src/libsyntax/ext/simplext.rs | 750 ------------------ src/libsyntax/fold.rs | 7 - src/libsyntax/parse/attr.rs | 35 - src/libsyntax/parse/lexer.rs | 5 - src/libsyntax/parse/parser.rs | 112 +-- src/libsyntax/parse/token.rs | 8 - src/libsyntax/print/pprust.rs | 16 - src/libsyntax/syntax.rc | 3 - src/libsyntax/visit.rs | 11 +- src/test/compile-fail/issue-1448-1.rs | 17 - src/test/compile-fail/macro-2.rs | 20 - src/test/compile-fail/macro.rs | 18 - src/test/run-pass/macro-3.rs | 22 - src/test/run-pass/macro-by-example-1.rs | 24 - src/test/run-pass/macro-by-example-2.rs | 60 -- src/test/run-pass/macro.rs | 21 - .../includeme.fragment | 6 +- 21 files changed, 30 insertions(+), 1226 deletions(-) delete mode 100644 src/libsyntax/ext/simplext.rs delete mode 100644 src/test/compile-fail/issue-1448-1.rs delete mode 100644 src/test/compile-fail/macro-2.rs delete mode 100644 src/test/compile-fail/macro.rs delete mode 100644 src/test/run-pass/macro-3.rs delete mode 100644 src/test/run-pass/macro-by-example-1.rs delete mode 100644 src/test/run-pass/macro-by-example-2.rs delete mode 100644 src/test/run-pass/macro.rs diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index b36555e01ef7e..160dc43a3b91e 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -842,13 +842,7 @@ type mac_body = Option; #[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; diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 10e42a6facfa5..08f8746c45e2a 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -16,16 +16,16 @@ use ast_util::dummy_sp; // obsolete old-style #macro code: // -// syntax_expander, normal, macro_defining, macro_definer, -// builtin +// syntax_expander, normal, 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. +// 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. // second argument is the span to blame for general argument problems type syntax_expander_ = @@ -35,10 +35,6 @@ type syntax_expander = {expander: syntax_expander_, span: Option}; 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]; @@ -63,9 +59,6 @@ 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 item_decorator(item_decorator), @@ -89,8 +82,6 @@ fn syntax_expander_table() -> HashMap<~str, 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)); diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 489a1cb3c2205..391edbbb7993e 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -10,7 +10,7 @@ use std::map::HashMap; -use ast::{crate, expr_, expr_mac, mac_invoc, mac_invoc_tt, +use ast::{crate, expr_, expr_mac, mac_invoc_tt, tt_delim, tt_tok, item_mac, stmt_, stmt_mac, stmt_expr, stmt_semi}; use fold::*; use ext::base::*; @@ -31,51 +31,6 @@ fn expand_expr(exts: HashMap<~str, syntax_extension>, cx: ext_ctxt, expr_mac(ref mac) => { match (*mac).node { - // Old-style macros. For compatibility, will erase this whole - // block once we've transitioned. - mac_invoc(pth, args, body) => { - assert (vec::len(pth.idents) > 0u); - /* using idents and token::special_idents would make the - the macro names be hygienic */ - let extname = cx.parse_sess().interner.get(pth.idents[0]); - match exts.find(*extname) { - None => { - cx.span_fatal(pth.span, - fmt!("macro undefined: '%s'", *extname)) - } - Some(item_decorator(_)) => { - cx.span_fatal( - pth.span, - fmt!("%s can only be used as a decorator", *extname)); - } - Some(normal({expander: exp, span: exp_sp})) => { - - cx.bt_push(ExpandedFrom({call_site: s, - callie: {name: *extname, span: exp_sp}})); - let expanded = exp(cx, (*mac).span, args, body); - - //keep going, outside-in - let fully_expanded = fld.fold_expr(expanded).node; - cx.bt_pop(); - - (fully_expanded, s) - } - Some(macro_defining(ext)) => { - let named_extension = ext(cx, (*mac).span, args, body); - exts.insert(named_extension.name, 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)) - } - Some(item_tt(*)) => { - cx.span_fatal(pth.span, - ~"cannot use item macros in this context"); - } - } - } // Token-tree macros, these will be the only case when we're // finished transitioning. @@ -130,7 +85,6 @@ fn expand_expr(exts: HashMap<~str, syntax_extension>, cx: ext_ctxt, } } - _ => cx.span_bug((*mac).span, ~"naked syntactic bit") } } _ => orig(e, s, fld) @@ -165,8 +119,8 @@ fn expand_mod_items(exts: HashMap<~str, syntax_extension>, cx: ext_ctxt, ast::meta_list(ref n, _) => (*n) }; match exts.find(mname) { - None | Some(normal(_)) | Some(macro_defining(_)) - | Some(normal_tt(_)) | Some(item_tt(*)) => items, + None | Some(normal(_)) + | Some(normal_tt(_)) | Some(item_tt(*)) => items, Some(item_decorator(dec_fn)) => { cx.bt_push(ExpandedFrom({call_site: attr.span, callie: {name: copy mname, @@ -209,36 +163,16 @@ fn expand_item(exts: HashMap<~str, syntax_extension>, } } -// avoid excess indentation when a series of nested `match`es -// has only one "good" outcome -macro_rules! biased_match ( - ( ($e :expr) ~ ($p :pat) else $err :stmt ; - $( ($e_cdr:expr) ~ ($p_cdr:pat) else $err_cdr:stmt ; )* - => $body:expr - ) => ( - match $e { - $p => { - biased_match!($( ($e_cdr) ~ ($p_cdr) else $err_cdr ; )* - => $body) - } - _ => { $err } - } - ); - ( => $body:expr ) => ( $body ) -) - - // Support for item-position macro invocations, exactly the same // logic as for expression-position macro invocations. fn expand_item_mac(exts: HashMap<~str, syntax_extension>, cx: ext_ctxt, &&it: @ast::item, fld: ast_fold) -> Option<@ast::item> { - let (pth, tts) = biased_match!( - (it.node) ~ (item_mac({node: mac_invoc_tt(pth, ref tts), _})) else { - cx.span_bug(it.span, ~"invalid item macro invocation") - }; - => (pth, (*tts)) - ); + + let (pth, tts) = match it.node { + item_mac({node: mac_invoc_tt(pth, ref tts), _}) => (pth, (*tts)), + _ => cx.span_bug(it.span, ~"invalid item macro invocation") + }; let extname = cx.parse_sess().interner.get(pth.idents[0]); let expanded = match exts.find(*extname) { @@ -293,12 +227,15 @@ fn expand_stmt(exts: HashMap<~str, syntax_extension>, cx: ext_ctxt, orig: fn@(&&s: stmt_, span, ast_fold) -> (stmt_, span)) -> (stmt_, span) { - let (mac, pth, tts, semi) = biased_match! ( - (s) ~ (stmt_mac(ref mac, semi)) else return orig(s, sp, fld); - ((*mac).node) ~ (mac_invoc_tt(pth, ref tts)) else { - cx.span_bug((*mac).span, ~"naked syntactic bit") - }; - => ((*mac), pth, (*tts), semi)); + + let (mac, pth, tts, semi) = match s { + stmt_mac(ref mac, semi) => { + match (*mac).node { + mac_invoc_tt(pth, ref tts) => ((*mac), pth, (*tts), semi) + } + } + _ => return orig(s, sp, fld) + }; assert(vec::len(pth.idents) == 1u); let extname = cx.parse_sess().interner.get(pth.idents[0]); diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index 60918121e9547..1e5d4ea8d16f8 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -406,7 +406,6 @@ fn mk_token(cx: ext_ctxt, sp: span, tok: token::Token) -> @ast::expr { AT => "AT", DOT => "DOT", DOTDOT => "DOTDOT", - ELLIPSIS => "ELLIPSIS", COMMA => "COMMA", SEMI => "SEMI", COLON => "COLON", diff --git a/src/libsyntax/ext/simplext.rs b/src/libsyntax/ext/simplext.rs deleted file mode 100644 index f13c5c9aff9ea..0000000000000 --- a/src/libsyntax/ext/simplext.rs +++ /dev/null @@ -1,750 +0,0 @@ -// Copyright 2012 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use codemap::span; -use std::map::HashMap; -use dvec::DVec; - -use base::*; - -use fold::*; -use ast_util::respan; -use ast::{ident, path, Ty, blk_, expr, expr_path, - expr_vec, expr_mac, mac_invoc, node_id, expr_index}; - -export add_new_extension; - -fn path_to_ident(pth: @path) -> Option { - if vec::len(pth.idents) == 1u && vec::len(pth.types) == 0u { - return Some(pth.idents[0u]); - } - return None; -} - -//a vec of binders might be a little big. -type clause = {params: binders, body: @expr}; - -/* logically, an arb_depth should contain only one kind of matchable */ -enum arb_depth { leaf(T), seq(@~[arb_depth], span), } - - -enum matchable { - match_expr(@expr), - match_path(@path), - match_ident(ast::spanned), - match_ty(@Ty), - match_block(ast::blk), - match_exact, /* don't bind anything, just verify the AST traversal */ -} - -/* for when given an incompatible bit of AST */ -fn match_error(cx: ext_ctxt, m: matchable, expected: ~str) -> ! { - match m { - match_expr(x) => cx.span_fatal( - x.span, ~"this argument is an expr, expected " + expected), - match_path(x) => cx.span_fatal( - x.span, ~"this argument is a path, expected " + expected), - match_ident(x) => cx.span_fatal( - x.span, ~"this argument is an ident, expected " + expected), - match_ty(x) => cx.span_fatal( - x.span, ~"this argument is a type, expected " + expected), - match_block(ref x) => cx.span_fatal( - (*x).span, ~"this argument is a block, expected " + expected), - match_exact => cx.bug(~"what is a match_exact doing in a bindings?") - } -} - -// We can't make all the matchables in a match_result the same type because -// idents can be paths, which can be exprs. - -// If we want better match failure error messages (like in Fortifying Syntax), -// we'll want to return something indicating amount of progress and location -// of failure instead of `none`. -type match_result = Option>; -type selector = fn@(matchable) -> match_result; - -fn elts_to_ell(cx: ext_ctxt, elts: ~[@expr]) -> - {pre: ~[@expr], rep: Option<@expr>, post: ~[@expr]} { - let mut idx: uint = 0u; - let mut res = None; - for elts.each |elt| { - match elt.node { - expr_mac(ref m) => match (*m).node { - ast::mac_ellipsis => { - if res.is_some() { - cx.span_fatal((*m).span, ~"only one ellipsis allowed"); - } - res = - Some({pre: vec::slice(elts, 0u, idx - 1u), - rep: Some(elts[idx - 1u]), - post: vec::slice(elts, idx + 1u, vec::len(elts))}); - } - _ => () - }, - _ => () - } - idx += 1u; - } - return match res { - Some(val) => val, - None => {pre: elts, rep: None, post: ~[]} - } -} - -fn option_flatten_map(f: fn@(T) -> Option, v: ~[T]) -> - Option<~[U]> { - let mut res = ~[]; - for v.each |elem| { - match f(*elem) { - None => return None, - Some(ref fv) => res.push((*fv)) - } - } - return Some(res); -} - -fn a_d_map(ad: arb_depth, f: selector) -> match_result { - match ad { - leaf(ref x) => return f((*x)), - seq(ads, span) => match option_flatten_map(|x| a_d_map(x, f), *ads) { - None => return None, - Some(ts) => return Some(seq(@ts, span)) - } - } -} - -fn compose_sels(s1: selector, s2: selector) -> selector { - fn scomp(s1: selector, s2: selector, m: matchable) -> match_result { - return match s1(m) { - None => None, - Some(ref matches) => a_d_map((*matches), s2) - } - } - return { |x| scomp(s1, s2, x) }; -} - - - -type binders = - {real_binders: HashMap, - literal_ast_matchers: DVec}; -type bindings = HashMap>; - -fn acumm_bindings(_cx: ext_ctxt, _b_dest: bindings, _b_src: bindings) { } - -/* these three functions are the big moving parts */ - -/* create the selectors needed to bind and verify the pattern */ - -fn pattern_to_selectors(cx: ext_ctxt, e: @expr) -> binders { - let res: binders = - {real_binders: HashMap(), - literal_ast_matchers: DVec()}; - //this oughta return binders instead, but macro args are a sequence of - //expressions, rather than a single expression - fn trivial_selector(m: matchable) -> match_result { - return Some(leaf(m)); - } - p_t_s_rec(cx, match_expr(e), trivial_selector, res); - move res -} - - - -/* use the selectors on the actual arguments to the macro to extract -bindings. Most of the work is done in p_t_s, which generates the -selectors. */ - -fn use_selectors_to_bind(b: binders, e: @expr) -> Option { - let res = HashMap(); - //need to do this first, to check vec lengths. - for b.literal_ast_matchers.each |sel| { - match (*sel)(match_expr(e)) { None => return None, _ => () } - } - let mut never_mind: bool = false; - for b.real_binders.each |key, val| { - match val(match_expr(e)) { - None => never_mind = true, - Some(ref mtc) => { res.insert(key, (*mtc)); } - } - }; - //HACK: `ret` doesn't work in `for each` - if never_mind { return None; } - return Some(res); -} - -/* use the bindings on the body to generate the expanded code */ - -fn transcribe(cx: ext_ctxt, b: bindings, body: @expr) -> @expr { - let idx_path: @mut ~[uint] = @mut ~[]; - fn new_id(_old: node_id, cx: ext_ctxt) -> node_id { return cx.next_id(); } - fn new_span(cx: ext_ctxt, sp: span) -> span { - /* this discards information in the case of macro-defining macros */ - return span {lo: sp.lo, hi: sp.hi, expn_info: cx.backtrace()}; - } - let afp = default_ast_fold(); - let f_pre = - @{fold_ident: |x,y|transcribe_ident(cx, b, idx_path, x, y), - fold_path: |x,y|transcribe_path(cx, b, idx_path, x, y), - fold_expr: |x,y,z| - transcribe_expr(cx, b, idx_path, x, y, z, afp.fold_expr) - , - fold_ty: |x,y,z| - transcribe_type(cx, b, idx_path, - x, y, z, afp.fold_ty) - , - fold_block: |x,y,z| - transcribe_block(cx, b, idx_path, x, y, z, afp.fold_block) - , - map_exprs: |x,y| - transcribe_exprs(cx, b, idx_path, x, y) - , - new_id: |x|new_id(x, cx), - .. *afp}; - let f = make_fold(f_pre); - let result = f.fold_expr(body); - return result; -} - - -/* helper: descend into a matcher */ -pure fn follow(m: arb_depth, idx_path: &[uint]) -> - arb_depth { - let mut res: arb_depth = m; - for vec::each(idx_path) |idx| { - res = match res { - leaf(_) => return res,/* end of the line */ - seq(new_ms, _) => new_ms[*idx] - } - } - return res; -} - -fn follow_for_trans(cx: ext_ctxt, mmaybe: Option>, - idx_path: @mut ~[uint]) -> Option { - match mmaybe { - None => return None, - Some(ref m) => { - return match follow((*m), *idx_path) { - seq(_, sp) => { - cx.span_fatal(sp, - ~"syntax matched under ... but not " + - ~"used that way.") - } - leaf(ref m) => return Some((*m)) - } - } - } - -} - -/* helper for transcribe_exprs: what vars from `b` occur in `e`? */ -fn free_vars(b: bindings, e: @expr, it: fn(ident)) { - let idents = HashMap(); - fn mark_ident(&&i: ident, _fld: ast_fold, b: bindings, - idents: HashMap) -> ident { - if b.contains_key(i) { idents.insert(i, ()); } - return i; - } - // using fold is a hack: we want visit, but it doesn't hit idents ) : - // solve this with macros - let f_pre = - @{fold_ident: |x,y|mark_ident(x, y, b, idents), - .. *default_ast_fold()}; - let f = make_fold(f_pre); - f.fold_expr(e); // ignore result - for idents.each_key |x| { it(x); }; -} - -fn wrong_occurs(cx: ext_ctxt, l: ident, l_c: uint, r: ident, r_c: uint) - -> ~str { - fmt!("'%s' occurs %u times, but '%s' occurs %u times", - *cx.parse_sess().interner.get(l), l_c, - *cx.parse_sess().interner.get(r), r_c) -} - -/* handle sequences (anywhere in the AST) of exprs, either real or ...ed */ -fn transcribe_exprs(cx: ext_ctxt, b: bindings, idx_path: @mut ~[uint], - recur: fn@(&&v: @expr) -> @expr, - exprs: ~[@expr]) -> ~[@expr] { - match elts_to_ell(cx, exprs) { - {pre: pre, rep: repeat_me_maybe, post: post} => { - let mut res = vec::map(pre, |x| recur(*x)); - match repeat_me_maybe { - None => (), - Some(repeat_me) => { - let mut repeat: Option<{rep_count: uint, name: ident}> = None; - /* we need to walk over all the free vars in lockstep, except for - the leaves, which are just duplicated */ - do free_vars(b, repeat_me) |fv| { - let fv_depth = b.get(fv); - let cur_pos = follow(fv_depth, *idx_path); - match cur_pos { - leaf(_) => (), - seq(ms, _) => { - match repeat { - None => { - repeat = Some({rep_count: vec::len(*ms), name: fv}); - } - Some({rep_count: old_len, name: old_name}) => { - let len = vec::len(*ms); - if old_len != len { - let msg = wrong_occurs(cx, fv, len, - old_name, old_len); - cx.span_fatal(repeat_me.span, msg); - } - } - } - } - } - }; - match repeat { - None => { - cx.span_fatal(repeat_me.span, - ~"'...' surrounds an expression without any" + - ~" repeating syntax variables"); - } - Some({rep_count: rc, _}) => { - /* Whew, we now know how how many times to repeat */ - let mut idx: uint = 0u; - while idx < rc { - idx_path.push(idx); - res.push(recur(repeat_me)); // whew! - idx_path.pop(); - idx += 1u; - } - } - } - } - } - res = vec::append(res, vec::map(post, |x| recur(*x))); - return res; - } - } -} - - - -// substitute, in a position that's required to be an ident -fn transcribe_ident(cx: ext_ctxt, b: bindings, idx_path: @mut ~[uint], - &&i: ident, _fld: ast_fold) -> ident { - return match follow_for_trans(cx, b.find(i), idx_path) { - Some(match_ident(a_id)) => a_id.node, - Some(ref m) => match_error(cx, (*m), ~"an identifier"), - None => i - } -} - - -fn transcribe_path(cx: ext_ctxt, b: bindings, idx_path: @mut ~[uint], - p: path, _fld: ast_fold) -> path { - // Don't substitute into qualified names. - if vec::len(p.types) > 0u || vec::len(p.idents) != 1u { return p; } - match follow_for_trans(cx, b.find(p.idents[0]), idx_path) { - Some(match_ident(id)) => { - {span: id.span, global: false, idents: ~[id.node], - rp: None, types: ~[]} - } - Some(match_path(a_pth)) => *a_pth, - Some(ref m) => match_error(cx, (*m), ~"a path"), - None => p - } -} - - -fn transcribe_expr(cx: ext_ctxt, b: bindings, idx_path: @mut ~[uint], - e: ast::expr_, s: span, fld: ast_fold, - orig: fn@(ast::expr_, span, ast_fold)->(ast::expr_, span)) - -> (ast::expr_, span) -{ - return match e { - expr_path(p) => { - // Don't substitute into qualified names. - if vec::len(p.types) > 0u || vec::len(p.idents) != 1u { - (e, s); - } - match follow_for_trans(cx, b.find(p.idents[0]), idx_path) { - Some(match_ident(id)) => { - (expr_path(@{span: id.span, - global: false, - idents: ~[id.node], - rp: None, - types: ~[]}), id.span) - } - Some(match_path(a_pth)) => (expr_path(a_pth), s), - Some(match_expr(a_exp)) => (a_exp.node, a_exp.span), - Some(ref m) => match_error(cx, (*m), ~"an expression"), - None => orig(e, s, fld) - } - } - _ => orig(e, s, fld) - } -} - -fn transcribe_type(cx: ext_ctxt, b: bindings, idx_path: @mut ~[uint], - t: ast::ty_, s: span, fld: ast_fold, - orig: fn@(ast::ty_, span, ast_fold) -> (ast::ty_, span)) - -> (ast::ty_, span) -{ - return match t { - ast::ty_path(pth, _) => { - match path_to_ident(pth) { - Some(id) => { - match follow_for_trans(cx, b.find(id), idx_path) { - Some(match_ty(ty)) => (ty.node, ty.span), - Some(ref m) => match_error(cx, (*m), ~"a type"), - None => orig(t, s, fld) - } - } - None => orig(t, s, fld) - } - } - _ => orig(t, s, fld) - } -} - - -/* for parsing reasons, syntax variables bound to blocks must be used like -`{v}` */ - -fn transcribe_block(cx: ext_ctxt, b: bindings, idx_path: @mut ~[uint], - blk: blk_, s: span, fld: ast_fold, - orig: fn@(blk_, span, ast_fold) -> (blk_, span)) - -> (blk_, span) -{ - return match block_to_ident(blk) { - Some(id) => { - match follow_for_trans(cx, b.find(id), idx_path) { - Some(match_block(ref new_blk)) => { - ((*new_blk).node, (*new_blk).span) - } - - // possibly allow promotion of ident/path/expr to blocks? - Some(ref m) => match_error(cx, (*m), ~"a block"), - None => orig(blk, s, fld) - } - } - None => orig(blk, s, fld) - } -} - - -/* traverse the pattern, building instructions on how to bind the actual -argument. ps accumulates instructions on navigating the tree.*/ -fn p_t_s_rec(cx: ext_ctxt, m: matchable, s: selector, b: binders) { - - //it might be possible to traverse only exprs, not matchables - match m { - match_expr(e) => { - match e.node { - expr_path(p_pth) => p_t_s_r_path(cx, p_pth, s, b), - expr_vec(p_elts, _) => { - match elts_to_ell(cx, p_elts) { - {pre: pre, rep: Some(repeat_me), post: post} => { - p_t_s_r_length(cx, vec::len(pre) + vec::len(post), true, s, - b); - if vec::len(pre) > 0u { - p_t_s_r_actual_vector(cx, pre, true, s, b); - } - p_t_s_r_ellipses(cx, repeat_me, vec::len(pre), s, b); - - if vec::len(post) > 0u { - cx.span_unimpl(e.span, - ~"matching after `...` not yet supported"); - } - } - {pre: pre, rep: None, post: post} => { - if post.len() > 0 { - cx.bug(~"elts_to_ell provided an invalid result"); - } - p_t_s_r_length(cx, vec::len(pre), false, s, b); - p_t_s_r_actual_vector(cx, pre, false, s, b); - } - } - } - /* FIXME (#2251): handle embedded types and blocks, at least */ - expr_mac(ref mac) => { - p_t_s_r_mac(cx, (*mac), s, b); - } - _ => { - fn select(cx: ext_ctxt, m: matchable, pat: @expr) -> - match_result { - return match m { - match_expr(e) => { - if managed::ptr_eq(e, pat) { - // XXX: Is this right? - Some(leaf(match_exact)) - } else { - None - } - } - _ => cx.bug(~"broken traversal in p_t_s_r") - } - } - b.literal_ast_matchers.push(|x| select(cx, x, e)); - } - } - } - _ => cx.bug(~"undocumented invariant in p_t_s_rec") - } -} - - -/* make a match more precise */ -fn specialize_match(m: matchable) -> matchable { - return match m { - match_expr(e) => { - match e.node { - expr_path(pth) => { - match path_to_ident(pth) { - Some(id) => match_ident(respan(pth.span, id)), - None => match_path(pth) - } - } - _ => m - } - } - _ => m - } -} - -/* pattern_to_selectors helper functions */ -fn p_t_s_r_path(cx: ext_ctxt, p: @path, s: selector, b: binders) { - match path_to_ident(p) { - Some(p_id) => { - fn select(cx: ext_ctxt, m: matchable) -> match_result { - return match m { - match_expr(*) => Some(leaf(specialize_match(m))), - _ => cx.bug(~"broken traversal in p_t_s_r") - } - } - if b.real_binders.contains_key(p_id) { - cx.span_fatal(p.span, ~"duplicate binding identifier"); - } - b.real_binders.insert(p_id, compose_sels(s, |x| select(cx, x))); - } - None => () - } -} - -fn block_to_ident(blk: blk_) -> Option { - if vec::len(blk.stmts) != 0u { return None; } - return match blk.expr { - Some(expr) => match expr.node { - expr_path(pth) => path_to_ident(pth), - _ => None - }, - None => None - } -} - -fn p_t_s_r_mac(cx: ext_ctxt, mac: ast::mac, _s: selector, _b: binders) { - fn select_pt_1(cx: ext_ctxt, m: matchable, - fn_m: fn(ast::mac) -> match_result) -> match_result { - return match m { - match_expr(e) => match e.node { - expr_mac(ref mac) => fn_m((*mac)), - _ => None - }, - _ => cx.bug(~"broken traversal in p_t_s_r") - } - } - fn no_des(cx: ext_ctxt, sp: span, syn: ~str) -> ! { - cx.span_fatal(sp, ~"destructuring " + syn + ~" is not yet supported"); - } - match mac.node { - ast::mac_ellipsis => cx.span_fatal(mac.span, ~"misused `...`"), - ast::mac_invoc(_, _, _) => no_des(cx, mac.span, ~"macro calls"), - ast::mac_invoc_tt(_, _) => no_des(cx, mac.span, ~"macro calls"), - ast::mac_aq(_,_) => no_des(cx, mac.span, ~"antiquotes"), - ast::mac_var(_) => no_des(cx, mac.span, ~"antiquote variables") - } -} - -fn p_t_s_r_ellipses(cx: ext_ctxt, repeat_me: @expr, offset: uint, s: selector, - b: binders) { - fn select(cx: ext_ctxt, repeat_me: @expr, offset: uint, m: matchable) -> - match_result { - return match m { - match_expr(e) => { - match e.node { - expr_vec(arg_elts, _) => { - let mut elts = ~[]; - let mut idx = offset; - while idx < vec::len(arg_elts) { - elts.push(leaf(match_expr(arg_elts[idx]))); - idx += 1u; - } - - // using repeat_me.span is a little wacky, but the - // error we want to report is one in the macro def - Some(seq(@elts, repeat_me.span)) - } - _ => None - } - } - _ => cx.bug(~"broken traversal in p_t_s_r") - } - } - p_t_s_rec(cx, match_expr(repeat_me), - compose_sels(s, |x| select(cx, repeat_me, offset, x)), b); -} - - -fn p_t_s_r_length(cx: ext_ctxt, len: uint, at_least: bool, s: selector, - b: binders) { - fn len_select(_cx: ext_ctxt, m: matchable, at_least: bool, len: uint) -> - match_result { - return match m { - match_expr(e) => { - match e.node { - expr_vec(arg_elts, _) => { - let actual_len = vec::len(arg_elts); - if at_least && actual_len >= len || actual_len == len { - Some(leaf(match_exact)) - } else { None } - } - _ => None - } - } - _ => None - } - } - b.literal_ast_matchers.push( - compose_sels(s, |x| len_select(cx, x, at_least, len))); -} - -fn p_t_s_r_actual_vector(cx: ext_ctxt, elts: ~[@expr], _repeat_after: bool, - s: selector, b: binders) { - let mut idx: uint = 0u; - while idx < vec::len(elts) { - fn select(cx: ext_ctxt, m: matchable, idx: uint) -> match_result { - return match m { - match_expr(e) => { - match e.node { - expr_vec(arg_elts, _) => { - Some(leaf(match_expr(arg_elts[idx]))) - } - _ => None - } - } - _ => cx.bug(~"broken traversal in p_t_s_r") - } - } - p_t_s_rec(cx, match_expr(elts[idx]), - compose_sels(s, |x, copy idx| select(cx, x, idx)), b); - idx += 1u; - } -} - -fn add_new_extension(cx: ext_ctxt, sp: span, arg: ast::mac_arg, - _body: ast::mac_body) -> base::macro_def { - let args = get_mac_args_no_max(cx, sp, arg, 0u, ~"macro"); - - let mut macro_name: Option<~str> = None; - let mut clauses: ~[@clause] = ~[]; - for args.each |arg| { - match arg.node { - expr_vec(elts, _) => { - if vec::len(elts) != 2u { - cx.span_fatal((*arg).span, - ~"extension clause must consist of ~[" + - ~"macro invocation, expansion body]"); - } - - - match elts[0u].node { - expr_mac(ref mac) => { - match (*mac).node { - mac_invoc(pth, invoc_arg, _) => { - match path_to_ident(pth) { - Some(id) => { - let id_str = cx.str_of(id); - match macro_name { - None => macro_name = Some(id_str), - Some(ref other_id) => if id_str != (*other_id) { - cx.span_fatal(pth.span, - ~"macro name must be " + - ~"consistent"); - } - } - }, - None => cx.span_fatal(pth.span, - ~"macro name must not be a path") - } - let arg = match invoc_arg { - Some(arg) => arg, - None => cx.span_fatal((*mac).span, - ~"macro must have arguments") - }; - clauses.push(@{params: pattern_to_selectors(cx, arg), - body: elts[1u]}); - - // FIXME (#2251): check duplicates (or just simplify - // the macro arg situation) - } - _ => { - cx.span_bug((*mac).span, ~"undocumented invariant in \ - add_extension"); - } - } - } - _ => { - cx.span_fatal(elts[0u].span, - ~"extension clause must" + - ~" start with a macro invocation."); - } - } - } - _ => { - cx.span_fatal((*arg).span, - ~"extension must be ~[clause, " + ~" ...]"); - } - } - } - - let ext = |a,b,c,d, move clauses| generic_extension(a,b,c,d,clauses); - - return {name: - match macro_name { - Some(ref id) => (*id), - None => cx.span_fatal(sp, ~"macro definition must have " + - ~"at least one clause") - }, - ext: normal({expander: ext, span: Some(arg.get().span)})}; - - fn generic_extension(cx: ext_ctxt, sp: span, arg: ast::mac_arg, - _body: ast::mac_body, - clauses: ~[@clause]) -> @expr { - let arg = match arg { - Some(arg) => arg, - None => cx.span_fatal(sp, ~"macro must have arguments") - }; - for clauses.each |c| { - match use_selectors_to_bind(c.params, arg) { - Some(bindings) => return transcribe(cx, bindings, c.body), - None => loop - } - } - cx.span_fatal(sp, ~"no clauses match macro invocation"); - } -} - - - -// -// Local Variables: -// mode: rust -// fill-column: 78; -// indent-tabs-mode: nil -// c-basic-offset: 4 -// buffer-file-coding-system: utf-8-unix -// End: -// diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 110fc664b0704..93845f3dbb859 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -120,14 +120,7 @@ fn fold_arg_(a: arg, fld: ast_fold) -> arg { fn fold_mac_(m: mac, fld: ast_fold) -> mac { return {node: match m.node { - mac_invoc(pth, arg, body) => { - mac_invoc(fld.fold_path(pth), - option::map(&arg, |x| fld.fold_expr(*x)), body) - } mac_invoc_tt(*) => m.node, - mac_ellipsis => mac_ellipsis, - mac_aq(_,_) => /* FIXME (#2543) */ copy m.node, - mac_var(_) => /* FIXME (#2543) */ copy m.node, }, span: fld.new_span(m.span)}; } diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs index 3f0b031bd066b..7248a0e224476 100644 --- a/src/libsyntax/parse/attr.rs +++ b/src/libsyntax/parse/attr.rs @@ -12,16 +12,9 @@ use either::{Either, Left, Right}; use ast_util::spanned; use common::*; //resolve bug? -export attr_or_ext; export parser_attr; -// A type to distingush between the parsing of item attributes or syntax -// extensions, which both begin with token.POUND -type attr_or_ext = Option>; - trait parser_attr { - fn parse_outer_attrs_or_ext(first_item_attrs: ~[ast::attribute]) - -> attr_or_ext; fn parse_outer_attributes() -> ~[ast::attribute]; fn parse_attribute(style: ast::attr_style) -> ast::attribute; fn parse_attribute_naked(style: ast::attr_style, lo: BytePos) -> @@ -35,34 +28,6 @@ trait parser_attr { impl Parser: parser_attr { - fn parse_outer_attrs_or_ext(first_item_attrs: ~[ast::attribute]) - -> attr_or_ext - { - let expect_item_next = vec::is_not_empty(first_item_attrs); - match self.token { - token::POUND => { - let lo = self.span.lo; - if self.look_ahead(1u) == token::LBRACKET { - self.bump(); - let first_attr = - self.parse_attribute_naked(ast::attr_outer, lo); - return Some(Left(vec::append(~[first_attr], - self.parse_outer_attributes()))); - } else if !(self.look_ahead(1u) == token::LT - || self.look_ahead(1u) == token::LBRACKET - || self.look_ahead(1u) == token::POUND - || expect_item_next) { - self.bump(); - return Some(Right(self.parse_syntax_ext_naked(lo))); - } else { return None; } - } - token::DOC_COMMENT(_) => { - return Some(Left(self.parse_outer_attributes())); - } - _ => return None - } - } - // Parse attributes that appear before an item fn parse_outer_attributes() -> ~[ast::attribute] { let mut attrs: ~[ast::attribute] = ~[]; diff --git a/src/libsyntax/parse/lexer.rs b/src/libsyntax/parse/lexer.rs index 3763a74b9d24d..c4e34311b8898 100644 --- a/src/libsyntax/parse/lexer.rs +++ b/src/libsyntax/parse/lexer.rs @@ -515,11 +515,6 @@ fn next_token_inner(rdr: string_reader) -> token::Token { bump(rdr); return token::DOTDOT; } - if rdr.curr == '.' && nextch(rdr) == '.' { - bump(rdr); - bump(rdr); - return token::ELLIPSIS; - } return token::DOT; } '(' => { bump(rdr); return token::LPAREN; } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index ead0de78f6e7f..625ff289607f6 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -54,8 +54,8 @@ use ast::{_mod, add, arg, arm, attribute, item_foreign_mod, item_impl, item_mac, item_mod, item_trait, item_ty, lit, lit_, lit_bool, lit_float, lit_float_unsuffixed, lit_int, lit_int_unsuffixed, lit_nil, lit_str, lit_uint, local, - m_const, m_imm, m_mutbl, mac_, mac_aq, mac_ellipsis, mac_invoc, - mac_invoc_tt, mac_var, matcher, match_nonterminal, match_seq, + m_const, m_imm, m_mutbl, mac_, + mac_invoc_tt, matcher, match_nonterminal, match_seq, match_tok, method, mode, module_ns, mt, mul, mutability, named_field, neg, noreturn, not, pat, pat_box, pat_enum, pat_ident, pat_lit, pat_range, pat_rec, pat_region, pat_struct, @@ -510,15 +510,6 @@ impl Parser { let lo = self.span.lo; - match self.maybe_parse_dollar_mac() { - Some(ref e) => { - return @{id: self.get_id(), - node: ty_mac(spanned(lo, self.span.hi, (*e))), - span: mk_sp(lo, self.span.hi)}; - } - None => () - } - let t = if self.token == token::LPAREN { self.bump(); if self.token == token::RPAREN { @@ -730,32 +721,6 @@ impl Parser { } } - fn maybe_parse_dollar_mac() -> Option { - match copy self.token { - token::DOLLAR => { - let lo = self.span.lo; - self.bump(); - match copy self.token { - token::LIT_INT_UNSUFFIXED(num) => { - self.bump(); - Some(mac_var(num as uint)) - } - token::LPAREN => { - self.bump(); - let e = self.parse_expr(); - self.expect(token::RPAREN); - let hi = self.last_span.hi; - Some(mac_aq(mk_sp(lo,hi), e)) - } - _ => { - self.fatal(~"expected `(` or unsuffixed integer literal"); - } - } - } - _ => None - } - } - fn maybe_parse_fixed_vstore_with_star() -> Option { if self.eat(token::BINOP(token::STAR)) { match copy self.token { @@ -928,11 +893,6 @@ impl Parser { let mut ex: expr_; - match self.maybe_parse_dollar_mac() { - Some(ref x) => return self.mk_mac_expr(lo, self.span.hi, (*x)), - _ => () - } - if self.token == token::LPAREN { self.bump(); if self.token == token::RPAREN { @@ -1022,13 +982,6 @@ impl Parser { } } hi = self.span.hi; - } else if self.token == token::ELLIPSIS { - self.bump(); - return self.mk_mac_expr(lo, self.span.hi, mac_ellipsis); - } else if self.token == token::POUND { - let ex_ext = self.parse_syntax_ext(); - hi = ex_ext.span.hi; - ex = ex_ext.node; } else if self.eat_keyword(~"fail") { if can_begin_expr(self.token) { let e = self.parse_expr(); @@ -1141,54 +1094,6 @@ impl Parser { return self.mk_expr(blk.span.lo, blk.span.hi, expr_block(blk)); } - fn parse_syntax_ext() -> @expr { - let lo = self.span.lo; - self.expect(token::POUND); - return self.parse_syntax_ext_naked(lo); - } - - fn parse_syntax_ext_naked(lo: BytePos) -> @expr { - match self.token { - token::IDENT(_, _) => (), - _ => self.fatal(~"expected a syntax expander name") - } - let pth = self.parse_path_without_tps(); - //temporary for a backwards-compatible cycle: - let sep = seq_sep_trailing_disallowed(token::COMMA); - let mut e = None; - if (self.token == token::LPAREN || self.token == token::LBRACKET) { - let lo = self.span.lo; - let es = - if self.token == token::LPAREN { - self.parse_unspanned_seq(token::LPAREN, token::RPAREN, - sep, |p| p.parse_expr()) - } else { - self.parse_unspanned_seq(token::LBRACKET, token::RBRACKET, - sep, |p| p.parse_expr()) - }; - let hi = self.span.hi; - e = Some(self.mk_expr(lo, hi, expr_vec(es, m_imm))); - } - let mut b = None; - if self.token == token::LBRACE { - self.bump(); - let lo = self.span.lo; - let mut depth = 1u; - while (depth > 0u) { - match (self.token) { - token::LBRACE => depth += 1u, - token::RBRACE => depth -= 1u, - token::EOF => self.fatal(~"unexpected EOF in macro body"), - _ => () - } - self.bump(); - } - let hi = self.last_span.lo; - b = Some({span: mk_sp(lo,hi)}); - } - return self.mk_mac_expr(lo, self.span.hi, mac_invoc(pth, e, b)); - } - fn parse_dot_or_call_expr() -> @expr { let b = self.parse_bottom_expr(); self.parse_dot_or_call_expr_with(b) @@ -2253,17 +2158,8 @@ impl Parser { } } else { - let mut item_attrs; - match self.parse_outer_attrs_or_ext(first_item_attrs) { - None => item_attrs = ~[], - Some(Left(ref attrs)) => item_attrs = (*attrs), - Some(Right(ext)) => { - return @spanned(lo, ext.span.hi, - stmt_expr(ext, self.get_id())); - } - } - - let item_attrs = vec::append(first_item_attrs, item_attrs); + let item_attrs = vec::append(first_item_attrs, + self.parse_outer_attributes()); match self.parse_item_or_view_item(item_attrs, true, false, false) { diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index a0aecd0375eba..7e7c61d2bf249 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -49,7 +49,6 @@ enum Token { AT, DOT, DOTDOT, - ELLIPSIS, COMMA, SEMI, COLON, @@ -137,7 +136,6 @@ fn to_str(in: @ident_interner, t: Token) -> ~str { AT => ~"@", DOT => ~".", DOTDOT => ~"..", - ELLIPSIS => ~"...", COMMA => ~",", SEMI => ~";", COLON => ~":", @@ -578,12 +576,6 @@ impl Token : cmp::Eq { _ => false } } - ELLIPSIS => { - match (*other) { - ELLIPSIS => true, - _ => false - } - } COMMA => { match (*other) { COMMA => true, diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index eda5ca1f91c1a..684f74f3575c4 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -590,9 +590,6 @@ fn print_item(s: ps, &&item: @ast::item) { pclose(s); end(s); } - ast::item_mac(_) => { - fail ~"invalid item-position syntax bit" - } } (s.ann.post)(ann_node); } @@ -1000,16 +997,6 @@ fn print_if(s: ps, test: @ast::expr, blk: ast::blk, fn print_mac(s: ps, m: ast::mac) { match m.node { - ast::mac_invoc(path, arg, _body) => { - word(s.s, ~"#"); - print_path(s, path, false); - match arg { - Some(@{node: ast::expr_vec(_, _), _}) => (), - _ => word(s.s, ~" ") - } - arg.iter(|a| print_expr(s, *a)); - // FIXME: extension 'body' (#2339) - } ast::mac_invoc_tt(pth, ref tts) => { print_path(s, pth, false); word(s.s, ~"!"); @@ -1017,9 +1004,6 @@ fn print_mac(s: ps, m: ast::mac) { for (*tts).each() |tt| { print_tt(s, *tt); } pclose(s); } - ast::mac_ellipsis => word(s.s, ~"..."), - ast::mac_var(v) => word(s.s, fmt!("$%u", v)), - _ => { /* fixme */ } } } diff --git a/src/libsyntax/syntax.rc b/src/libsyntax/syntax.rc index c85b033be84e4..00c3804cce16c 100644 --- a/src/libsyntax/syntax.rc +++ b/src/libsyntax/syntax.rc @@ -99,9 +99,6 @@ mod ext { } - #[legacy_exports] - #[path = "ext/simplext.rs"] - mod simplext; #[legacy_exports] #[path = "ext/fmt.rs"] mod fmt; diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 72a605dcf1168..7b406564114b8 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -379,15 +379,8 @@ fn visit_exprs(exprs: ~[@expr], e: E, v: vt) { for exprs.each |ex| { (v.visit_expr)(*ex, e, v); } } -fn visit_mac(m: mac, e: E, v: vt) { - match m.node { - ast::mac_invoc(_, arg, _) => { - option::map(&arg, |arg| (v.visit_expr)(*arg, e, v)); } - ast::mac_invoc_tt(*) => { /* no user-serviceable parts inside */ } - ast::mac_ellipsis => (), - ast::mac_aq(*) => { /* FIXME: maybe visit (Issue #2340) */ } - ast::mac_var(_) => () - } +fn visit_mac(_m: mac, _e: E, _v: vt) { + /* no user-serviceable parts inside */ } fn visit_expr(ex: @expr, e: E, v: vt) { diff --git a/src/test/compile-fail/issue-1448-1.rs b/src/test/compile-fail/issue-1448-1.rs deleted file mode 100644 index 187956b645af8..0000000000000 --- a/src/test/compile-fail/issue-1448-1.rs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2012 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Regresion test for issue #1448 and #1386 - -fn main() { - #macro[[#apply[f, [x, ...]], f(x, ...)]]; - fn add(a: int, b: int) -> int { return a + b; } - assert (apply!(add, [y, 15]) == 16); //~ ERROR unresolved name: y -} diff --git a/src/test/compile-fail/macro-2.rs b/src/test/compile-fail/macro-2.rs deleted file mode 100644 index 57ed12789ab6e..0000000000000 --- a/src/test/compile-fail/macro-2.rs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2012 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//error-pattern:is an expr, expected a path -fn main() { - #macro[[#mylambda[x, body], - { - fn f(x: int) -> int { return body } - f - }]]; - - assert (mylambda!(y * 1, y * 2)(8) == 16); -} diff --git a/src/test/compile-fail/macro.rs b/src/test/compile-fail/macro.rs deleted file mode 100644 index 43ce05845ec58..0000000000000 --- a/src/test/compile-fail/macro.rs +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2012 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//error-pattern:no clauses match - -fn main() { - #macro[[#trivial[], 1 * 2 * 4 * 2 * 1]]; - - assert (trivial!(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16) == - 16); -} diff --git a/src/test/run-pass/macro-3.rs b/src/test/run-pass/macro-3.rs deleted file mode 100644 index e23651d262cc9..0000000000000 --- a/src/test/run-pass/macro-3.rs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2012 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// xfail-pretty - token trees can't pretty print - -fn main() { - #macro[[#trivial[], 1 * 2 * 4 * 2 * 1]]; - - assert (trivial!() == 16); - - macro_rules! trivial_tt( - () => {1*2*4*2*1} - ) - assert(trivial_tt!() == 16); -} diff --git a/src/test/run-pass/macro-by-example-1.rs b/src/test/run-pass/macro-by-example-1.rs deleted file mode 100644 index 3e8bced1b889c..0000000000000 --- a/src/test/run-pass/macro-by-example-1.rs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2012 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - - -fn main() { - #macro[[#apply[f, [x, ...]], f(x, ...)]]; - - macro_rules! apply_tt( - ($f:expr, ($($x:expr),*)) => {$f($($x),*)} - ) - - fn add(a: int, b: int) -> int { return a + b; } - - assert(apply!(add, [1, 15]) == 16); - assert(apply!(add, [1, 15]) == 16); - assert(apply_tt!(add, (1, 15)) == 16); -} diff --git a/src/test/run-pass/macro-by-example-2.rs b/src/test/run-pass/macro-by-example-2.rs deleted file mode 100644 index 903dc0439e580..0000000000000 --- a/src/test/run-pass/macro-by-example-2.rs +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 2012 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// xfail-test -// I can't for the life of me manage to untangle all of the brackets -// in this test, so I am xfailing it... - -fn main() { - #macro[[#zip_or_unzip[[x, ...], [y, ...]], [[x, y], ...]], - [#zip_or_unzip[[xx, yy], ...], [[xx, ...], [yy, ...]]]]; - - - assert (zip_or_unzip!([1, 2, 3, 4], [5, 6, 7, 8]) == - [[1, 5], [2, 6], [3, 7], [4, 8]]); - assert (zip_or_unzip!([1, 5], [2, 6], [3, 7], [4, 8]) == - [[1, 2, 3, 4], [5, 6, 7, 8]]); - - - #macro[[#nested[[[x, ...], ...], [[y, ...], ...]], [[[x, y], ...], ...]]]; - assert (nested!([[1, 2, 3, 4, 5], [7, 8, 9, 10, 11, 12]], - [[-1, -2, -3, -4, -5], [-7, -8, -9, -10, -11, -12]]) == - [[[1, -1], [2, -2], [3, -3], [4, -4], [5, -5]], - [[7, -7], [8, -8], [9, -9], [10, -10], [11, -11], - [12, -12]]]); - - #macro[[#dup[y, [x, ...]], [[y, x], ...]]]; - - assert (dup!(1, [1, 2, 3, 4]) == [[1, 1], [1, 2], [1, 3], [1, 4]]); - - - #macro[[#lambda[x, #, body, #], - { - fn result(x: t) -> s { return body } - result - }]]; - - - assert (lambda!(i, #, i + 4u, #)(12u) == 16u); - - #macro[[#sum[x, xs, ...], x + #sum[xs, ...]], [#sum[], 0]]; - - assert (sum!(1, 2, 3, 4) == 10); - - - #macro[[#transcr_mixed[a, as, ...], #sum[6, as, ...] * a]]; - - assert (transcr_mixed!(10, 5, 4, 3, 2, 1) == 210); - - #macro[[#surround[pre, [xs, ...], post], [pre, xs, ..., post]]]; - - assert (surround!(1, [2, 3, 4], 5) == [1, 2, 3, 4, 5]); - -} diff --git a/src/test/run-pass/macro.rs b/src/test/run-pass/macro.rs deleted file mode 100644 index f928043150ede..0000000000000 --- a/src/test/run-pass/macro.rs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2012 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// xfail-pretty - token trees can't pretty print - -fn main() { - #macro[[#m1[a], a * 4]]; - assert (m1!(2) == 8); - - macro_rules! m1tt ( - ($a:expr) => {$a*4} - ); - assert(m1tt!(2) == 8); -} diff --git a/src/test/run-pass/syntax-extension-source-utils-files/includeme.fragment b/src/test/run-pass/syntax-extension-source-utils-files/includeme.fragment index 17682fd67fd39..eca0881deafd5 100644 --- a/src/test/run-pass/syntax-extension-source-utils-files/includeme.fragment +++ b/src/test/run-pass/syntax-extension-source-utils-files/includeme.fragment @@ -1,7 +1,7 @@ /* this is for run-pass/syntax-extension-source-utils.rs */ { - assert(#file[].ends_with("includeme.fragment")); - assert(#line[] == 5u); - #fmt["victory robot %u", #line[]] + assert(file!().ends_with("includeme.fragment")); + assert(line!() == 5u); + fmt!("victory robot %u", line!()) } From 9a4c669867765d42bdd13fc09eb9a32b7a667a43 Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Wed, 12 Dec 2012 17:08:09 -0800 Subject: [PATCH 3/3] syntax: remove remaining #syntaxext machinery. Close #3516. --- src/libsyntax/ast.rs | 8 - src/libsyntax/ext/base.rs | 151 ++++++------------ src/libsyntax/ext/concat_idents.rs | 35 ++-- src/libsyntax/ext/env.rs | 17 +- src/libsyntax/ext/expand.rs | 35 +--- src/libsyntax/ext/fmt.rs | 11 +- src/libsyntax/ext/ident_to_str.rs | 20 --- src/libsyntax/ext/source_util.rs | 76 ++++----- src/libsyntax/print/pp.rs | 4 +- src/libsyntax/print/pprust.rs | 35 ++-- src/libsyntax/syntax.rc | 3 - src/test/compile-fail/ext-noname.rs | 15 -- src/test/compile-fail/extenv-no-args.rs | 2 +- src/test/compile-fail/extenv-too-many-args.rs | 2 +- src/test/compile-fail/extfmt-no-args.rs | 2 +- src/test/run-pass/class-attributes-1.rs | 2 +- src/test/run-pass/syntax-extension-minor.rs | 2 +- .../run-pass/syntax-extension-source-utils.rs | 2 +- 18 files changed, 150 insertions(+), 272 deletions(-) delete mode 100644 src/libsyntax/ext/ident_to_str.rs delete mode 100644 src/test/compile-fail/ext-noname.rs diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 160dc43a3b91e..c21aa7d248ea0 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -831,14 +831,6 @@ enum matcher_ { type mac = spanned; -type mac_arg = Option<@expr>; - -#[auto_serialize] -#[auto_deserialize] -type mac_body_ = {span: span}; - -type mac_body = Option; - #[auto_serialize] #[auto_deserialize] enum mac_ { diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 08f8746c45e2a..a5ed1f5e10189 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -13,11 +13,8 @@ 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, builtin -// // new-style macro! tt code: // // syntax_expander_tt, syntax_expander_tt_item, mac_result, @@ -27,12 +24,6 @@ use ast_util::dummy_sp; // is now probably a redundant AST node, can be merged with // ast::mac_invoc_tt. -// 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}; - type macro_def = {name: ~str, ext: syntax_extension}; type item_decorator = @@ -56,10 +47,7 @@ enum mac_result { enum syntax_extension { - // normal() is obsolete, remove when #old_macros go away. - normal(syntax_expander), - - // #[auto_serialize] and such. will probably survive death of #old_macros + // #[auto_serialize] and such item_decorator(item_decorator), // Token-tree expanders @@ -73,8 +61,6 @@ 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}) } @@ -85,18 +71,19 @@ fn syntax_expander_table() -> HashMap<~str, syntax_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)); @@ -122,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( @@ -292,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, 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 } // diff --git a/src/libsyntax/ext/concat_idents.rs b/src/libsyntax/ext/concat_idents.rs index b6fb3a75938af..a47b64bea3af1 100644 --- a/src/libsyntax/ext/concat_idents.rs +++ b/src/libsyntax/ext/concat_idents.rs @@ -10,19 +10,32 @@ use base::*; -fn expand_syntax_ext(cx: ext_ctxt, sp: codemap::span, arg: ast::mac_arg, - _body: ast::mac_body) -> @ast::expr { - let args = get_mac_args_no_max(cx,sp,arg,1u,~"concat_idents"); +fn expand_syntax_ext(cx: ext_ctxt, sp: span, tts: ~[ast::token_tree]) + -> base::mac_result { let mut res_str = ~""; - for args.each |e| { - res_str += *cx.parse_sess().interner.get( - expr_to_ident(cx, *e, ~"expected an ident")); + for tts.eachi |i, e| { + if i & 1 == 1 { + match *e { + ast::tt_tok(_, token::COMMA) => (), + _ => cx.span_fatal(sp, ~"concat_idents! \ + expecting comma.") + } + } else { + match *e { + ast::tt_tok(_, token::IDENT(ident,_)) => + res_str += cx.str_of(ident), + _ => cx.span_fatal(sp, ~"concat_idents! \ + requires ident args.") + } + } } let res = cx.parse_sess().interner.intern(@res_str); - return @{id: cx.next_id(), - callee_id: cx.next_id(), - node: ast::expr_path(@{span: sp, global: false, idents: ~[res], - rp: None, types: ~[]}), - span: sp}; + let e = @{id: cx.next_id(), + callee_id: cx.next_id(), + node: ast::expr_path(@{span: sp, global: false, + idents: ~[res], + rp: None, types: ~[]}), + span: sp}; + mr_expr(e) } diff --git a/src/libsyntax/ext/env.rs b/src/libsyntax/ext/env.rs index 51db63c819aef..68db1b41781e4 100644 --- a/src/libsyntax/ext/env.rs +++ b/src/libsyntax/ext/env.rs @@ -18,18 +18,19 @@ use base::*; use build::mk_uniq_str; export expand_syntax_ext; -fn expand_syntax_ext(cx: ext_ctxt, sp: codemap::span, arg: ast::mac_arg, - _body: ast::mac_body) -> @ast::expr { - let args = get_mac_args(cx, sp, arg, 1u, option::Some(1u), ~"env"); +fn expand_syntax_ext(cx: ext_ctxt, sp: span, tts: ~[ast::token_tree]) + -> base::mac_result { + + let var = get_single_str_from_tts(cx, sp, tts, "env!"); // FIXME (#2248): if this was more thorough it would manufacture an // Option rather than just an maybe-empty string. - let var = expr_to_str(cx, args[0], ~"env! requires a string"); - match os::getenv(var) { - option::None => return mk_uniq_str(cx, sp, ~""), - option::Some(ref s) => return mk_uniq_str(cx, sp, (*s)) - } + let e = match os::getenv(var) { + option::None => mk_uniq_str(cx, sp, ~""), + option::Some(ref s) => mk_uniq_str(cx, sp, (*s)) + }; + mr_expr(e) } // diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 391edbbb7993e..a35f351451bdc 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -62,21 +62,6 @@ fn expand_expr(exts: HashMap<~str, syntax_extension>, cx: ext_ctxt, (fully_expanded, s) } - Some(normal({expander: exp, span: exp_sp})) => { - cx.bt_push(ExpandedFrom({call_site: s, - callie: {name: *extname, span: exp_sp}})); - - //convert the new-style invoc for the old-style macro - let arg = base::tt_args_to_original_flavor(cx, pth.span, - (*tts)); - let expanded = exp(cx, (*mac).span, arg, None); - - //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", @@ -119,8 +104,7 @@ fn expand_mod_items(exts: HashMap<~str, syntax_extension>, cx: ext_ctxt, ast::meta_list(ref n, _) => (*n) }; match exts.find(mname) { - None | Some(normal(_)) - | Some(normal_tt(_)) | Some(item_tt(*)) => items, + None | Some(normal_tt(_)) | Some(item_tt(*)) => items, Some(item_decorator(dec_fn)) => { cx.bt_push(ExpandedFrom({call_site: attr.span, callie: {name: copy mname, @@ -262,23 +246,6 @@ fn expand_stmt(exts: HashMap<~str, syntax_extension>, cx: ext_ctxt, (fully_expanded, sp) } - Some(normal({expander: exp, span: exp_sp})) => { - cx.bt_push(ExpandedFrom({call_site: sp, - callie: {name: *extname, - span: exp_sp}})); - //convert the new-style invoc for the old-style macro - let arg = base::tt_args_to_original_flavor(cx, pth.span, tts); - let exp_expr = exp(cx, mac.span, arg, None); - let expanded = @{node: stmt_expr(exp_expr, cx.next_id()), - span: exp_expr.span}; - - //keep going, outside-in - let fully_expanded = fld.fold_stmt(expanded).node; - cx.bt_pop(); - - (fully_expanded, sp) - } - _ => { cx.span_fatal(pth.span, fmt!("'%s' is not a tt-style macro", *extname)) diff --git a/src/libsyntax/ext/fmt.rs b/src/libsyntax/ext/fmt.rs index e0d3bd03f42a4..46003624a76e5 100644 --- a/src/libsyntax/ext/fmt.rs +++ b/src/libsyntax/ext/fmt.rs @@ -21,9 +21,12 @@ use codemap::span; use ext::build::*; export expand_syntax_ext; -fn expand_syntax_ext(cx: ext_ctxt, sp: span, arg: ast::mac_arg, - _body: ast::mac_body) -> @ast::expr { - let args = get_mac_args_no_max(cx, sp, arg, 1u, ~"fmt"); +fn expand_syntax_ext(cx: ext_ctxt, sp: span, tts: ~[ast::token_tree]) + -> base::mac_result { + let args = get_exprs_from_tts(cx, copy tts); + if args.len() == 0 { + cx.span_fatal(sp, "fmt! takes at least 1 argument."); + } let fmt = expr_to_str(cx, args[0], ~"first argument to fmt! must be a string literal."); @@ -37,7 +40,7 @@ fn expand_syntax_ext(cx: ext_ctxt, sp: span, arg: ast::mac_arg, parse_fmt_err_(cx, fmtspan, s) }; let pieces = parse_fmt_string(fmt, parse_fmt_err); - return pieces_to_expr(cx, sp, pieces, args); + mr_expr(pieces_to_expr(cx, sp, pieces, args)) } // FIXME (#2249): A lot of these functions for producing expressions can diff --git a/src/libsyntax/ext/ident_to_str.rs b/src/libsyntax/ext/ident_to_str.rs deleted file mode 100644 index ededc1a5f7ffc..0000000000000 --- a/src/libsyntax/ext/ident_to_str.rs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2012 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use base::*; -use build::mk_uniq_str; - -fn expand_syntax_ext(cx: ext_ctxt, sp: codemap::span, arg: ast::mac_arg, - _body: ast::mac_body) -> @ast::expr { - let args = get_mac_args(cx,sp,arg,1u,option::Some(1u),~"ident_to_str"); - - return mk_uniq_str(cx, sp, *cx.parse_sess().interner.get( - expr_to_ident(cx, args[0u], ~"expected an ident"))); -} diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs index aa97646c05429..8d2b9163f152f 100644 --- a/src/libsyntax/ext/source_util.rs +++ b/src/libsyntax/ext/source_util.rs @@ -23,63 +23,58 @@ export expand_include_str; export expand_include_bin; /* line!(): expands to the current line number */ -fn expand_line(cx: ext_ctxt, sp: span, arg: ast::mac_arg, - _body: ast::mac_body) -> @ast::expr { - get_mac_args(cx, sp, arg, 0u, option::Some(0u), ~"line"); +fn expand_line(cx: ext_ctxt, sp: span, tts: ~[ast::token_tree]) + -> base::mac_result { + base::check_zero_tts(cx, sp, tts, "line!"); let loc = cx.codemap().lookup_char_pos(sp.lo); - return mk_uint(cx, sp, loc.line); + base::mr_expr(mk_uint(cx, sp, loc.line)) } /* col!(): expands to the current column number */ -fn expand_col(cx: ext_ctxt, sp: span, arg: ast::mac_arg, - _body: ast::mac_body) -> @ast::expr { - get_mac_args(cx, sp, arg, 0u, option::Some(0u), ~"col"); +fn expand_col(cx: ext_ctxt, sp: span, tts: ~[ast::token_tree]) + -> base::mac_result { + base::check_zero_tts(cx, sp, tts, "col!"); let loc = cx.codemap().lookup_char_pos(sp.lo); - return mk_uint(cx, sp, loc.col.to_uint()); + base::mr_expr(mk_uint(cx, sp, loc.col.to_uint())) } /* file!(): expands to the current filename */ /* The filemap (`loc.file`) contains a bunch more information we could spit * out if we wanted. */ -fn expand_file(cx: ext_ctxt, sp: span, arg: ast::mac_arg, - _body: ast::mac_body) -> @ast::expr { - get_mac_args(cx, sp, arg, 0u, option::Some(0u), ~"file"); +fn expand_file(cx: ext_ctxt, sp: span, tts: ~[ast::token_tree]) + -> base::mac_result { + base::check_zero_tts(cx, sp, tts, "file!"); let Loc { file: @FileMap { name: filename, _ }, _ } = cx.codemap().lookup_char_pos(sp.lo); - return mk_uniq_str(cx, sp, filename); + base::mr_expr(mk_uniq_str(cx, sp, filename)) } -fn expand_stringify(cx: ext_ctxt, sp: span, arg: ast::mac_arg, - _body: ast::mac_body) -> @ast::expr { - let args = get_mac_args(cx, sp, arg, 1u, option::Some(1u), ~"stringify"); - let s = pprust::expr_to_str(args[0], cx.parse_sess().interner); - return mk_uniq_str(cx, sp, s); +fn expand_stringify(cx: ext_ctxt, sp: span, tts: ~[ast::token_tree]) + -> base::mac_result { + let s = pprust::tts_to_str(tts, cx.parse_sess().interner); + base::mr_expr(mk_uniq_str(cx, sp, s)) } -fn expand_mod(cx: ext_ctxt, sp: span, arg: ast::mac_arg, _body: ast::mac_body) - -> @ast::expr { - get_mac_args(cx, sp, arg, 0u, option::Some(0u), ~"file"); - return mk_uniq_str(cx, sp, - str::connect(cx.mod_path().map( - |x| cx.str_of(*x)), ~"::")); +fn expand_mod(cx: ext_ctxt, sp: span, tts: ~[ast::token_tree]) + -> base::mac_result { + base::check_zero_tts(cx, sp, tts, "module_path!"); + base::mr_expr(mk_uniq_str(cx, sp, + str::connect(cx.mod_path().map( + |x| cx.str_of(*x)), ~"::"))) } -fn expand_include(cx: ext_ctxt, sp: span, arg: ast::mac_arg, - _body: ast::mac_body) -> @ast::expr { - let args = get_mac_args(cx, sp, arg, 1u, option::Some(1u), ~"include"); - let file = expr_to_str(cx, args[0], ~"include_str! requires a string"); +fn expand_include(cx: ext_ctxt, sp: span, tts: ~[ast::token_tree]) + -> base::mac_result { + let file = get_single_str_from_tts(cx, sp, tts, "include!"); let p = parse::new_sub_parser_from_file( cx.parse_sess(), cx.cfg(), &res_rel_file(cx, sp, &Path(file)), sp); - return p.parse_expr(); + base::mr_expr(p.parse_expr()) } -fn expand_include_str(cx: ext_ctxt, sp: codemap::span, arg: ast::mac_arg, - _body: ast::mac_body) -> @ast::expr { - let args = get_mac_args(cx,sp,arg,1u,option::Some(1u),~"include_str"); - - let file = expr_to_str(cx, args[0], ~"include_str! requires a string"); - +fn expand_include_str(cx: ext_ctxt, sp: span, tts: ~[ast::token_tree]) + -> base::mac_result { + let file = get_single_str_from_tts(cx, sp, tts, "include_str!"); let res = io::read_whole_file_str(&res_rel_file(cx, sp, &Path(file))); match res { result::Ok(_) => { /* Continue. */ } @@ -88,21 +83,18 @@ fn expand_include_str(cx: ext_ctxt, sp: codemap::span, arg: ast::mac_arg, } } - return mk_uniq_str(cx, sp, result::unwrap(res)); + base::mr_expr(mk_uniq_str(cx, sp, result::unwrap(res))) } -fn expand_include_bin(cx: ext_ctxt, sp: codemap::span, arg: ast::mac_arg, - _body: ast::mac_body) -> @ast::expr { - let args = get_mac_args(cx,sp,arg,1u,option::Some(1u),~"include_bin"); - - let file = expr_to_str(cx, args[0], ~"include_bin! requires a string"); - +fn expand_include_bin(cx: ext_ctxt, sp: span, tts: ~[ast::token_tree]) + -> base::mac_result { + let file = get_single_str_from_tts(cx, sp, tts, "include_bin!"); match io::read_whole_file(&res_rel_file(cx, sp, &Path(file))) { result::Ok(src) => { let u8_exprs = vec::map(src, |char| { mk_u8(cx, sp, *char) }); - return mk_base_vec_e(cx, sp, u8_exprs); + base::mr_expr(mk_base_vec_e(cx, sp, u8_exprs)) } result::Err(ref e) => { cx.parse_sess().span_diagnostic.handler().fatal((*e)) diff --git a/src/libsyntax/print/pp.rs b/src/libsyntax/print/pp.rs index 3e9fe80526000..d90341254cc34 100644 --- a/src/libsyntax/print/pp.rs +++ b/src/libsyntax/print/pp.rs @@ -154,8 +154,7 @@ fn mk_printer(out: io::Writer, linewidth: uint) -> printer { mut top: 0, mut bottom: 0, print_stack: DVec(), - mut pending_indentation: 0, - mut token_tree_last_was_ident: false}) + mut pending_indentation: 0 }) } @@ -261,7 +260,6 @@ type printer_ = { print_stack: DVec, // buffered indentation to avoid writing trailing whitespace mut pending_indentation: int, - mut token_tree_last_was_ident: bool }; enum printer { diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 684f74f3575c4..fa384341fb973 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -118,6 +118,10 @@ fn tt_to_str(tt: ast::token_tree, intr: @ident_interner) -> ~str { to_str(tt, print_tt, intr) } +fn tts_to_str(tts: &[ast::token_tree], intr: @ident_interner) -> ~str { + to_str(tts, print_tts, intr) +} + fn stmt_to_str(s: ast::stmt, intr: @ident_interner) -> ~str { to_str(s, print_stmt, intr) } @@ -584,9 +588,7 @@ fn print_item(s: ps, &&item: @ast::item) { print_ident(s, item.ident); cbox(s, indent_unit); popen(s); - for (*tts).each |tt| { - print_tt(s, *tt); - } + print_tts(s, *tts); pclose(s); end(s); } @@ -736,17 +738,9 @@ fn print_struct(s: ps, struct_def: @ast::struct_def, tps: ~[ast::ty_param], /// expression arguments as expressions). It can be done! I think. fn print_tt(s: ps, tt: ast::token_tree) { match tt { - ast::tt_delim(ref tts) => - for (*tts).each() |tt_elt| { print_tt(s, *tt_elt); }, + ast::tt_delim(ref tts) => print_tts(s, *tts), ast::tt_tok(_, ref tk) => { - match (*tk) { - parse::token::IDENT(*) => { // don't let idents run together - if s.s.token_tree_last_was_ident { word(s.s, ~" ") } - s.s.token_tree_last_was_ident = true; - } - _ => { s.s.token_tree_last_was_ident = false; } - } - word(s.s, parse::token::to_str(s.intr, (*tk))); + word(s.s, parse::token::to_str(s.intr, (*tk))); } ast::tt_seq(_, ref tts, ref sep, zerok) => { word(s.s, ~"$("); @@ -757,16 +751,25 @@ fn print_tt(s: ps, tt: ast::token_tree) { None => () } word(s.s, if zerok { ~"*" } else { ~"+" }); - s.s.token_tree_last_was_ident = false; } ast::tt_nonterminal(_, name) => { word(s.s, ~"$"); print_ident(s, name); - s.s.token_tree_last_was_ident = true; } } } +fn print_tts(s: ps, &&tts: &[ast::token_tree]) { + ibox(s, 0); + for tts.eachi |i, tt| { + if i != 0 { + space(s.s); + } + print_tt(s, *tt); + } + end(s); +} + fn print_variant(s: ps, v: ast::variant) { print_visibility(s, v.node.vis); match v.node.kind { @@ -1001,7 +1004,7 @@ fn print_mac(s: ps, m: ast::mac) { print_path(s, pth, false); word(s.s, ~"!"); popen(s); - for (*tts).each() |tt| { print_tt(s, *tt); } + print_tts(s, *tts); pclose(s); } } diff --git a/src/libsyntax/syntax.rc b/src/libsyntax/syntax.rc index 00c3804cce16c..fbc5f10fcd6f9 100644 --- a/src/libsyntax/syntax.rc +++ b/src/libsyntax/syntax.rc @@ -109,9 +109,6 @@ mod ext { #[path = "ext/concat_idents.rs"] mod concat_idents; #[legacy_exports] - #[path = "ext/ident_to_str.rs"] - mod ident_to_str; - #[legacy_exports] #[path = "ext/log_syntax.rs"] mod log_syntax; #[legacy_exports] diff --git a/src/test/compile-fail/ext-noname.rs b/src/test/compile-fail/ext-noname.rs deleted file mode 100644 index bf6bcd6f0817d..0000000000000 --- a/src/test/compile-fail/ext-noname.rs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2012 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 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// error-pattern:expected a syntax expander name - -fn main() { - #(); -} diff --git a/src/test/compile-fail/extenv-no-args.rs b/src/test/compile-fail/extenv-no-args.rs index 0c59ed9d33991..7ff1357dcf3c9 100644 --- a/src/test/compile-fail/extenv-no-args.rs +++ b/src/test/compile-fail/extenv-no-args.rs @@ -8,6 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: env! takes between 1 and 1 arguments +// error-pattern: env! takes 1 argument fn main() { env!(); } diff --git a/src/test/compile-fail/extenv-too-many-args.rs b/src/test/compile-fail/extenv-too-many-args.rs index abd7487f50c06..b1b2001abc358 100644 --- a/src/test/compile-fail/extenv-too-many-args.rs +++ b/src/test/compile-fail/extenv-too-many-args.rs @@ -8,6 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: env! takes between 1 and 1 arguments +// error-pattern: env! takes 1 argument fn main() { env!("one", "two"); } diff --git a/src/test/compile-fail/extfmt-no-args.rs b/src/test/compile-fail/extfmt-no-args.rs index b5d0462b436cc..cd9308e7b3f25 100644 --- a/src/test/compile-fail/extfmt-no-args.rs +++ b/src/test/compile-fail/extfmt-no-args.rs @@ -8,6 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern:fmt! needs at least 1 arguments +// error-pattern:fmt! takes at least 1 argument fn main() { fmt!(); } diff --git a/src/test/run-pass/class-attributes-1.rs b/src/test/run-pass/class-attributes-1.rs index d3a24488ca89b..ef3a82d1e2b69 100644 --- a/src/test/run-pass/class-attributes-1.rs +++ b/src/test/run-pass/class-attributes-1.rs @@ -16,7 +16,7 @@ struct cat { impl cat: Drop { #[cat_dropper] - fn finalize(&self) { error!("%s landed on hir feet",self.name); } + fn finalize(&self) { error!("%s landed on hir feet" , self . name); } } diff --git a/src/test/run-pass/syntax-extension-minor.rs b/src/test/run-pass/syntax-extension-minor.rs index dd08605ae61e5..aafd71d9162c8 100644 --- a/src/test/run-pass/syntax-extension-minor.rs +++ b/src/test/run-pass/syntax-extension-minor.rs @@ -13,6 +13,6 @@ fn main() { let asdf_fdsa = ~"<.<"; assert (concat_idents!(asd, f_f, dsa) == ~"<.<"); - assert (ident_to_str!(use_mention_distinction) == + assert (stringify!(use_mention_distinction) == ~"use_mention_distinction"); } diff --git a/src/test/run-pass/syntax-extension-source-utils.rs b/src/test/run-pass/syntax-extension-source-utils.rs index 44eb6337a6fa4..0d7174370a084 100644 --- a/src/test/run-pass/syntax-extension-source-utils.rs +++ b/src/test/run-pass/syntax-extension-source-utils.rs @@ -24,7 +24,7 @@ fn main() { assert(line!() == 24); assert(col!() == 11); assert(file!().ends_with(~"syntax-extension-source-utils.rs")); - assert(stringify!((2*3) + 5) == ~"(2 * 3) + 5"); + assert(stringify!((2*3) + 5) == ~"( 2 * 3 ) + 5"); assert(include!("syntax-extension-source-utils-files/includeme.fragment") == ~"victory robot 6");