summary refs log tree commit diff
path: root/src/comp/syntax
diff options
context:
space:
mode:
authorKevin Atkinson <kevina@cs.utah.edu>2012-01-28 18:20:43 -0700
committerKevin Atkinson <kevina@cs.utah.edu>2012-02-03 20:41:37 -0700
commit099290bc7385477ab6c9908abb3b540e8cb6956a (patch)
tree4f02a335086428e58f6d34f83e072d4642d86587 /src/comp/syntax
parentc0f9073557b5daed86aea411fb4c56e554583af2 (diff)
downloadrust-099290bc7385477ab6c9908abb3b540e8cb6956a.tar.gz
rust-099290bc7385477ab6c9908abb3b540e8cb6956a.zip
When replacing $(...) with $0 preserve spacing for better error messages.
That is:
  x + $(foo) + y
becomes:
  x + $0     + y
not:
  x + $0 + y
Diffstat (limited to 'src/comp/syntax')
-rw-r--r--src/comp/syntax/ext/qquote.rs26
1 files changed, 19 insertions, 7 deletions
diff --git a/src/comp/syntax/ext/qquote.rs b/src/comp/syntax/ext/qquote.rs
index fc4e0599c2f..1b17356ce91 100644
--- a/src/comp/syntax/ext/qquote.rs
+++ b/src/comp/syntax/ext/qquote.rs
@@ -38,6 +38,10 @@ fn visit_expr_aq(expr: @ast::expr, &&cx: aq_ctxt, v: vt<aq_ctxt>)
     }
 }
 
+fn is_space(c: char) -> bool {
+    syntax::parse::lexer::is_whitespace(c)
+}
+
 fn expand_qquote(ecx: ext_ctxt, sp: span, e: @ast::expr) -> @ast::expr {
     let str = codemap::span_to_snippet(sp, ecx.session().parse_sess.cm);
     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 {
         prev = lo;
     }
     let str2 = "";
-    let active = true;
+    enum state {active, skip(uint), blank};
+    let state = active;
     let i = 0u, j = 0u;
     let g_len = vec::len(cx.gather);
     str::chars_iter(str) {|ch|
-        if (active && j < g_len && i == cx.gather[j].lo) {
+        if (j < g_len && i == cx.gather[j].lo) {
             assert ch == '$';
-            active = false;
-            str2 += #fmt(" $%u ", j);
+            let repl = #fmt("$%u ", j);
+            state = skip(str::char_len(repl));
+            str2 += repl;
+        }
+        alt state {
+          active {str::push_char(str2, ch);}
+          skip(1u) {state = blank;}
+          skip(sk) {state = skip (sk-1u);}
+          blank if is_space(ch) {str::push_char(str2, ch);}
+          blank {str::push_char(str2, ' ');}
         }
-        if (active) {str::push_char(str2, ch);}
         i += 1u;
-        if (!active && j < g_len && i == cx.gather[j].hi) {
+        if (j < g_len && i == cx.gather[j].hi) {
             assert ch == ')';
-            active = true;
+            state = active;
             j += 1u;
         }
     }