aboutsummaryrefslogtreecommitdiff
path: root/src/comp
diff options
context:
space:
mode:
authorBrian Anderson <[email protected]>2011-02-27 19:44:57 -0500
committerGraydon Hoare <[email protected]>2011-03-02 10:28:14 -0800
commit61edf544a2d16b43d0c4ba1c7537d6a8475f681c (patch)
tree177669ff5ce99c71235b2e122240957c25618250 /src/comp
parentStart generating AST nodes for #fmt (diff)
downloadrust-61edf544a2d16b43d0c4ba1c7537d6a8475f681c.tar.xz
rust-61edf544a2d16b43d0c4ba1c7537d6a8475f681c.zip
Implement #fmt conversion for int and uint
Diffstat (limited to 'src/comp')
-rw-r--r--src/comp/front/extfmt.rs115
1 files changed, 107 insertions, 8 deletions
diff --git a/src/comp/front/extfmt.rs b/src/comp/front/extfmt.rs
index 38c2ea8c..bd5bab5b 100644
--- a/src/comp/front/extfmt.rs
+++ b/src/comp/front/extfmt.rs
@@ -21,6 +21,8 @@ import std.option;
import std.option.none;
import std.option.some;
+export expand_syntax_ext;
+
tag signedness {
signed;
unsigned;
@@ -61,7 +63,7 @@ type conv = rec(option.t[int] param,
vec[flag] flags,
count width,
count precision,
- ty typ);
+ ty ty);
// A fragment of the output sequence
tag piece {
@@ -74,6 +76,7 @@ fn bad_fmt_call() {
fail;
}
+// TODO: Need to thread parser through here to handle errors correctly
fn expand_syntax_ext(vec[@ast.expr] args,
option.t[@ast.expr] body) -> @ast.expr {
@@ -96,6 +99,8 @@ fn expand_syntax_ext(vec[@ast.expr] args,
}
}
log "done printing all pieces";
+ auto args_len = _vec.len[@ast.expr](args);
+ auto fmt_args = _vec.slice[@ast.expr](args, 1u, args_len - 1u);
ret pieces_to_expr(pieces, args);
}
@@ -179,7 +184,7 @@ fn parse_conversion(str s, uint i, uint lim) -> tup(piece, uint) {
flags = flags._0,
width = width._0,
precision = prec._0,
- typ = ty._0)),
+ ty = ty._0)),
ty._1);
}
@@ -252,22 +257,107 @@ fn parse_type(str s, uint i, uint lim) -> tup(ty, uint) {
fn pieces_to_expr(vec[piece] pieces, vec[@ast.expr] args) -> @ast.expr {
- fn make_new_str(common.span sp, str s) -> @ast.expr {
- auto strlit = ast.lit_str(s);
- auto spstrlit = @parser.spanned[ast.lit_](sp, sp, strlit);
- auto expr = ast.expr_lit(spstrlit, ast.ann_none);
+ fn make_new_lit(common.span sp, ast.lit_ lit) -> @ast.expr {
+ auto sp_lit = @parser.spanned[ast.lit_](sp, sp, lit);
+ auto expr = ast.expr_lit(sp_lit, ast.ann_none);
ret @parser.spanned[ast.expr_](sp, sp, expr);
}
+ fn make_new_str(common.span sp, str s) -> @ast.expr {
+ auto lit = ast.lit_str(s);
+ 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);
+ }
+
fn make_add_expr(common.span sp,
@ast.expr lhs, @ast.expr rhs) -> @ast.expr {
auto binexpr = ast.expr_binary(ast.add, lhs, rhs, ast.ann_none);
ret @parser.spanned[ast.expr_](sp, sp, binexpr);
}
+ 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);
+ auto sp_path = parser.spanned[ast.path_](sp, sp, path);
+ auto pathexpr = ast.expr_path(sp_path, none[ast.def], ast.ann_none);
+ auto sp_pathexpr = @parser.spanned[ast.expr_](sp, sp, pathexpr);
+ auto callexpr = ast.expr_call(sp_pathexpr, args, ast.ann_none);
+ auto sp_callexpr = @parser.spanned[ast.expr_](sp, sp, callexpr);
+ ret sp_callexpr;
+ }
+
+ fn make_new_conv(conv cnv, @ast.expr arg) -> @ast.expr {
+
+ auto unsupported = "conversion not supported in #fmt string";
+
+ alt (cnv.param) {
+ case (option.none[int]) {
+ }
+ case (_) {
+ log unsupported;
+ fail;
+ }
+ }
+
+ if (_vec.len[flag](cnv.flags) != 0u) {
+ log unsupported;
+ fail;
+ }
+
+ alt (cnv.width) {
+ case (count_implied) {
+ }
+ case (_) {
+ log unsupported;
+ fail;
+ }
+ }
+
+ alt (cnv.precision) {
+ case (count_implied) {
+ }
+ case (_) {
+ log unsupported;
+ fail;
+ }
+ }
+
+ alt (cnv.ty) {
+ case (ty_str) {
+ ret arg;
+ }
+ case (ty_int(?sign)) {
+ alt (sign) {
+ case (signed) {
+ let vec[str] path = vec("std", "_int", "to_str");
+ auto radix_expr = make_new_uint(arg.span, 10u);
+ let vec[@ast.expr] args = vec(arg, radix_expr);
+ ret make_call(arg.span, path, args);
+ }
+ case (unsigned) {
+ let vec[str] path = vec("std", "_uint", "to_str");
+ auto radix_expr = make_new_uint(arg.span, 10u);
+ let vec[@ast.expr] args = vec(arg, radix_expr);
+ ret make_call(arg.span, path, args);
+ }
+ }
+ }
+ case (_) {
+ log unsupported;
+ fail;
+ }
+ }
+ }
+
auto sp = args.(0).span;
- auto n = 0;
- auto tmp_expr = make_new_str(sp, "whatever");
+ auto n = 0u;
+ auto tmp_expr = make_new_str(sp, "");
for (piece p in pieces) {
alt (p) {
@@ -276,6 +366,15 @@ fn pieces_to_expr(vec[piece] pieces, vec[@ast.expr] args) -> @ast.expr {
tmp_expr = make_add_expr(sp, tmp_expr, s_expr);
}
case (piece_conv(?conv)) {
+ if (n >= _vec.len[@ast.expr](args)) {
+ log "too many conversions in #fmt string";
+ fail;
+ }
+
+ n += 1u;
+ auto arg_expr = args.(n);
+ auto c_expr = make_new_conv(conv, arg_expr);
+ tmp_expr = make_add_expr(sp, tmp_expr, c_expr);
}
}
}