Make #fmt support explicit conversion widths
This commit is contained in:
parent
07e820089f
commit
dcfdb02fab
3 changed files with 91 additions and 13 deletions
|
|
@ -91,6 +91,11 @@ fn pieces_to_expr(vec[piece] pieces, vec[@ast.expr] args) -> @ast.expr {
|
|||
ret make_new_lit(sp, lit);
|
||||
}
|
||||
|
||||
fn make_new_int(common.span sp, int i) -> @ast.expr {
|
||||
auto lit = ast.lit_int(i);
|
||||
ret make_new_lit(sp, lit);
|
||||
}
|
||||
|
||||
fn make_new_uint(common.span sp, uint u) -> @ast.expr {
|
||||
auto lit = ast.lit_uint(u);
|
||||
ret make_new_lit(sp, lit);
|
||||
|
|
@ -145,6 +150,26 @@ fn pieces_to_expr(vec[piece] pieces, vec[@ast.expr] args) -> @ast.expr {
|
|||
}
|
||||
|
||||
fn make_rt_conv_expr(common.span sp, &conv cnv) -> @ast.expr {
|
||||
|
||||
fn make_count(common.span sp, &count cnt) -> @ast.expr {
|
||||
alt (cnt) {
|
||||
case (count_implied) {
|
||||
auto idents = make_path_vec("count_implied");
|
||||
ret make_path_expr(sp, idents);
|
||||
}
|
||||
case (count_is(?c)) {
|
||||
auto count_lit = make_new_int(sp, c);
|
||||
auto count_is_path = make_path_vec("count_is");
|
||||
auto count_is_args = vec(count_lit);
|
||||
ret make_call(sp, count_is_path, count_is_args);
|
||||
}
|
||||
case (_) {
|
||||
log "not implemented";
|
||||
fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn make_ty(common.span sp, &ty t) -> @ast.expr {
|
||||
auto rt_type;
|
||||
alt (t) {
|
||||
|
|
@ -170,12 +195,17 @@ fn pieces_to_expr(vec[piece] pieces, vec[@ast.expr] args) -> @ast.expr {
|
|||
ret make_path_expr(sp, idents);
|
||||
}
|
||||
|
||||
fn make_conv_rec(common.span sp, &@ast.expr ty_expr) -> @ast.expr {
|
||||
ret make_rec_expr(sp, vec(tup("ty", ty_expr)));
|
||||
fn make_conv_rec(common.span sp, @ast.expr width_expr,
|
||||
@ast.expr ty_expr) -> @ast.expr {
|
||||
ret make_rec_expr(sp, vec(tup("width", width_expr),
|
||||
tup("ty", ty_expr)));
|
||||
}
|
||||
|
||||
auto rt_conv_width = make_count(sp, cnv.width);
|
||||
auto rt_conv_ty = make_ty(sp, cnv.ty);
|
||||
ret make_conv_rec(sp, rt_conv_ty);
|
||||
ret make_conv_rec(sp,
|
||||
rt_conv_width,
|
||||
rt_conv_ty);
|
||||
}
|
||||
|
||||
fn make_conv_call(common.span sp, str conv_type,
|
||||
|
|
@ -208,6 +238,8 @@ fn pieces_to_expr(vec[piece] pieces, vec[@ast.expr] args) -> @ast.expr {
|
|||
alt (cnv.width) {
|
||||
case (count_implied) {
|
||||
}
|
||||
case (count_is(_)) {
|
||||
}
|
||||
case (_) {
|
||||
log unsupported;
|
||||
fail;
|
||||
|
|
@ -225,7 +257,7 @@ fn pieces_to_expr(vec[piece] pieces, vec[@ast.expr] args) -> @ast.expr {
|
|||
|
||||
alt (cnv.ty) {
|
||||
case (ty_str) {
|
||||
ret arg;
|
||||
ret make_conv_call(arg.span, "str", cnv, arg);
|
||||
}
|
||||
case (ty_int(?sign)) {
|
||||
alt (sign) {
|
||||
|
|
|
|||
|
|
@ -294,6 +294,11 @@ mod CT {
|
|||
// implement it this way, I think.
|
||||
mod RT {
|
||||
|
||||
tag count {
|
||||
count_is(int);
|
||||
count_implied;
|
||||
}
|
||||
|
||||
tag ty {
|
||||
ty_default;
|
||||
ty_bits;
|
||||
|
|
@ -301,39 +306,70 @@ mod RT {
|
|||
ty_hex_lower;
|
||||
}
|
||||
|
||||
type conv = rec(ty ty);
|
||||
type conv = rec(count width,
|
||||
ty ty);
|
||||
|
||||
fn conv_int(&conv cv, int i) -> str {
|
||||
ret _int.to_str(i, 10u);
|
||||
ret pad(cv, _int.to_str(i, 10u));
|
||||
}
|
||||
|
||||
fn conv_uint(&conv cv, uint u) -> str {
|
||||
auto res;
|
||||
alt (cv.ty) {
|
||||
case (ty_default) {
|
||||
ret _uint.to_str(u, 10u);
|
||||
res = _uint.to_str(u, 10u);
|
||||
}
|
||||
case (ty_hex_lower) {
|
||||
ret _uint.to_str(u, 16u);
|
||||
res = _uint.to_str(u, 16u);
|
||||
}
|
||||
case (ty_hex_upper) {
|
||||
ret _str.to_upper(_uint.to_str(u, 16u));
|
||||
res = _str.to_upper(_uint.to_str(u, 16u));
|
||||
}
|
||||
case (ty_bits) {
|
||||
ret _uint.to_str(u, 2u);
|
||||
res = _uint.to_str(u, 2u);
|
||||
}
|
||||
}
|
||||
ret pad(cv, res);
|
||||
}
|
||||
|
||||
fn conv_bool(&conv cv, bool b) -> str {
|
||||
if (b) {
|
||||
ret "true";
|
||||
ret pad(cv, "true");
|
||||
} else {
|
||||
ret "false";
|
||||
ret pad(cv, "false");
|
||||
}
|
||||
}
|
||||
|
||||
fn conv_char(&conv cv, char c) -> str {
|
||||
ret _str.from_char(c);
|
||||
ret pad(cv, _str.from_char(c));
|
||||
}
|
||||
|
||||
fn conv_str(&conv cv, str s) -> str {
|
||||
ret pad(cv, s);
|
||||
}
|
||||
|
||||
fn pad(&conv cv, str s) -> str {
|
||||
alt (cv.width) {
|
||||
case (count_implied) {
|
||||
ret s;
|
||||
}
|
||||
case (count_is(?width)) {
|
||||
// FIXME: Maybe width should be uint
|
||||
auto uwidth = width as uint;
|
||||
auto strlen = _str.char_len(s);
|
||||
if (strlen < uwidth) {
|
||||
auto diff = uwidth - strlen;
|
||||
// FIXME: Probably should be a _str fn for this
|
||||
auto padvec = _vec.init_elt[u8](' ' as u8, diff);
|
||||
// FIXME: Using unsafe_from_bytes because rustboot
|
||||
// can't figure out the is_utf8 predicate on from_bytes?
|
||||
auto padstr = _str.unsafe_from_bytes(padvec);
|
||||
ret padstr + s;
|
||||
} else {
|
||||
ret s;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,4 +32,14 @@ fn main() {
|
|||
test(#fmt("%u", 4294967295u), "4294967295");
|
||||
test(#fmt("%x", 0xffffffff_u), "ffffffff");
|
||||
test(#fmt("%t", 0xffffffff_u), "11111111111111111111111111111111");
|
||||
|
||||
// Widths
|
||||
test(#fmt("%10d", 500), " 500");
|
||||
test(#fmt("%10d", -500), " -500");
|
||||
test(#fmt("%10u", 500u), " 500");
|
||||
test(#fmt("%10s", "test"), " test");
|
||||
test(#fmt("%10b", true), " true");
|
||||
test(#fmt("%10x", 0xff_u), " ff");
|
||||
test(#fmt("%10X", 0xff_u), " FF");
|
||||
test(#fmt("%10t", 0xff_u), " 11111111");
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue