提交 e24ae850 编写于 作者: G Graydon Hoare

syntax: remove most code handling old-style syntax extensions.

上级 9cced55b
......@@ -842,13 +842,7 @@ enum matcher_ {
#[auto_serialize]
#[auto_deserialize]
enum mac_ {
mac_invoc(@path, mac_arg, mac_body), // old macro-invocation
mac_invoc_tt(@path,~[token_tree]), // new macro-invocation
mac_ellipsis, // old pattern-match (obsolete)
// the span is used by the quoter/anti-quoter ...
mac_aq(span /* span of quote */, @expr), // anti-quote
mac_var(uint)
}
type lit = spanned<lit_>;
......
......@@ -16,16 +16,16 @@
// 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 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 builtin_item_tt(f: syntax_expander_tt_item_) -> syntax_extension {
item_tt({expander: f, span: None})
}
let syntax_expanders = HashMap();
syntax_expanders.insert(~"macro",
macro_defining(ext::simplext::add_new_extension));
syntax_expanders.insert(~"macro_rules",
builtin_item_tt(
ext::tt::macro_rules::add_new_extension));
......
......@@ -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]);
......
......@@ -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",
......
此差异已折叠。
......@@ -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)};
}
......
......@@ -12,16 +12,9 @@
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<Either<~[ast::attribute], @ast::expr>>;
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 @@ fn parse_inner_attrs_and_next() ->
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] = ~[];
......
......@@ -515,11 +515,6 @@ fn binop(rdr: string_reader, op: token::binop) -> 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; }
......
......@@ -54,8 +54,8 @@
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 @@ fn parse_ty(colons_before_params: bool) -> @Ty {
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 @@ fn parse_fn_block_arg() -> arg_or_capture_item {
}
}
fn maybe_parse_dollar_mac() -> Option<mac_> {
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<uint> {
if self.eat(token::BINOP(token::STAR)) {
match copy self.token {
......@@ -928,11 +893,6 @@ fn parse_bottom_expr() -> @expr {
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 @@ fn parse_bottom_expr() -> @expr {
}
}
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 @@ fn parse_block_expr(lo: BytePos, blk_mode: blk_check_mode) -> @expr {
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 @@ fn check_expected_item(p: Parser, current_attrs: ~[attribute]) {
}
} 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) {
......
......@@ -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,
......
......@@ -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 do_else(s: ps, els: Option<@ast::expr>) {
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 */ }
}
}
......
......@@ -99,9 +99,6 @@ mod ext {
}
#[legacy_exports]
#[path = "ext/simplext.rs"]
mod simplext;
#[legacy_exports]
#[path = "ext/fmt.rs"]
mod fmt;
......
......@@ -379,15 +379,8 @@ fn visit_exprs<E>(exprs: ~[@expr], e: E, v: vt<E>) {
for exprs.each |ex| { (v.visit_expr)(*ex, e, v); }
}
fn visit_mac<E>(m: mac, e: E, v: vt<E>) {
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<E>(_m: mac, _e: E, _v: vt<E>) {
/* no user-serviceable parts inside */
}
fn visit_expr<E>(ex: @expr, e: E, v: vt<E>) {
......
// 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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
}
// 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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);
}
// 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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);
}
// 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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);
}
// 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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);
}
// 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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, #<t>, body, #<s>],
{
fn result(x: t) -> s { return body }
result
}]];
assert (lambda!(i, #<uint>, i + 4u, #<uint>)(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]);
}
// 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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);
}
/* 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!())
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册