Skip to content

Commit 91d3c36

Browse files
committed
adding test case to check marking/unmarking
1 parent b7c0512 commit 91d3c36

File tree

3 files changed

+25
-12
lines changed

3 files changed

+25
-12
lines changed

src/libsyntax/ext/expand.rs

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use opt_vec;
2323
use parse;
2424
use parse::{parse_item_from_source_str};
2525
use parse::token;
26-
use parse::token::{fresh_name, ident_to_str, intern};
26+
use parse::token::{fresh_mark, fresh_name, ident_to_str, intern};
2727
use visit;
2828
use visit::Visitor;
2929

@@ -67,7 +67,9 @@ pub fn expand_expr(extsbox: @mut SyntaxEnv,
6767
},
6868
});
6969

70-
let expanded = match expandfun(cx, mac.span, *tts) {
70+
let fm = fresh_mark();
71+
let marked_tts = mark_tts(*tts,fm);
72+
let expanded = match expandfun(cx, mac.span, marked_tts) {
7173
MRExpr(e) => e,
7274
MRAny(expr_maker,_,_) => expr_maker(),
7375
_ => {
@@ -259,6 +261,12 @@ pub fn expand_expr(extsbox: @mut SyntaxEnv,
259261
}
260262
}
261263

264+
// apply a fresh mark to the given token trees. Used prior to expansion of a macro.
265+
fn mark_tts(tts : &[token_tree], m : Mrk) -> ~[token_tree] {
266+
fold_tts(tts,new_ident_marker(m))
267+
}
268+
269+
262270
// This is a secondary mechanism for invoking syntax extensions on items:
263271
// "decorator" attributes, such as #[auto_encode]. These are invoked by an
264272
// attribute prefixing an item, and are interpreted by feeding the item
@@ -1285,7 +1293,7 @@ pub fn new_ident_renamer(from: ast::Ident,
12851293

12861294

12871295
// update the ctxts in a path to get a mark node
1288-
pub fn new_ident_marker(mark: uint) ->
1296+
pub fn new_ident_marker(mark: Mrk) ->
12891297
@fn(ast::Ident)->ast::Ident {
12901298
|id : ast::Ident|
12911299
ast::Ident{
@@ -1461,18 +1469,18 @@ mod test {
14611469

14621470
#[test]
14631471
fn automatic_renaming () {
1464-
// "fn a() -> int { let b = 13; let c = b; b+c }"
1465-
// --> b & c should get new names, in the expr too.
1466-
// "macro_rules! f (($x:ident) => ($x + b)) fn a() -> int { let b = 13; f!(b)}"
1467-
// --> one should be renamed, one should not.
1468-
14691472
let teststrs =
14701473
~[// b & c should get new names throughout, in the expr too:
14711474
@"fn a() -> int { let b = 13; let c = b; b+c }",
14721475
// the use of b before the + should be renamed, the other one not:
14731476
@"macro_rules! f (($x:ident) => ($x + b)) fn a() -> int { let b = 13; f!(b)}",
14741477
// the b before the plus should not be renamed (requires marks)
1475-
@"macro_rules! f (($x:ident) => ({let b=9; ($x + b)})) fn a() -> int { f!(b)}"];
1478+
@"macro_rules! f (($x:ident) => ({let b=9; ($x + b)})) fn a() -> int { f!(b)}",
1479+
// the z flows into and out of two macros (g & f) along one path, and one (just g) along the
1480+
// other, so the result of the whole thing should be "let z_123 = 3; z_123"
1481+
@"macro_rules! g (($x:ident) => ({macro_rules! f(($y:ident)=>({let $y=3;$x}));f!($x)}))
1482+
fn a(){g!(z)}"
1483+
];
14761484
for s in teststrs.iter() {
14771485
// we need regexps to test these!
14781486
std::io::println(expand_and_resolve_and_pretty_print(*s));

src/libsyntax/fold.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ fn fold_mac_(m: &mac, fld: @ast_fold) -> mac {
126126

127127
// build a new vector of tts by appling the given function to
128128
// all of the identifiers in the token trees.
129-
pub fn fold_tts(tts : &[token_tree], f: @fn(ident)->ident) -> ~[token_tree] {
129+
pub fn fold_tts(tts : &[token_tree], f: @fn(Ident)->Ident) -> ~[token_tree] {
130130
do tts.map |tt| {
131131
match *tt {
132132
tt_tok(span, ref tok) =>
@@ -145,7 +145,7 @@ pub fn fold_tts(tts : &[token_tree], f: @fn(ident)->ident) -> ~[token_tree] {
145145
}
146146

147147
// apply ident folder if it's an ident, otherwise leave it alone
148-
fn maybe_fold_ident(t : &token::Token, f: @fn(ident)->ident) -> token::Token {
148+
fn maybe_fold_ident(t : &token::Token, f: @fn(Ident)->Ident) -> token::Token {
149149
match *t {
150150
token::IDENT(id,followed_by_colons) =>
151151
token::IDENT(f(id),followed_by_colons),

src/libsyntax/parse/token.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
// except according to those terms.
1010

1111
use ast;
12-
use ast::Name;
12+
use ast::{Name, Mrk};
1313
use ast_util;
1414
use parse::token;
1515
use util::interner::StrInterner;
@@ -557,6 +557,11 @@ pub fn fresh_name(src_name : &ast::Ident) -> Name {
557557
gensym(fmt!("%s_%u",ident_to_str(src_name),num))
558558
}
559559

560+
// create a fresh mark.
561+
pub fn fresh_mark() -> Mrk {
562+
gensym("mark")
563+
}
564+
560565
/**
561566
* All the valid words that have meaning in the Rust language.
562567
*

0 commit comments

Comments
 (0)