about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBrian Anderson <andersrb@gmail.com>2011-04-17 19:50:58 -0400
committerBrian Anderson <andersrb@gmail.com>2011-04-17 19:50:58 -0400
commit9976bb93d6c2ab46979c2bc13480266069fd8b3e (patch)
tree036dee6d7f8d2b9f96b6611d407caf687f755cd3
parent86a43c24d627131c7c543ffc2df7793939141404 (diff)
Support the space flag in #fmt
-rw-r--r--src/comp/front/extfmt.rs54
-rw-r--r--src/lib/ExtFmt.rs13
-rw-r--r--src/test/run-pass/syntax-extension-fmt.rs9
3 files changed, 53 insertions, 23 deletions
diff --git a/src/comp/front/extfmt.rs b/src/comp/front/extfmt.rs
index c05c74d1e46..287c7e552ec 100644
--- a/src/comp/front/extfmt.rs
+++ b/src/comp/front/extfmt.rs
@@ -28,7 +28,7 @@ import std.ExtFmt.CT.ty_hex;
 import std.ExtFmt.CT.flag;
 import std.ExtFmt.CT.flag_left_justify;
 import std.ExtFmt.CT.flag_left_zero_pad;
-import std.ExtFmt.CT.flag_left_space_pad;
+import std.ExtFmt.CT.flag_space_for_sign;
 import std.ExtFmt.CT.flag_sign_always;
 import std.ExtFmt.CT.flag_alternate;
 import std.ExtFmt.CT.count;
@@ -180,6 +180,10 @@ fn pieces_to_expr(vec[piece] pieces, vec[@ast.expr] args) -> @ast.expr {
                         auto fstr = "flag_sign_always";
                         flagexprs += vec(make_rt_path_expr(sp, fstr));
                     }
+                    case (flag_space_for_sign) {
+                        auto fstr = "flag_space_for_sign";
+                        flagexprs += vec(make_rt_path_expr(sp, fstr));
+                    }
                 }
             }
 
@@ -268,6 +272,25 @@ fn pieces_to_expr(vec[piece] pieces, vec[@ast.expr] args) -> @ast.expr {
 
     fn make_new_conv(conv cnv, @ast.expr arg) -> @ast.expr {
 
+        // FIXME: Extract all this validation into ExtFmt.CT
+        fn is_signed_type(conv cnv) -> bool {
+            alt (cnv.ty) {
+                case (ty_int(?s)) {
+                    alt (s) {
+                        case (signed) {
+                            ret true;
+                        }
+                        case (unsigned) {
+                            ret false;
+                        }
+                    }
+                }
+                case (_) {
+                    ret false;
+                }
+            }
+        }
+
         auto unsupported = "conversion not supported in #fmt string";
 
         alt (cnv.param) {
@@ -284,23 +307,16 @@ fn pieces_to_expr(vec[piece] pieces, vec[@ast.expr] args) -> @ast.expr {
                 case (flag_left_justify) {
                 }
                 case (flag_sign_always) {
-                    auto err = "+ flag only valid in signed #fmt conversions";
-                    alt (cnv.ty) {
-                        case (ty_int(?s)) {
-                            alt (s) {
-                                case (signed) {
-                                    // Valid
-                                }
-                                case (unsigned) {
-                                    log err;
-                                    fail;
-                                }
-                            }
-                        }
-                        case (_) {
-                            log err;
-                            fail;
-                        }
+                    if (!is_signed_type(cnv)) {
+                        log "+ flag only valid in signed #fmt conversions";
+                        fail;
+                    }
+                }
+                case (flag_space_for_sign) {
+                    if (!is_signed_type(cnv)) {
+                        log "space flag only valid in "
+                            + "signed #fmt conversions";
+                        fail;
                     }
                 }
                 case (_) {
@@ -382,7 +398,7 @@ fn pieces_to_expr(vec[piece] pieces, vec[@ast.expr] args) -> @ast.expr {
                 case (flag_left_zero_pad) {
                     log "flag: left zero pad";
                 }
-                case (flag_left_space_pad) {
+                case (flag_space_for_sign) {
                     log "flag: left space pad";
                 }
                 case (flag_sign_always) {
diff --git a/src/lib/ExtFmt.rs b/src/lib/ExtFmt.rs
index c2cce279ffb..c6ddad30395 100644
--- a/src/lib/ExtFmt.rs
+++ b/src/lib/ExtFmt.rs
@@ -52,7 +52,7 @@ mod CT {
     tag flag {
         flag_left_justify;
         flag_left_zero_pad;
-        flag_left_space_pad;
+        flag_space_for_sign;
         flag_sign_always;
         flag_alternate;
     }
@@ -201,7 +201,7 @@ mod CT {
         } else if (f == ('0' as u8)) {
             ret more(flag_left_zero_pad);
         } else if (f == (' ' as u8)) {
-            ret more(flag_left_space_pad);
+            ret more(flag_space_for_sign);
         } else if (f == ('+' as u8)) {
             ret more(flag_sign_always);
         } else if (f == ('#' as u8)) {
@@ -306,6 +306,7 @@ mod RT {
 
     tag flag {
         flag_left_justify;
+        flag_space_for_sign;
         flag_sign_always;
         // FIXME: This is a hack to avoid creating 0-length vec exprs,
         // which have some difficulty typechecking currently. See
@@ -336,8 +337,12 @@ mod RT {
         auto radix = 10u;
         auto prec = get_int_precision(cv);
         auto s = int_to_str_prec(i, radix, prec);
-        if (0 <= i && have_flag(cv.flags, flag_sign_always)) {
-            s = "+" + s;
+        if (0 <= i) {
+            if (have_flag(cv.flags, flag_sign_always)) {
+                s = "+" + s;
+            } else if (have_flag(cv.flags, flag_space_for_sign)) {
+                s = " " + s;
+            }
         }
         ret pad(cv, s);
     }
diff --git a/src/test/run-pass/syntax-extension-fmt.rs b/src/test/run-pass/syntax-extension-fmt.rs
index 1e283c2d360..61143e4aac8 100644
--- a/src/test/run-pass/syntax-extension-fmt.rs
+++ b/src/test/run-pass/syntax-extension-fmt.rs
@@ -117,4 +117,13 @@ fn main() {
   test(#fmt("%+d", 0), "+0");
   test(#fmt("%+d", 1), "+1");
   test(#fmt("%+d", -1), "-1");
+
+  // Leave space for sign
+  test(#fmt("% d", 0), " 0");
+  test(#fmt("% d", 1), " 1");
+  test(#fmt("% d", -1), "-1");
+
+  // Plus overrides space
+  test(#fmt("% +d", 0), "+0");
+  test(#fmt("%+ d", 0), "+0");
 }