Convert core::extfmt to camel case
This commit is contained in:
parent
ec225166cd
commit
2c6c963f61
2 changed files with 339 additions and 146 deletions
|
@ -1,5 +1,4 @@
|
|||
#[doc(hidden)];
|
||||
#[allow(non_camel_case_types)];
|
||||
|
||||
/*
|
||||
Syntax Extension: fmt
|
||||
|
@ -43,53 +42,53 @@ use option::{Some, None};
|
|||
|
||||
// Functions used by the fmt extension at compile time
|
||||
mod ct {
|
||||
enum signedness { signed, unsigned, }
|
||||
enum caseness { case_upper, case_lower, }
|
||||
enum ty {
|
||||
ty_bool,
|
||||
ty_str,
|
||||
ty_char,
|
||||
ty_int(signedness),
|
||||
ty_bits,
|
||||
ty_hex(caseness),
|
||||
ty_octal,
|
||||
ty_float,
|
||||
ty_poly,
|
||||
enum Signedness { Signed, Unsigned, }
|
||||
enum Caseness { CaseUpper, CaseLower, }
|
||||
enum Ty {
|
||||
TyBool,
|
||||
TyStr,
|
||||
TyChar,
|
||||
TyInt(Signedness),
|
||||
TyBits,
|
||||
TyHex(Caseness),
|
||||
TyOctal,
|
||||
TyFloat,
|
||||
TyPoly,
|
||||
}
|
||||
enum flag {
|
||||
flag_left_justify,
|
||||
flag_left_zero_pad,
|
||||
flag_space_for_sign,
|
||||
flag_sign_always,
|
||||
flag_alternate,
|
||||
enum Flag {
|
||||
FlagLeftJustify,
|
||||
FlagLeftZeroPad,
|
||||
FlagSpaceForSign,
|
||||
FlagSignAlways,
|
||||
FlagAlternate,
|
||||
}
|
||||
enum count {
|
||||
count_is(int),
|
||||
count_is_param(int),
|
||||
count_is_next_param,
|
||||
count_implied,
|
||||
enum Count {
|
||||
CountIs(int),
|
||||
CountIsParam(int),
|
||||
CountIsNextParam,
|
||||
CountImplied,
|
||||
}
|
||||
|
||||
// A formatted conversion from an expression to a string
|
||||
type conv =
|
||||
type Conv =
|
||||
{param: Option<int>,
|
||||
flags: ~[flag],
|
||||
width: count,
|
||||
precision: count,
|
||||
ty: ty};
|
||||
flags: ~[Flag],
|
||||
width: Count,
|
||||
precision: Count,
|
||||
ty: Ty};
|
||||
|
||||
|
||||
// A fragment of the output sequence
|
||||
enum piece { piece_string(~str), piece_conv(conv), }
|
||||
type error_fn = fn@(~str) -> ! ;
|
||||
enum Piece { PieceString(~str), PieceConv(Conv), }
|
||||
type ErrorFn = fn@(~str) -> ! ;
|
||||
|
||||
fn parse_fmt_string(s: ~str, error: error_fn) -> ~[piece] {
|
||||
let mut pieces: ~[piece] = ~[];
|
||||
fn parse_fmt_string(s: ~str, error: ErrorFn) -> ~[Piece] {
|
||||
let mut pieces: ~[Piece] = ~[];
|
||||
let lim = str::len(s);
|
||||
let mut buf = ~"";
|
||||
fn flush_buf(+buf: ~str, &pieces: ~[piece]) -> ~str {
|
||||
fn flush_buf(+buf: ~str, &pieces: ~[Piece]) -> ~str {
|
||||
if str::len(buf) > 0 {
|
||||
let piece = piece_string(move buf);
|
||||
let piece = PieceString(move buf);
|
||||
vec::push(pieces, move piece);
|
||||
}
|
||||
return ~"";
|
||||
|
@ -140,15 +139,15 @@ mod ct {
|
|||
None
|
||||
}
|
||||
}
|
||||
fn parse_conversion(s: ~str, i: uint, lim: uint, error: error_fn) ->
|
||||
{piece: piece, next: uint} {
|
||||
fn parse_conversion(s: ~str, i: uint, lim: uint, error: ErrorFn) ->
|
||||
{piece: Piece, next: uint} {
|
||||
let parm = parse_parameter(s, i, lim);
|
||||
let flags = parse_flags(s, parm.next, lim);
|
||||
let width = parse_count(s, flags.next, lim);
|
||||
let prec = parse_precision(s, width.next, lim);
|
||||
let ty = parse_type(s, prec.next, lim, error);
|
||||
return {piece:
|
||||
piece_conv({param: parm.param,
|
||||
PieceConv({param: parm.param,
|
||||
flags: copy flags.flags,
|
||||
width: width.count,
|
||||
precision: prec.count,
|
||||
|
@ -171,58 +170,58 @@ mod ct {
|
|||
};
|
||||
}
|
||||
fn parse_flags(s: ~str, i: uint, lim: uint) ->
|
||||
{flags: ~[flag], next: uint} {
|
||||
let noflags: ~[flag] = ~[];
|
||||
{flags: ~[Flag], next: uint} {
|
||||
let noflags: ~[Flag] = ~[];
|
||||
if i >= lim { return {flags: move noflags, next: i}; }
|
||||
|
||||
fn more_(f: flag, s: ~str, i: uint, lim: uint) ->
|
||||
{flags: ~[flag], next: uint} {
|
||||
fn more_(f: Flag, s: ~str, i: uint, lim: uint) ->
|
||||
{flags: ~[Flag], next: uint} {
|
||||
let next = parse_flags(s, i + 1u, lim);
|
||||
let rest = copy next.flags;
|
||||
let j = next.next;
|
||||
let curr: ~[flag] = ~[f];
|
||||
let curr: ~[Flag] = ~[f];
|
||||
return {flags: vec::append(move curr, rest), next: j};
|
||||
}
|
||||
let more = |x, copy s| more_(x, copy s, i, lim);
|
||||
let f = s[i];
|
||||
return if f == '-' as u8 {
|
||||
more(flag_left_justify)
|
||||
more(FlagLeftJustify)
|
||||
} else if f == '0' as u8 {
|
||||
more(flag_left_zero_pad)
|
||||
more(FlagLeftZeroPad)
|
||||
} else if f == ' ' as u8 {
|
||||
more(flag_space_for_sign)
|
||||
more(FlagSpaceForSign)
|
||||
} else if f == '+' as u8 {
|
||||
more(flag_sign_always)
|
||||
more(FlagSignAlways)
|
||||
} else if f == '#' as u8 {
|
||||
more(flag_alternate)
|
||||
more(FlagAlternate)
|
||||
} else { {flags: move noflags, next: i} };
|
||||
}
|
||||
fn parse_count(s: ~str, i: uint, lim: uint)
|
||||
-> {count: count, next: uint} {
|
||||
-> {count: Count, next: uint} {
|
||||
return if i >= lim {
|
||||
{count: count_implied, next: i}
|
||||
{count: CountImplied, next: i}
|
||||
} else if s[i] == '*' as u8 {
|
||||
let param = parse_parameter(s, i + 1u, lim);
|
||||
let j = param.next;
|
||||
match param.param {
|
||||
None => {count: count_is_next_param, next: j},
|
||||
Some(n) => {count: count_is_param(n), next: j}
|
||||
None => {count: CountIsNextParam, next: j},
|
||||
Some(n) => {count: CountIsParam(n), next: j}
|
||||
}
|
||||
} else {
|
||||
let num = peek_num(s, i, lim);
|
||||
match num {
|
||||
None => {count: count_implied, next: i},
|
||||
None => {count: CountImplied, next: i},
|
||||
Some(num) => {
|
||||
count: count_is(num.num as int),
|
||||
count: CountIs(num.num as int),
|
||||
next: num.next
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
fn parse_precision(s: ~str, i: uint, lim: uint) ->
|
||||
{count: count, next: uint} {
|
||||
{count: Count, next: uint} {
|
||||
return if i >= lim {
|
||||
{count: count_implied, next: i}
|
||||
{count: CountImplied, next: i}
|
||||
} else if s[i] == '.' as u8 {
|
||||
let count = parse_count(s, i + 1u, lim);
|
||||
|
||||
|
@ -230,40 +229,40 @@ mod ct {
|
|||
// If there were no digits specified, i.e. the precision
|
||||
// was ".", then the precision is 0
|
||||
match count.count {
|
||||
count_implied => {count: count_is(0), next: count.next},
|
||||
CountImplied => {count: CountIs(0), next: count.next},
|
||||
_ => count
|
||||
}
|
||||
} else { {count: count_implied, next: i} };
|
||||
} else { {count: CountImplied, next: i} };
|
||||
}
|
||||
fn parse_type(s: ~str, i: uint, lim: uint, error: error_fn) ->
|
||||
{ty: ty, next: uint} {
|
||||
fn parse_type(s: ~str, i: uint, lim: uint, error: ErrorFn) ->
|
||||
{ty: Ty, next: uint} {
|
||||
if i >= lim { error(~"missing type in conversion"); }
|
||||
let tstr = str::slice(s, i, i+1u);
|
||||
// FIXME (#2249): Do we really want two signed types here?
|
||||
// How important is it to be printf compatible?
|
||||
let t =
|
||||
if tstr == ~"b" {
|
||||
ty_bool
|
||||
TyBool
|
||||
} else if tstr == ~"s" {
|
||||
ty_str
|
||||
TyStr
|
||||
} else if tstr == ~"c" {
|
||||
ty_char
|
||||
TyChar
|
||||
} else if tstr == ~"d" || tstr == ~"i" {
|
||||
ty_int(signed)
|
||||
TyInt(Signed)
|
||||
} else if tstr == ~"u" {
|
||||
ty_int(unsigned)
|
||||
TyInt(Unsigned)
|
||||
} else if tstr == ~"x" {
|
||||
ty_hex(case_lower)
|
||||
TyHex(CaseLower)
|
||||
} else if tstr == ~"X" {
|
||||
ty_hex(case_upper)
|
||||
TyHex(CaseUpper)
|
||||
} else if tstr == ~"t" {
|
||||
ty_bits
|
||||
TyBits
|
||||
} else if tstr == ~"o" {
|
||||
ty_octal
|
||||
TyOctal
|
||||
} else if tstr == ~"f" {
|
||||
ty_float
|
||||
TyFloat
|
||||
} else if tstr == ~"?" {
|
||||
ty_poly
|
||||
TyPoly
|
||||
} else { error(~"unknown type in conversion: " + tstr) };
|
||||
return {ty: t, next: i + 1u};
|
||||
}
|
||||
|
@ -274,6 +273,199 @@ 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 0this way, I think.
|
||||
#[cfg(stage1)]
|
||||
#[cfg(stage2)]
|
||||
#[cfg(stage3)]
|
||||
mod rt {
|
||||
const flag_none : u32 = 0u32;
|
||||
const flag_left_justify : u32 = 0b00000000000000000000000000000001u32;
|
||||
const flag_left_zero_pad : u32 = 0b00000000000000000000000000000010u32;
|
||||
const flag_space_for_sign : u32 = 0b00000000000000000000000000000100u32;
|
||||
const flag_sign_always : u32 = 0b00000000000000000000000000001000u32;
|
||||
const flag_alternate : u32 = 0b00000000000000000000000000010000u32;
|
||||
|
||||
enum Count { CountIs(int), CountImplied, }
|
||||
enum Ty { TyDefault, TyBits, TyHexUpper, TyHexLower, TyOctal, }
|
||||
|
||||
type Conv = {flags: u32, width: Count, precision: Count, ty: Ty};
|
||||
|
||||
pure fn conv_int(cv: Conv, i: int) -> ~str {
|
||||
let radix = 10u;
|
||||
let prec = get_int_precision(cv);
|
||||
let mut s : ~str = int_to_str_prec(i, radix, prec);
|
||||
if 0 <= i {
|
||||
if have_flag(cv.flags, flag_sign_always) {
|
||||
unchecked { str::unshift_char(s, '+') };
|
||||
} else if have_flag(cv.flags, flag_space_for_sign) {
|
||||
unchecked { str::unshift_char(s, ' ') };
|
||||
}
|
||||
}
|
||||
return unchecked { pad(cv, s, PadSigned) };
|
||||
}
|
||||
pure fn conv_uint(cv: Conv, u: uint) -> ~str {
|
||||
let prec = get_int_precision(cv);
|
||||
let mut rs =
|
||||
match cv.ty {
|
||||
TyDefault => uint_to_str_prec(u, 10u, prec),
|
||||
TyHexLower => uint_to_str_prec(u, 16u, prec),
|
||||
TyHexUpper => str::to_upper(uint_to_str_prec(u, 16u, prec)),
|
||||
TyBits => uint_to_str_prec(u, 2u, prec),
|
||||
TyOctal => uint_to_str_prec(u, 8u, prec)
|
||||
};
|
||||
return unchecked { pad(cv, rs, PadUnsigned) };
|
||||
}
|
||||
pure fn conv_bool(cv: Conv, b: bool) -> ~str {
|
||||
let s = if b { ~"true" } else { ~"false" };
|
||||
// run the boolean conversion through the string conversion logic,
|
||||
// giving it the same rules for precision, etc.
|
||||
return conv_str(cv, s);
|
||||
}
|
||||
pure fn conv_char(cv: Conv, c: char) -> ~str {
|
||||
let mut s = str::from_char(c);
|
||||
return unchecked { pad(cv, s, PadNozero) };
|
||||
}
|
||||
pure fn conv_str(cv: Conv, s: &str) -> ~str {
|
||||
// For strings, precision is the maximum characters
|
||||
// displayed
|
||||
let mut unpadded = match cv.precision {
|
||||
CountImplied => s.to_unique(),
|
||||
CountIs(max) => if max as uint < str::char_len(s) {
|
||||
str::substr(s, 0u, max as uint)
|
||||
} else {
|
||||
s.to_unique()
|
||||
}
|
||||
};
|
||||
return unchecked { pad(cv, unpadded, PadNozero) };
|
||||
}
|
||||
pure fn conv_float(cv: Conv, f: float) -> ~str {
|
||||
let (to_str, digits) = match cv.precision {
|
||||
CountIs(c) => (float::to_str_exact, c as uint),
|
||||
CountImplied => (float::to_str, 6u)
|
||||
};
|
||||
let mut s = unchecked { to_str(f, digits) };
|
||||
if 0.0 <= f {
|
||||
if have_flag(cv.flags, flag_sign_always) {
|
||||
s = ~"+" + s;
|
||||
} else if have_flag(cv.flags, flag_space_for_sign) {
|
||||
s = ~" " + s;
|
||||
}
|
||||
}
|
||||
return unchecked { pad(cv, s, PadFloat) };
|
||||
}
|
||||
pure fn conv_poly<T>(cv: Conv, v: T) -> ~str {
|
||||
let s = sys::log_str(v);
|
||||
return conv_str(cv, s);
|
||||
}
|
||||
|
||||
// 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.
|
||||
pure fn int_to_str_prec(num: int, radix: uint, prec: uint) -> ~str {
|
||||
return if num < 0 {
|
||||
~"-" + uint_to_str_prec(-num as uint, radix, prec)
|
||||
} else { 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.
|
||||
pure fn uint_to_str_prec(num: uint, radix: uint, prec: uint) -> ~str {
|
||||
return if prec == 0u && num == 0u {
|
||||
~""
|
||||
} else {
|
||||
let s = uint::to_str(num, radix);
|
||||
let len = str::char_len(s);
|
||||
if len < prec {
|
||||
let diff = prec - len;
|
||||
let pad = str::from_chars(vec::from_elem(diff, '0'));
|
||||
pad + s
|
||||
} else { move s }
|
||||
};
|
||||
}
|
||||
pure fn get_int_precision(cv: Conv) -> uint {
|
||||
return match cv.precision {
|
||||
CountIs(c) => c as uint,
|
||||
CountImplied => 1u
|
||||
};
|
||||
}
|
||||
|
||||
enum PadMode { PadSigned, PadUnsigned, PadNozero, PadFloat }
|
||||
|
||||
impl PadMode: Eq {
|
||||
pure fn eq(&&other: PadMode) -> bool {
|
||||
match (self, other) {
|
||||
(PadSigned, PadSigned) => true,
|
||||
(PadUnsigned, PadUnsigned) => true,
|
||||
(PadNozero, PadNozero) => true,
|
||||
(PadFloat, PadFloat) => true,
|
||||
(PadSigned, _) => false,
|
||||
(PadUnsigned, _) => false,
|
||||
(PadNozero, _) => false,
|
||||
(PadFloat, _) => false
|
||||
}
|
||||
}
|
||||
pure fn ne(&&other: PadMode) -> bool { !self.eq(other) }
|
||||
}
|
||||
|
||||
fn pad(cv: Conv, &s: ~str, mode: PadMode) -> ~str {
|
||||
let uwidth : uint = match cv.width {
|
||||
CountImplied => return copy s,
|
||||
CountIs(width) => {
|
||||
// FIXME: width should probably be uint (see Issue #1996)
|
||||
width as uint
|
||||
}
|
||||
};
|
||||
let strlen = str::char_len(s);
|
||||
if uwidth <= strlen { return copy s; }
|
||||
let mut padchar = ' ';
|
||||
let diff = uwidth - strlen;
|
||||
if have_flag(cv.flags, flag_left_justify) {
|
||||
let padstr = str::from_chars(vec::from_elem(diff, padchar));
|
||||
return s + padstr;
|
||||
}
|
||||
let {might_zero_pad, signed} = match mode {
|
||||
PadNozero => {might_zero_pad:false, signed:false},
|
||||
PadSigned => {might_zero_pad:true, signed:true },
|
||||
PadFloat => {might_zero_pad:true, signed:true},
|
||||
PadUnsigned => {might_zero_pad:true, signed:false}
|
||||
};
|
||||
pure fn have_precision(cv: Conv) -> bool {
|
||||
return match cv.precision { CountImplied => false, _ => true };
|
||||
}
|
||||
let zero_padding = {
|
||||
if might_zero_pad && have_flag(cv.flags, flag_left_zero_pad) &&
|
||||
(!have_precision(cv) || mode == PadFloat) {
|
||||
padchar = '0';
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
};
|
||||
let padstr = str::from_chars(vec::from_elem(diff, padchar));
|
||||
// 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::len(s) > 0u {
|
||||
let head = str::shift_char(s);
|
||||
if head == '+' || head == '-' || head == ' ' {
|
||||
let headstr = str::from_chars(vec::from_elem(1u, head));
|
||||
return headstr + padstr + s;
|
||||
}
|
||||
else {
|
||||
str::unshift_char(s, head);
|
||||
}
|
||||
}
|
||||
return padstr + s;
|
||||
}
|
||||
pure fn have_flag(flags: u32, f: u32) -> bool {
|
||||
flags & f != 0
|
||||
}
|
||||
}
|
||||
|
||||
// XXX remove after snappies
|
||||
#[cfg(stage0)]
|
||||
#[allow(non_camel_case_types)]
|
||||
mod rt {
|
||||
const flag_none : u32 = 0u32;
|
||||
const flag_left_justify : u32 = 0b00000000000000000000000000000001u32;
|
||||
|
@ -461,6 +653,7 @@ mod rt {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
#[test]
|
||||
|
|
|
@ -35,7 +35,7 @@ fn expand_syntax_ext(cx: ext_ctxt, sp: span, arg: ast::mac_arg,
|
|||
// expressions. Also: Cleanup the naming of these functions.
|
||||
// NOTE: Moved many of the common ones to build.rs --kevina
|
||||
fn pieces_to_expr(cx: ext_ctxt, sp: span,
|
||||
pieces: ~[piece], args: ~[@ast::expr])
|
||||
pieces: ~[Piece], args: ~[@ast::expr])
|
||||
-> @ast::expr {
|
||||
fn make_path_vec(_cx: ext_ctxt, ident: @~str) -> ~[ast::ident] {
|
||||
let intr = _cx.parse_sess().interner;
|
||||
|
@ -49,46 +49,46 @@ fn pieces_to_expr(cx: ext_ctxt, sp: span,
|
|||
// Produces an AST expression that represents a RT::conv record,
|
||||
// which tells the RT::conv* functions how to perform the conversion
|
||||
|
||||
fn make_rt_conv_expr(cx: ext_ctxt, sp: span, cnv: conv) -> @ast::expr {
|
||||
fn make_flags(cx: ext_ctxt, sp: span, flags: ~[flag]) -> @ast::expr {
|
||||
fn make_rt_conv_expr(cx: ext_ctxt, sp: span, cnv: Conv) -> @ast::expr {
|
||||
fn make_flags(cx: ext_ctxt, sp: span, flags: ~[Flag]) -> @ast::expr {
|
||||
let mut tmp_expr = make_rt_path_expr(cx, sp, @~"flag_none");
|
||||
for flags.each |f| {
|
||||
let fstr = match f {
|
||||
flag_left_justify => ~"flag_left_justify",
|
||||
flag_left_zero_pad => ~"flag_left_zero_pad",
|
||||
flag_space_for_sign => ~"flag_space_for_sign",
|
||||
flag_sign_always => ~"flag_sign_always",
|
||||
flag_alternate => ~"flag_alternate"
|
||||
FlagLeftJustify => ~"flag_left_justify",
|
||||
FlagLeftZeroPad => ~"flag_left_zero_pad",
|
||||
FlagSpaceForSign => ~"flag_space_for_sign",
|
||||
FlagSignAlways => ~"flag_sign_always",
|
||||
FlagAlternate => ~"flag_alternate"
|
||||
};
|
||||
tmp_expr = mk_binary(cx, sp, ast::bitor, tmp_expr,
|
||||
make_rt_path_expr(cx, sp, @fstr));
|
||||
}
|
||||
return tmp_expr;
|
||||
}
|
||||
fn make_count(cx: ext_ctxt, sp: span, cnt: count) -> @ast::expr {
|
||||
fn make_count(cx: ext_ctxt, sp: span, cnt: Count) -> @ast::expr {
|
||||
match cnt {
|
||||
count_implied => {
|
||||
return make_rt_path_expr(cx, sp, @~"count_implied");
|
||||
CountImplied => {
|
||||
return make_rt_path_expr(cx, sp, @~"CountImplied");
|
||||
}
|
||||
count_is(c) => {
|
||||
CountIs(c) => {
|
||||
let count_lit = mk_int(cx, sp, c);
|
||||
let count_is_path = make_path_vec(cx, @~"count_is");
|
||||
let count_is_path = make_path_vec(cx, @~"CountIs");
|
||||
let count_is_args = ~[count_lit];
|
||||
return mk_call(cx, sp, count_is_path, count_is_args);
|
||||
}
|
||||
_ => cx.span_unimpl(sp, ~"unimplemented #fmt conversion")
|
||||
}
|
||||
}
|
||||
fn make_ty(cx: ext_ctxt, sp: span, t: ty) -> @ast::expr {
|
||||
fn make_ty(cx: ext_ctxt, sp: span, t: Ty) -> @ast::expr {
|
||||
let mut rt_type;
|
||||
match t {
|
||||
ty_hex(c) => match c {
|
||||
case_upper => rt_type = ~"ty_hex_upper",
|
||||
case_lower => rt_type = ~"ty_hex_lower"
|
||||
TyHex(c) => match c {
|
||||
CaseUpper => rt_type = ~"TyHexUpper",
|
||||
CaseLower => rt_type = ~"TyHexLower"
|
||||
},
|
||||
ty_bits => rt_type = ~"ty_bits",
|
||||
ty_octal => rt_type = ~"ty_octal",
|
||||
_ => rt_type = ~"ty_default"
|
||||
TyBits => rt_type = ~"TyBits",
|
||||
TyOctal => rt_type = ~"TyOctal",
|
||||
_ => rt_type = ~"TyDefault"
|
||||
}
|
||||
return make_rt_path_expr(cx, sp, @rt_type);
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ fn pieces_to_expr(cx: ext_ctxt, sp: span,
|
|||
return make_conv_rec(cx, sp, rt_conv_flags, rt_conv_width,
|
||||
rt_conv_precision, rt_conv_ty);
|
||||
}
|
||||
fn make_conv_call(cx: ext_ctxt, sp: span, conv_type: ~str, cnv: conv,
|
||||
fn make_conv_call(cx: ext_ctxt, sp: span, conv_type: ~str, cnv: Conv,
|
||||
arg: @ast::expr) -> @ast::expr {
|
||||
let fname = ~"conv_" + conv_type;
|
||||
let path = make_path_vec(cx, @fname);
|
||||
|
@ -119,17 +119,17 @@ fn pieces_to_expr(cx: ext_ctxt, sp: span,
|
|||
return mk_call(cx, arg.span, path, args);
|
||||
}
|
||||
|
||||
fn make_new_conv(cx: ext_ctxt, sp: span, cnv: conv, arg: @ast::expr) ->
|
||||
fn make_new_conv(cx: ext_ctxt, sp: span, cnv: Conv, arg: @ast::expr) ->
|
||||
@ast::expr {
|
||||
// FIXME: Move validation code into core::extfmt (Issue #2249)
|
||||
|
||||
fn is_signed_type(cnv: conv) -> bool {
|
||||
fn is_signed_type(cnv: Conv) -> bool {
|
||||
match cnv.ty {
|
||||
ty_int(s) => match s {
|
||||
signed => return true,
|
||||
unsigned => return false
|
||||
TyInt(s) => match s {
|
||||
Signed => return true,
|
||||
Unsigned => return false
|
||||
},
|
||||
ty_float => return true,
|
||||
TyFloat => return true,
|
||||
_ => return false
|
||||
}
|
||||
}
|
||||
|
@ -140,102 +140,102 @@ fn pieces_to_expr(cx: ext_ctxt, sp: span,
|
|||
}
|
||||
for cnv.flags.each |f| {
|
||||
match f {
|
||||
flag_left_justify => (),
|
||||
flag_sign_always => {
|
||||
FlagLeftJustify => (),
|
||||
FlagSignAlways => {
|
||||
if !is_signed_type(cnv) {
|
||||
cx.span_fatal(sp,
|
||||
~"+ flag only valid in " +
|
||||
~"signed #fmt conversion");
|
||||
}
|
||||
}
|
||||
flag_space_for_sign => {
|
||||
FlagSpaceForSign => {
|
||||
if !is_signed_type(cnv) {
|
||||
cx.span_fatal(sp,
|
||||
~"space flag only valid in " +
|
||||
~"signed #fmt conversions");
|
||||
}
|
||||
}
|
||||
flag_left_zero_pad => (),
|
||||
FlagLeftZeroPad => (),
|
||||
_ => cx.span_unimpl(sp, unsupported)
|
||||
}
|
||||
}
|
||||
match cnv.width {
|
||||
count_implied => (),
|
||||
count_is(_) => (),
|
||||
CountImplied => (),
|
||||
CountIs(_) => (),
|
||||
_ => cx.span_unimpl(sp, unsupported)
|
||||
}
|
||||
match cnv.precision {
|
||||
count_implied => (),
|
||||
count_is(_) => (),
|
||||
CountImplied => (),
|
||||
CountIs(_) => (),
|
||||
_ => cx.span_unimpl(sp, unsupported)
|
||||
}
|
||||
match cnv.ty {
|
||||
ty_str => return make_conv_call(cx, arg.span, ~"str", cnv, arg),
|
||||
ty_int(sign) => match sign {
|
||||
signed => return make_conv_call(cx, arg.span, ~"int", cnv, arg),
|
||||
unsigned => {
|
||||
TyStr => return make_conv_call(cx, arg.span, ~"str", cnv, arg),
|
||||
TyInt(sign) => match sign {
|
||||
Signed => return make_conv_call(cx, arg.span, ~"int", cnv, arg),
|
||||
Unsigned => {
|
||||
return make_conv_call(cx, arg.span, ~"uint", cnv, arg)
|
||||
}
|
||||
},
|
||||
ty_bool => return make_conv_call(cx, arg.span, ~"bool", cnv, arg),
|
||||
ty_char => return make_conv_call(cx, arg.span, ~"char", cnv, arg),
|
||||
ty_hex(_) => {
|
||||
TyBool => return make_conv_call(cx, arg.span, ~"bool", cnv, arg),
|
||||
TyChar => return make_conv_call(cx, arg.span, ~"char", cnv, arg),
|
||||
TyHex(_) => {
|
||||
return make_conv_call(cx, arg.span, ~"uint", cnv, arg);
|
||||
}
|
||||
ty_bits => return make_conv_call(cx, arg.span, ~"uint", cnv, arg),
|
||||
ty_octal => return make_conv_call(cx, arg.span, ~"uint", cnv, arg),
|
||||
ty_float => {
|
||||
TyBits => return make_conv_call(cx, arg.span, ~"uint", cnv, arg),
|
||||
TyOctal => return make_conv_call(cx, arg.span, ~"uint", cnv, arg),
|
||||
TyFloat => {
|
||||
return make_conv_call(cx, arg.span, ~"float", cnv, arg);
|
||||
}
|
||||
ty_poly => return make_conv_call(cx, arg.span, ~"poly", cnv, arg)
|
||||
TyPoly => return make_conv_call(cx, arg.span, ~"poly", cnv, arg)
|
||||
}
|
||||
}
|
||||
fn log_conv(c: conv) {
|
||||
fn log_conv(c: Conv) {
|
||||
match c.param {
|
||||
Some(p) => { log(debug, ~"param: " + int::to_str(p, 10u)); }
|
||||
_ => debug!("param: none")
|
||||
}
|
||||
for c.flags.each |f| {
|
||||
match f {
|
||||
flag_left_justify => debug!("flag: left justify"),
|
||||
flag_left_zero_pad => debug!("flag: left zero pad"),
|
||||
flag_space_for_sign => debug!("flag: left space pad"),
|
||||
flag_sign_always => debug!("flag: sign always"),
|
||||
flag_alternate => debug!("flag: alternate")
|
||||
FlagLeftJustify => debug!("flag: left justify"),
|
||||
FlagLeftZeroPad => debug!("flag: left zero pad"),
|
||||
FlagSpaceForSign => debug!("flag: left space pad"),
|
||||
FlagSignAlways => debug!("flag: sign always"),
|
||||
FlagAlternate => debug!("flag: alternate")
|
||||
}
|
||||
}
|
||||
match c.width {
|
||||
count_is(i) => log(
|
||||
CountIs(i) => log(
|
||||
debug, ~"width: count is " + int::to_str(i, 10u)),
|
||||
count_is_param(i) => log(
|
||||
CountIsParam(i) => log(
|
||||
debug, ~"width: count is param " + int::to_str(i, 10u)),
|
||||
count_is_next_param => debug!("width: count is next param"),
|
||||
count_implied => debug!("width: count is implied")
|
||||
CountIsNextParam => debug!("width: count is next param"),
|
||||
CountImplied => debug!("width: count is implied")
|
||||
}
|
||||
match c.precision {
|
||||
count_is(i) => log(
|
||||
CountIs(i) => log(
|
||||
debug, ~"prec: count is " + int::to_str(i, 10u)),
|
||||
count_is_param(i) => log(
|
||||
CountIsParam(i) => log(
|
||||
debug, ~"prec: count is param " + int::to_str(i, 10u)),
|
||||
count_is_next_param => debug!("prec: count is next param"),
|
||||
count_implied => debug!("prec: count is implied")
|
||||
CountIsNextParam => debug!("prec: count is next param"),
|
||||
CountImplied => debug!("prec: count is implied")
|
||||
}
|
||||
match c.ty {
|
||||
ty_bool => debug!("type: bool"),
|
||||
ty_str => debug!("type: str"),
|
||||
ty_char => debug!("type: char"),
|
||||
ty_int(s) => match s {
|
||||
signed => debug!("type: signed"),
|
||||
unsigned => debug!("type: unsigned")
|
||||
TyBool => debug!("type: bool"),
|
||||
TyStr => debug!("type: str"),
|
||||
TyChar => debug!("type: char"),
|
||||
TyInt(s) => match s {
|
||||
Signed => debug!("type: signed"),
|
||||
Unsigned => debug!("type: unsigned")
|
||||
},
|
||||
ty_bits => debug!("type: bits"),
|
||||
ty_hex(cs) => match cs {
|
||||
case_upper => debug!("type: uhex"),
|
||||
case_lower => debug!("type: lhex"),
|
||||
TyBits => debug!("type: bits"),
|
||||
TyHex(cs) => match cs {
|
||||
CaseUpper => debug!("type: uhex"),
|
||||
CaseLower => debug!("type: lhex"),
|
||||
},
|
||||
ty_octal => debug!("type: octal"),
|
||||
ty_float => debug!("type: float"),
|
||||
ty_poly => debug!("type: poly")
|
||||
TyOctal => debug!("type: octal"),
|
||||
TyFloat => debug!("type: float"),
|
||||
TyPoly => debug!("type: poly")
|
||||
}
|
||||
}
|
||||
let fmt_sp = args[0].span;
|
||||
|
@ -244,10 +244,10 @@ fn pieces_to_expr(cx: ext_ctxt, sp: span,
|
|||
let nargs = args.len();
|
||||
for pieces.each |pc| {
|
||||
match pc {
|
||||
piece_string(s) => {
|
||||
PieceString(s) => {
|
||||
vec::push(piece_exprs, mk_uniq_str(cx, fmt_sp, s))
|
||||
}
|
||||
piece_conv(conv) => {
|
||||
PieceConv(conv) => {
|
||||
n += 1u;
|
||||
if n >= nargs {
|
||||
cx.span_fatal(sp,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue