aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Anderson <[email protected]>2011-04-13 20:14:59 -0400
committerBrian Anderson <[email protected]>2011-04-13 22:14:24 -0400
commit4844e1c08a0f87f8c2bf4ba752630e1af0794a63 (patch)
treea7d877e2298ac884441ab73002a48f05e897e7c7
parentMove #fmt conversion model into ExtFmt.CT namespace (diff)
downloadrust-4844e1c08a0f87f8c2bf4ba752630e1af0794a63.tar.xz
rust-4844e1c08a0f87f8c2bf4ba752630e1af0794a63.zip
Add support for printing uints as lower-case hex to ExtFmt.
Begin passing an ExtFmt.RT.conv parsed format description to each of the ExtFmt.RT.conv* functions.
-rw-r--r--src/comp/front/extfmt.rs91
-rw-r--r--src/lib/ExtFmt.rs27
-rw-r--r--src/test/run-pass/syntax-extension-fmt.rs1
3 files changed, 101 insertions, 18 deletions
diff --git a/src/comp/front/extfmt.rs b/src/comp/front/extfmt.rs
index 3a12fb82..bb9f8832 100644
--- a/src/comp/front/extfmt.rs
+++ b/src/comp/front/extfmt.rs
@@ -111,24 +111,86 @@ fn pieces_to_expr(vec[piece] pieces, vec[@ast.expr] args) -> @ast.expr {
ret @rec(node=binexpr, span=sp);
}
- fn make_call(common.span sp, vec[ast.ident] fn_path,
- vec[@ast.expr] args) -> @ast.expr {
- let vec[ast.ident] path_idents = fn_path;
- let vec[@ast.ty] path_types = vec();
- auto path = rec(idents = path_idents, types = path_types);
+ fn make_path_expr(common.span sp, vec[ast.ident] idents) -> @ast.expr {
+ let vec[@ast.ty] types = vec();
+ auto path = rec(idents=idents, types=types);
auto sp_path = rec(node=path, span=sp);
auto pathexpr = ast.expr_path(sp_path, none[ast.def], ast.ann_none);
auto sp_pathexpr = @rec(node=pathexpr, span=sp);
- auto callexpr = ast.expr_call(sp_pathexpr, args, ast.ann_none);
+ ret sp_pathexpr;
+ }
+
+ fn make_call(common.span sp, vec[ast.ident] fn_path,
+ vec[@ast.expr] args) -> @ast.expr {
+ auto pathexpr = make_path_expr(sp, fn_path);
+ auto callexpr = ast.expr_call(pathexpr, args, ast.ann_none);
auto sp_callexpr = @rec(node=callexpr, span=sp);
ret sp_callexpr;
}
+ fn make_rec_expr(common.span sp,
+ vec[tup(ast.ident, @ast.expr)] fields) -> @ast.expr {
+ let vec[ast.field] astfields = vec();
+ for (tup(ast.ident, @ast.expr) field in fields) {
+ auto ident = field._0;
+ auto val = field._1;
+ auto astfield = rec(mut = ast.imm,
+ ident = ident,
+ expr = val);
+ astfields += vec(astfield);
+ }
+
+ auto recexpr = ast.expr_rec(astfields,
+ option.none[@ast.expr],
+ ast.ann_none);
+ auto sp_recexpr = @rec(node=recexpr, span=sp);
+ ret sp_recexpr;
+ }
+
+ fn make_path_vec(str ident) -> vec[str] {
+ ret vec("std", "ExtFmt", "RT", ident);
+ }
+
+ fn make_rt_conv_expr(common.span sp, &conv cnv) -> @ast.expr {
+ fn make_ty(common.span sp, &ty t) -> @ast.expr {
+ auto rt_type;
+ alt (t) {
+ case (ty_hex(?c)) {
+ alt (c) {
+ case (case_upper) {
+ rt_type = "ty_hex_upper";
+ }
+ case (case_lower) {
+ rt_type = "ty_hex_lower";
+ }
+ }
+ }
+ case (ty_bits) {
+ rt_type = "ty_bits";
+ }
+ case (_) {
+ rt_type = "ty_default";
+ }
+ }
+
+ auto idents = make_path_vec(rt_type);
+ 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)));
+ }
+
+ auto rt_conv_ty = make_ty(sp, cnv.ty);
+ ret make_conv_rec(sp, rt_conv_ty);
+ }
+
fn make_conv_call(common.span sp, str conv_type,
- @ast.expr arg) -> @ast.expr {
+ &conv cnv, @ast.expr arg) -> @ast.expr {
auto fname = "conv_" + conv_type;
- let vec[str] path = vec("std", "ExtFmt", "RT", fname);
- let vec[@ast.expr] args = vec(arg);
+ auto path = make_path_vec(fname);
+ auto cnv_expr = make_rt_conv_expr(sp, cnv);
+ auto args = vec(cnv_expr, arg);
ret make_call(arg.span, path, args);
}
@@ -175,18 +237,21 @@ fn pieces_to_expr(vec[piece] pieces, vec[@ast.expr] args) -> @ast.expr {
case (ty_int(?sign)) {
alt (sign) {
case (signed) {
- ret make_conv_call(arg.span, "int", arg);
+ ret make_conv_call(arg.span, "int", cnv, arg);
}
case (unsigned) {
- ret make_conv_call(arg.span, "uint", arg);
+ ret make_conv_call(arg.span, "uint", cnv, arg);
}
}
}
case (ty_bool) {
- ret make_conv_call(arg.span, "bool", arg);
+ ret make_conv_call(arg.span, "bool", cnv, arg);
}
case (ty_char) {
- ret make_conv_call(arg.span, "char", arg);
+ ret make_conv_call(arg.span, "char", cnv, arg);
+ }
+ case (ty_hex(_)) {
+ ret make_conv_call(arg.span, "uint", cnv, arg);
}
case (_) {
log unsupported;
diff --git a/src/lib/ExtFmt.rs b/src/lib/ExtFmt.rs
index 35b9c5dd..229a0c5d 100644
--- a/src/lib/ExtFmt.rs
+++ b/src/lib/ExtFmt.rs
@@ -264,15 +264,32 @@ mod CT {
// Functions used by the fmt extension at runtime
mod RT {
- fn conv_int(int i) -> str {
+
+ tag ty {
+ ty_default;
+ ty_bits;
+ ty_hex_upper;
+ ty_hex_lower;
+ }
+
+ type conv = rec(ty ty);
+
+ fn conv_int(&conv cv, int i) -> str {
ret _int.to_str(i, 10u);
}
- fn conv_uint(uint u) -> str {
- ret _uint.to_str(u, 10u);
+ fn conv_uint(&conv cv, uint u) -> str {
+ alt (cv.ty) {
+ case (ty_default) {
+ ret _uint.to_str(u, 10u);
+ }
+ case (ty_hex_lower) {
+ ret _uint.to_str(u, 16u);
+ }
+ }
}
- fn conv_bool(bool b) -> str {
+ fn conv_bool(&conv cv, bool b) -> str {
if (b) {
ret "true";
} else {
@@ -280,7 +297,7 @@ mod RT {
}
}
- fn conv_char(char c) -> str {
+ fn conv_char(&conv cv, char c) -> str {
ret _str.from_char(c);
}
}
diff --git a/src/test/run-pass/syntax-extension-fmt.rs b/src/test/run-pass/syntax-extension-fmt.rs
index 36983fd4..78a414b3 100644
--- a/src/test/run-pass/syntax-extension-fmt.rs
+++ b/src/test/run-pass/syntax-extension-fmt.rs
@@ -22,4 +22,5 @@ fn main() {
test(#fmt("%b", true), "true");
test(#fmt("%b", false), "false");
test(#fmt("%c", 'A'), "A");
+ test(#fmt("%x", 0xff_u), "ff");
}