adding test case to check marking/unmarking
This commit is contained in:
parent
b7c0512b27
commit
91d3c36430
@ -23,7 +23,7 @@ use opt_vec;
|
|||||||
use parse;
|
use parse;
|
||||||
use parse::{parse_item_from_source_str};
|
use parse::{parse_item_from_source_str};
|
||||||
use parse::token;
|
use parse::token;
|
||||||
use parse::token::{fresh_name, ident_to_str, intern};
|
use parse::token::{fresh_mark, fresh_name, ident_to_str, intern};
|
||||||
use visit;
|
use visit;
|
||||||
use visit::Visitor;
|
use visit::Visitor;
|
||||||
|
|
||||||
@ -67,7 +67,9 @@ pub fn expand_expr(extsbox: @mut SyntaxEnv,
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
let expanded = match expandfun(cx, mac.span, *tts) {
|
let fm = fresh_mark();
|
||||||
|
let marked_tts = mark_tts(*tts,fm);
|
||||||
|
let expanded = match expandfun(cx, mac.span, marked_tts) {
|
||||||
MRExpr(e) => e,
|
MRExpr(e) => e,
|
||||||
MRAny(expr_maker,_,_) => expr_maker(),
|
MRAny(expr_maker,_,_) => expr_maker(),
|
||||||
_ => {
|
_ => {
|
||||||
@ -259,6 +261,12 @@ pub fn expand_expr(extsbox: @mut SyntaxEnv,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// apply a fresh mark to the given token trees. Used prior to expansion of a macro.
|
||||||
|
fn mark_tts(tts : &[token_tree], m : Mrk) -> ~[token_tree] {
|
||||||
|
fold_tts(tts,new_ident_marker(m))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// This is a secondary mechanism for invoking syntax extensions on items:
|
// This is a secondary mechanism for invoking syntax extensions on items:
|
||||||
// "decorator" attributes, such as #[auto_encode]. These are invoked by an
|
// "decorator" attributes, such as #[auto_encode]. These are invoked by an
|
||||||
// attribute prefixing an item, and are interpreted by feeding the item
|
// attribute prefixing an item, and are interpreted by feeding the item
|
||||||
@ -1285,7 +1293,7 @@ pub fn new_ident_renamer(from: ast::Ident,
|
|||||||
|
|
||||||
|
|
||||||
// update the ctxts in a path to get a mark node
|
// update the ctxts in a path to get a mark node
|
||||||
pub fn new_ident_marker(mark: uint) ->
|
pub fn new_ident_marker(mark: Mrk) ->
|
||||||
@fn(ast::Ident)->ast::Ident {
|
@fn(ast::Ident)->ast::Ident {
|
||||||
|id : ast::Ident|
|
|id : ast::Ident|
|
||||||
ast::Ident{
|
ast::Ident{
|
||||||
@ -1461,18 +1469,18 @@ mod test {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn automatic_renaming () {
|
fn automatic_renaming () {
|
||||||
// "fn a() -> int { let b = 13; let c = b; b+c }"
|
|
||||||
// --> b & c should get new names, in the expr too.
|
|
||||||
// "macro_rules! f (($x:ident) => ($x + b)) fn a() -> int { let b = 13; f!(b)}"
|
|
||||||
// --> one should be renamed, one should not.
|
|
||||||
|
|
||||||
let teststrs =
|
let teststrs =
|
||||||
~[// b & c should get new names throughout, in the expr too:
|
~[// b & c should get new names throughout, in the expr too:
|
||||||
@"fn a() -> int { let b = 13; let c = b; b+c }",
|
@"fn a() -> int { let b = 13; let c = b; b+c }",
|
||||||
// the use of b before the + should be renamed, the other one not:
|
// the use of b before the + should be renamed, the other one not:
|
||||||
@"macro_rules! f (($x:ident) => ($x + b)) fn a() -> int { let b = 13; f!(b)}",
|
@"macro_rules! f (($x:ident) => ($x + b)) fn a() -> int { let b = 13; f!(b)}",
|
||||||
// the b before the plus should not be renamed (requires marks)
|
// the b before the plus should not be renamed (requires marks)
|
||||||
@"macro_rules! f (($x:ident) => ({let b=9; ($x + b)})) fn a() -> int { f!(b)}"];
|
@"macro_rules! f (($x:ident) => ({let b=9; ($x + b)})) fn a() -> int { f!(b)}",
|
||||||
|
// the z flows into and out of two macros (g & f) along one path, and one (just g) along the
|
||||||
|
// other, so the result of the whole thing should be "let z_123 = 3; z_123"
|
||||||
|
@"macro_rules! g (($x:ident) => ({macro_rules! f(($y:ident)=>({let $y=3;$x}));f!($x)}))
|
||||||
|
fn a(){g!(z)}"
|
||||||
|
];
|
||||||
for s in teststrs.iter() {
|
for s in teststrs.iter() {
|
||||||
// we need regexps to test these!
|
// we need regexps to test these!
|
||||||
std::io::println(expand_and_resolve_and_pretty_print(*s));
|
std::io::println(expand_and_resolve_and_pretty_print(*s));
|
||||||
|
@ -126,7 +126,7 @@ fn fold_mac_(m: &mac, fld: @ast_fold) -> mac {
|
|||||||
|
|
||||||
// build a new vector of tts by appling the given function to
|
// build a new vector of tts by appling the given function to
|
||||||
// all of the identifiers in the token trees.
|
// all of the identifiers in the token trees.
|
||||||
pub fn fold_tts(tts : &[token_tree], f: @fn(ident)->ident) -> ~[token_tree] {
|
pub fn fold_tts(tts : &[token_tree], f: @fn(Ident)->Ident) -> ~[token_tree] {
|
||||||
do tts.map |tt| {
|
do tts.map |tt| {
|
||||||
match *tt {
|
match *tt {
|
||||||
tt_tok(span, ref tok) =>
|
tt_tok(span, ref tok) =>
|
||||||
@ -145,7 +145,7 @@ pub fn fold_tts(tts : &[token_tree], f: @fn(ident)->ident) -> ~[token_tree] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// apply ident folder if it's an ident, otherwise leave it alone
|
// apply ident folder if it's an ident, otherwise leave it alone
|
||||||
fn maybe_fold_ident(t : &token::Token, f: @fn(ident)->ident) -> token::Token {
|
fn maybe_fold_ident(t : &token::Token, f: @fn(Ident)->Ident) -> token::Token {
|
||||||
match *t {
|
match *t {
|
||||||
token::IDENT(id,followed_by_colons) =>
|
token::IDENT(id,followed_by_colons) =>
|
||||||
token::IDENT(f(id),followed_by_colons),
|
token::IDENT(f(id),followed_by_colons),
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use ast;
|
use ast;
|
||||||
use ast::Name;
|
use ast::{Name, Mrk};
|
||||||
use ast_util;
|
use ast_util;
|
||||||
use parse::token;
|
use parse::token;
|
||||||
use util::interner::StrInterner;
|
use util::interner::StrInterner;
|
||||||
@ -557,6 +557,11 @@ pub fn fresh_name(src_name : &ast::Ident) -> Name {
|
|||||||
gensym(fmt!("%s_%u",ident_to_str(src_name),num))
|
gensym(fmt!("%s_%u",ident_to_str(src_name),num))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// create a fresh mark.
|
||||||
|
pub fn fresh_mark() -> Mrk {
|
||||||
|
gensym("mark")
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All the valid words that have meaning in the Rust language.
|
* All the valid words that have meaning in the Rust language.
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user