builtin: string interpolation: binary format support (#11421)
parent
fae0f8d821
commit
bd10a63839
|
@ -219,3 +219,38 @@ fn test_signed_cast() {
|
|||
assert '${u.f:G}' == '-INF'
|
||||
}
|
||||
}
|
||||
|
||||
fn test_binary() {
|
||||
i := i8(127)
|
||||
u := u8(127)
|
||||
assert '${i:08b}' == '01111111'
|
||||
assert '${u:08b}' == '01111111'
|
||||
assert '${i16(i):08b}' == '01111111'
|
||||
assert '${u16(u):08b}' == '01111111'
|
||||
assert '${int(i):08b}' == '01111111'
|
||||
assert '${u32(u):08b}' == '01111111'
|
||||
assert '${i64(i):08b}' == '01111111'
|
||||
assert '${u64(u):08b}' == '01111111'
|
||||
|
||||
n := i8(-1)
|
||||
assert '${u8(-1):08b}' == '11111111'
|
||||
assert '${u16(n):08b}' == '1111111111111111'
|
||||
assert '${u32(n):08b}' == '11111111111111111111111111111111'
|
||||
assert '${u64(n):08b}' == '1111111111111111111111111111111111111111111111111111111111111111'
|
||||
}
|
||||
|
||||
fn test_binary32() {
|
||||
i := int(0x7fff_ffff)
|
||||
u := u32(0x7fff_ffff)
|
||||
assert '${i:032b}' == '01111111111111111111111111111111'
|
||||
assert '${u:032b}' == '01111111111111111111111111111111'
|
||||
assert '${i64(i):032b}' == '01111111111111111111111111111111'
|
||||
assert '${u64(u):032b}' == '01111111111111111111111111111111'
|
||||
}
|
||||
|
||||
fn test_binary64() {
|
||||
i := i64(0x7fff_ffff_ffff_ffff)
|
||||
u := u64(0x7fff_ffff_ffff_ffff)
|
||||
assert '${i:064b}' == '0111111111111111111111111111111111111111111111111111111111111111'
|
||||
assert '${u:064b}' == '0111111111111111111111111111111111111111111111111111111111111111'
|
||||
}
|
||||
|
|
|
@ -252,6 +252,10 @@ fn (data StrIntpData) get_fmt_format(mut sb strings.Builder) {
|
|||
}
|
||||
strconv.format_dec_sb(abs64(d), bf, mut sb)
|
||||
} else {
|
||||
// binary, we use 3 for binary
|
||||
if base == 3 {
|
||||
base = 2
|
||||
}
|
||||
mut hx := strconv.format_int(d, base)
|
||||
if upper_case {
|
||||
tmp := hx
|
||||
|
@ -287,6 +291,10 @@ fn (data StrIntpData) get_fmt_format(mut sb strings.Builder) {
|
|||
}
|
||||
strconv.format_dec_sb(d, bf, mut sb)
|
||||
} else {
|
||||
// binary, we use 3 for binary
|
||||
if base == 3 {
|
||||
base = 2
|
||||
}
|
||||
mut hx := strconv.format_uint(d, base)
|
||||
if upper_case {
|
||||
tmp := hx
|
||||
|
|
|
@ -451,8 +451,7 @@ pub fn (mut c Checker) string_inter_lit(mut node ast.StringInterLiteral) ast.Typ
|
|||
mut fmt := node.fmts[i]
|
||||
// analyze and validate format specifier
|
||||
if fmt !in [`E`, `F`, `G`, `e`, `f`, `g`, `d`, `u`, `x`, `X`, `o`, `c`, `s`, `S`, `p`,
|
||||
`_`,
|
||||
] {
|
||||
`b`, `_`] {
|
||||
c.error('unknown format specifier `${fmt:c}`', node.fmt_poss[i])
|
||||
}
|
||||
if fmt == `_` { // set default representation for type if none has been given
|
||||
|
@ -473,9 +472,10 @@ pub fn (mut c Checker) string_inter_lit(mut node ast.StringInterLiteral) ast.Typ
|
|||
if node.pluss[i] && !typ.is_number() {
|
||||
c.error('plus prefix only allowed for numbers', node.fmt_poss[i])
|
||||
}
|
||||
if (typ.is_unsigned() && fmt !in [`u`, `x`, `X`, `o`, `c`])
|
||||
|| (typ.is_signed() && fmt !in [`d`, `x`, `X`, `o`, `c`])
|
||||
|| (typ.is_int_literal() && fmt !in [`d`, `c`, `x`, `X`, `o`, `u`, `x`, `X`, `o`])
|
||||
if (typ.is_unsigned() && fmt !in [`u`, `x`, `X`, `o`, `c`, `b`])
|
||||
|| (typ.is_signed() && fmt !in [`d`, `x`, `X`, `o`, `c`, `b`])
|
||||
|| (typ.is_int_literal()
|
||||
&& fmt !in [`d`, `c`, `x`, `X`, `o`, `u`, `x`, `X`, `o`, `b`])
|
||||
|| (typ.is_float() && fmt !in [`E`, `F`, `G`, `e`, `f`, `g`])
|
||||
|| (typ.is_pointer() && fmt !in [`p`, `x`, `X`])
|
||||
|| (typ.is_string() && fmt !in [`s`, `S`])
|
||||
|
|
|
@ -76,6 +76,10 @@ fn (mut g Gen) str_format(node ast.StringInterLiteral, i int) (u64, string) {
|
|||
if fspec == `o` {
|
||||
base = 8 - 2 // our base start from 2
|
||||
}
|
||||
// binary format
|
||||
if fspec == `b` {
|
||||
base = 1 // our base start from 2 we use 1 for binary
|
||||
}
|
||||
if fspec == `c` {
|
||||
fmt_type = .si_c
|
||||
} else {
|
||||
|
|
Loading…
Reference in New Issue