diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/comp/front/extfmt.rs | 54 | ||||
| -rw-r--r-- | src/lib/ExtFmt.rs | 13 | ||||
| -rw-r--r-- | src/test/run-pass/syntax-extension-fmt.rs | 9 |
3 files changed, 53 insertions, 23 deletions
diff --git a/src/comp/front/extfmt.rs b/src/comp/front/extfmt.rs index c05c74d1..287c7e55 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 c2cce279..c6ddad30 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 1e283c2d..61143e4a 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"); } |