Rename std.extfmt.CT to std.extfmt.RT to ct and rt
Temporarily duplicate the entire RT module, leaving it with the old name to accomodate the stage0 compiler. Will be removed after the next snapshot.
This commit is contained in:
parent
5295a4dabd
commit
02fdd2d2d9
@ -13,36 +13,36 @@ import std::option;
|
||||
import std::option::none;
|
||||
import std::option::some;
|
||||
|
||||
import std::extfmt::CT::signedness;
|
||||
import std::extfmt::CT::signed;
|
||||
import std::extfmt::CT::unsigned;
|
||||
import std::extfmt::CT::caseness;
|
||||
import std::extfmt::CT::case_upper;
|
||||
import std::extfmt::CT::case_lower;
|
||||
import std::extfmt::CT::ty;
|
||||
import std::extfmt::CT::ty_bool;
|
||||
import std::extfmt::CT::ty_str;
|
||||
import std::extfmt::CT::ty_char;
|
||||
import std::extfmt::CT::ty_int;
|
||||
import std::extfmt::CT::ty_bits;
|
||||
import std::extfmt::CT::ty_hex;
|
||||
import std::extfmt::CT::ty_octal;
|
||||
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_space_for_sign;
|
||||
import std::extfmt::CT::flag_sign_always;
|
||||
import std::extfmt::CT::flag_alternate;
|
||||
import std::extfmt::CT::count;
|
||||
import std::extfmt::CT::count_is;
|
||||
import std::extfmt::CT::count_is_param;
|
||||
import std::extfmt::CT::count_is_next_param;
|
||||
import std::extfmt::CT::count_implied;
|
||||
import std::extfmt::CT::conv;
|
||||
import std::extfmt::CT::piece;
|
||||
import std::extfmt::CT::piece_string;
|
||||
import std::extfmt::CT::piece_conv;
|
||||
import std::extfmt::CT::parse_fmt_string;
|
||||
import std::extfmt::ct::signedness;
|
||||
import std::extfmt::ct::signed;
|
||||
import std::extfmt::ct::unsigned;
|
||||
import std::extfmt::ct::caseness;
|
||||
import std::extfmt::ct::case_upper;
|
||||
import std::extfmt::ct::case_lower;
|
||||
import std::extfmt::ct::ty;
|
||||
import std::extfmt::ct::ty_bool;
|
||||
import std::extfmt::ct::ty_str;
|
||||
import std::extfmt::ct::ty_char;
|
||||
import std::extfmt::ct::ty_int;
|
||||
import std::extfmt::ct::ty_bits;
|
||||
import std::extfmt::ct::ty_hex;
|
||||
import std::extfmt::ct::ty_octal;
|
||||
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_space_for_sign;
|
||||
import std::extfmt::ct::flag_sign_always;
|
||||
import std::extfmt::ct::flag_alternate;
|
||||
import std::extfmt::ct::count;
|
||||
import std::extfmt::ct::count_is;
|
||||
import std::extfmt::ct::count_is_param;
|
||||
import std::extfmt::ct::count_is_next_param;
|
||||
import std::extfmt::ct::count_implied;
|
||||
import std::extfmt::ct::conv;
|
||||
import std::extfmt::ct::piece;
|
||||
import std::extfmt::ct::piece_string;
|
||||
import std::extfmt::ct::piece_conv;
|
||||
import std::extfmt::ct::parse_fmt_string;
|
||||
|
||||
export expand_syntax_ext;
|
||||
|
||||
@ -163,7 +163,7 @@ fn pieces_to_expr(parser p, vec[piece] pieces, vec[@ast::expr] args)
|
||||
fn make_path_vec(str ident) -> vec[str] {
|
||||
// FIXME: #fmt can't currently be used from within std
|
||||
// because we're explicitly referencing the 'std' crate here
|
||||
ret vec("std", "extfmt", "RT", ident);
|
||||
ret vec("std", "extfmt", "rt", ident);
|
||||
}
|
||||
|
||||
fn make_rt_path_expr(parser p, common::span sp, str ident) -> @ast::expr {
|
||||
@ -290,7 +290,7 @@ fn pieces_to_expr(parser p, vec[piece] pieces, vec[@ast::expr] args)
|
||||
|
||||
fn make_new_conv(parser p, conv cnv, @ast::expr arg) -> @ast::expr {
|
||||
|
||||
// FIXME: Extract all this validation into extfmt::CT
|
||||
// FIXME: Extract all this validation into extfmt::ct
|
||||
fn is_signed_type(conv cnv) -> bool {
|
||||
alt (cnv.ty) {
|
||||
case (ty_int(?s)) {
|
||||
|
@ -28,7 +28,7 @@ import option::some;
|
||||
*/
|
||||
|
||||
// Functions used by the fmt extension at compile time
|
||||
mod CT {
|
||||
mod ct {
|
||||
tag signedness {
|
||||
signed;
|
||||
unsigned;
|
||||
@ -305,7 +305,7 @@ mod CT {
|
||||
// decisions made a runtime. If it proves worthwhile then some of these
|
||||
// conditions can be evaluated at compile-time. For now though it's cleaner to
|
||||
// implement it this way, I think.
|
||||
mod RT {
|
||||
mod rt {
|
||||
|
||||
tag flag {
|
||||
flag_left_justify;
|
||||
@ -558,6 +558,260 @@ mod RT {
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: This is a temporary duplication of the rt mod that only
|
||||
// needs to exist to accomodate the stage0 compiler until the next snapshot
|
||||
mod RT {
|
||||
tag flag {
|
||||
flag_left_justify;
|
||||
flag_left_zero_pad;
|
||||
flag_space_for_sign;
|
||||
flag_sign_always;
|
||||
flag_alternate;
|
||||
// FIXME: This is a hack to avoid creating 0-length vec exprs,
|
||||
// which have some difficulty typechecking currently. See
|
||||
// comments in front::extfmt::make_flags
|
||||
flag_none;
|
||||
}
|
||||
|
||||
tag count {
|
||||
count_is(int);
|
||||
count_implied;
|
||||
}
|
||||
|
||||
tag ty {
|
||||
ty_default;
|
||||
ty_bits;
|
||||
ty_hex_upper;
|
||||
ty_hex_lower;
|
||||
ty_octal;
|
||||
}
|
||||
|
||||
// FIXME: May not want to use a vector here for flags;
|
||||
// instead just use a bool per flag
|
||||
type conv = rec(vec[flag] flags,
|
||||
count width,
|
||||
count precision,
|
||||
ty ty);
|
||||
|
||||
fn conv_int(&conv cv, int i) -> str {
|
||||
auto radix = 10u;
|
||||
auto prec = get_int_precision(cv);
|
||||
auto s = int_to_str_prec(i, radix, prec);
|
||||
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, pad_signed);
|
||||
}
|
||||
|
||||
fn conv_uint(&conv cv, uint u) -> str {
|
||||
auto prec = get_int_precision(cv);
|
||||
auto res;
|
||||
alt (cv.ty) {
|
||||
case (ty_default) {
|
||||
res = uint_to_str_prec(u, 10u, prec);
|
||||
}
|
||||
case (ty_hex_lower) {
|
||||
res = uint_to_str_prec(u, 16u, prec);
|
||||
}
|
||||
case (ty_hex_upper) {
|
||||
res = _str::to_upper(uint_to_str_prec(u, 16u, prec));
|
||||
}
|
||||
case (ty_bits) {
|
||||
res = uint_to_str_prec(u, 2u, prec);
|
||||
}
|
||||
case (ty_octal) {
|
||||
res = uint_to_str_prec(u, 8u, prec);
|
||||
}
|
||||
}
|
||||
ret pad(cv, res, pad_unsigned);
|
||||
}
|
||||
|
||||
fn conv_bool(&conv cv, bool b) -> str {
|
||||
auto s;
|
||||
if (b) {
|
||||
s = "true";
|
||||
} else {
|
||||
s = "false";
|
||||
}
|
||||
// run the boolean conversion through the string conversion logic,
|
||||
// giving it the same rules for precision, etc.
|
||||
ret conv_str(cv, s);
|
||||
}
|
||||
|
||||
fn conv_char(&conv cv, char c) -> str {
|
||||
ret pad(cv, _str::from_char(c), pad_nozero);
|
||||
}
|
||||
|
||||
fn conv_str(&conv cv, str s) -> str {
|
||||
auto unpadded = s;
|
||||
alt (cv.precision) {
|
||||
case (count_implied) {
|
||||
}
|
||||
case (count_is(?max)) {
|
||||
// For strings, precision is the maximum characters displayed
|
||||
if (max as uint < _str::char_len(s)) {
|
||||
// FIXME: substr works on bytes, not chars!
|
||||
unpadded = _str::substr(s, 0u, max as uint);
|
||||
}
|
||||
}
|
||||
}
|
||||
ret pad(cv, unpadded, pad_nozero);
|
||||
}
|
||||
|
||||
// Convert an int to string with minimum number of digits. If precision is
|
||||
// 0 and num is 0 then the result is the empty string.
|
||||
fn int_to_str_prec(int num, uint radix, uint prec) -> str {
|
||||
if (num < 0) {
|
||||
ret "-" + uint_to_str_prec((-num) as uint, radix, prec);
|
||||
} else {
|
||||
ret uint_to_str_prec(num as uint, radix, prec);
|
||||
}
|
||||
}
|
||||
|
||||
// Convert a uint to string with a minimum number of digits. If precision
|
||||
// is 0 and num is 0 then the result is the empty string. Could move this
|
||||
// to _uint: but it doesn't seem all that useful.
|
||||
fn uint_to_str_prec(uint num, uint radix, uint prec) -> str {
|
||||
auto s;
|
||||
|
||||
if (prec == 0u && num == 0u) {
|
||||
s = "";
|
||||
} else {
|
||||
s = _uint::to_str(num, radix);
|
||||
auto len = _str::char_len(s);
|
||||
if (len < prec) {
|
||||
auto diff = prec - len;
|
||||
auto pad = str_init_elt('0', diff);
|
||||
s = pad + s;
|
||||
}
|
||||
}
|
||||
|
||||
ret s;
|
||||
}
|
||||
|
||||
fn get_int_precision(&conv cv) -> uint {
|
||||
alt (cv.precision) {
|
||||
case (count_is(?c)) {
|
||||
ret c as uint;
|
||||
}
|
||||
case (count_implied) {
|
||||
ret 1u;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: This might be useful in _str: but needs to be utf8 safe first
|
||||
fn str_init_elt(char c, uint n_elts) -> str {
|
||||
auto svec = _vec::init_elt[u8](c as u8, n_elts);
|
||||
// FIXME: Using unsafe_from_bytes because rustboot
|
||||
// can't figure out the is_utf8 predicate on from_bytes?
|
||||
ret _str::unsafe_from_bytes(svec);
|
||||
}
|
||||
|
||||
tag pad_mode {
|
||||
pad_signed;
|
||||
pad_unsigned;
|
||||
pad_nozero;
|
||||
}
|
||||
|
||||
fn pad(&conv cv, str s, pad_mode mode) -> str {
|
||||
auto uwidth;
|
||||
alt (cv.width) {
|
||||
case (count_implied) {
|
||||
ret s;
|
||||
}
|
||||
case (count_is(?width)) {
|
||||
// FIXME: Maybe width should be uint
|
||||
uwidth = width as uint;
|
||||
}
|
||||
}
|
||||
|
||||
auto strlen = _str::char_len(s);
|
||||
if (uwidth <= strlen) {
|
||||
ret s;
|
||||
}
|
||||
|
||||
auto padchar = ' ';
|
||||
auto diff = uwidth - strlen;
|
||||
if (have_flag(cv.flags, flag_left_justify)) {
|
||||
auto padstr = str_init_elt(padchar, diff);
|
||||
ret s + padstr;
|
||||
}
|
||||
|
||||
auto might_zero_pad = false;
|
||||
auto signed = false;
|
||||
|
||||
alt (mode) {
|
||||
case (pad_nozero) {
|
||||
// fallthrough
|
||||
}
|
||||
case (pad_signed) {
|
||||
might_zero_pad = true;
|
||||
signed = true;
|
||||
}
|
||||
case (pad_unsigned) {
|
||||
might_zero_pad = true;
|
||||
}
|
||||
}
|
||||
|
||||
fn have_precision(&conv cv) -> bool {
|
||||
alt (cv.precision) {
|
||||
case (count_implied) {
|
||||
ret false;
|
||||
}
|
||||
case (_) {
|
||||
ret true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto zero_padding = false;
|
||||
if (might_zero_pad
|
||||
&& have_flag(cv.flags, flag_left_zero_pad)
|
||||
&& !have_precision(cv)) {
|
||||
|
||||
padchar = '0';
|
||||
zero_padding = true;
|
||||
}
|
||||
|
||||
auto padstr = str_init_elt(padchar, diff);
|
||||
|
||||
// This is completely heinous. If we have a signed value then
|
||||
// potentially rip apart the intermediate result and insert some
|
||||
// zeros. It may make sense to convert zero padding to a precision
|
||||
// instead.
|
||||
if (signed
|
||||
&& zero_padding
|
||||
&& _str::byte_len(s) > 0u) {
|
||||
|
||||
auto head = s.(0);
|
||||
if (head == '+' as u8
|
||||
|| head == '-' as u8
|
||||
|| head == ' ' as u8) {
|
||||
|
||||
auto headstr = _str::unsafe_from_bytes(vec(head));
|
||||
auto bytelen = _str::byte_len(s);
|
||||
auto numpart = _str::substr(s, 1u, bytelen - 1u);
|
||||
ret headstr + padstr + numpart;
|
||||
}
|
||||
}
|
||||
ret padstr + s;
|
||||
}
|
||||
|
||||
fn have_flag(vec[flag] flags, flag f) -> bool {
|
||||
for (flag candidate in flags) {
|
||||
if (candidate == f) {
|
||||
ret true;
|
||||
}
|
||||
}
|
||||
ret false;
|
||||
}
|
||||
}
|
||||
|
||||
// Local Variables:
|
||||
// mode: rust;
|
||||
// fill-column: 78;
|
||||
|
Loading…
x
Reference in New Issue
Block a user