Implement #fmt conversion for int and uint
This commit is contained in:
parent
f9144d5972
commit
61edf544a2
@ -21,6 +21,8 @@ import std.option;
|
|||||||
import std.option.none;
|
import std.option.none;
|
||||||
import std.option.some;
|
import std.option.some;
|
||||||
|
|
||||||
|
export expand_syntax_ext;
|
||||||
|
|
||||||
tag signedness {
|
tag signedness {
|
||||||
signed;
|
signed;
|
||||||
unsigned;
|
unsigned;
|
||||||
@ -61,7 +63,7 @@ type conv = rec(option.t[int] param,
|
|||||||
vec[flag] flags,
|
vec[flag] flags,
|
||||||
count width,
|
count width,
|
||||||
count precision,
|
count precision,
|
||||||
ty typ);
|
ty ty);
|
||||||
|
|
||||||
// A fragment of the output sequence
|
// A fragment of the output sequence
|
||||||
tag piece {
|
tag piece {
|
||||||
@ -74,6 +76,7 @@ fn bad_fmt_call() {
|
|||||||
fail;
|
fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Need to thread parser through here to handle errors correctly
|
||||||
fn expand_syntax_ext(vec[@ast.expr] args,
|
fn expand_syntax_ext(vec[@ast.expr] args,
|
||||||
option.t[@ast.expr] body) -> @ast.expr {
|
option.t[@ast.expr] body) -> @ast.expr {
|
||||||
|
|
||||||
@ -96,6 +99,8 @@ fn expand_syntax_ext(vec[@ast.expr] args,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
log "done printing all pieces";
|
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);
|
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,
|
flags = flags._0,
|
||||||
width = width._0,
|
width = width._0,
|
||||||
precision = prec._0,
|
precision = prec._0,
|
||||||
typ = ty._0)),
|
ty = ty._0)),
|
||||||
ty._1);
|
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 pieces_to_expr(vec[piece] pieces, vec[@ast.expr] args) -> @ast.expr {
|
||||||
|
|
||||||
fn make_new_str(common.span sp, str s) -> @ast.expr {
|
fn make_new_lit(common.span sp, ast.lit_ lit) -> @ast.expr {
|
||||||
auto strlit = ast.lit_str(s);
|
auto sp_lit = @parser.spanned[ast.lit_](sp, sp, lit);
|
||||||
auto spstrlit = @parser.spanned[ast.lit_](sp, sp, strlit);
|
auto expr = ast.expr_lit(sp_lit, ast.ann_none);
|
||||||
auto expr = ast.expr_lit(spstrlit, ast.ann_none);
|
|
||||||
ret @parser.spanned[ast.expr_](sp, sp, expr);
|
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,
|
fn make_add_expr(common.span sp,
|
||||||
@ast.expr lhs, @ast.expr rhs) -> @ast.expr {
|
@ast.expr lhs, @ast.expr rhs) -> @ast.expr {
|
||||||
auto binexpr = ast.expr_binary(ast.add, lhs, rhs, ast.ann_none);
|
auto binexpr = ast.expr_binary(ast.add, lhs, rhs, ast.ann_none);
|
||||||
ret @parser.spanned[ast.expr_](sp, sp, binexpr);
|
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 sp = args.(0).span;
|
||||||
auto n = 0;
|
auto n = 0u;
|
||||||
auto tmp_expr = make_new_str(sp, "whatever");
|
auto tmp_expr = make_new_str(sp, "");
|
||||||
|
|
||||||
for (piece p in pieces) {
|
for (piece p in pieces) {
|
||||||
alt (p) {
|
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);
|
tmp_expr = make_add_expr(sp, tmp_expr, s_expr);
|
||||||
}
|
}
|
||||||
case (piece_conv(?conv)) {
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user