@@ -38,6 +38,10 @@ fn visit_expr_aq(expr: @ast::expr, &&cx: aq_ctxt, v: vt<aq_ctxt>)
38
38
}
39
39
}
40
40
41
+ fn is_space ( c : char ) -> bool {
42
+ syntax:: parse:: lexer:: is_whitespace ( c)
43
+ }
44
+
41
45
fn expand_qquote ( ecx : ext_ctxt , sp : span , e : @ast:: expr ) -> @ast:: expr {
42
46
let str = codemap:: span_to_snippet ( sp, ecx. session ( ) . parse_sess . cm ) ;
43
47
let qcx = gather_anti_quotes ( sp. lo , e) ;
@@ -48,20 +52,28 @@ fn expand_qquote(ecx: ext_ctxt, sp: span, e: @ast::expr) -> @ast::expr {
48
52
prev = lo;
49
53
}
50
54
let str2 = "" ;
51
- let active = true ;
55
+ enum state { active, skip( uint ) , blank} ;
56
+ let state = active;
52
57
let i = 0 u, j = 0 u;
53
58
let g_len = vec:: len ( cx. gather ) ;
54
59
str:: chars_iter ( str) { |ch|
55
- if ( active && j < g_len && i == cx. gather [ j] . lo ) {
60
+ if ( j < g_len && i == cx. gather [ j] . lo ) {
56
61
assert ch == '$' ;
57
- active = false ;
58
- str2 += #fmt ( " $%u " , j) ;
62
+ let repl = #fmt ( "$%u " , j) ;
63
+ state = skip ( str:: char_len ( repl) ) ;
64
+ str2 += repl;
65
+ }
66
+ alt state {
67
+ active { str:: push_char ( str2, ch) ; }
68
+ skip ( 1 u) { state = blank; }
69
+ skip ( sk) { state = skip ( sk-1 u) ; }
70
+ blank if is_space ( ch) { str:: push_char ( str2, ch) ; }
71
+ blank { str : : push_char ( str2, ' ' ) ; }
59
72
}
60
- if ( active) { str:: push_char ( str2, ch) ; }
61
73
i += 1 u;
62
- if ( !active && j < g_len && i == cx. gather [ j] . hi ) {
74
+ if ( j < g_len && i == cx. gather [ j] . hi ) {
63
75
assert ch == ')' ;
64
- active = true ;
76
+ state = active ;
65
77
j += 1 u;
66
78
}
67
79
}
0 commit comments