builtin: string interpolation: binary format support (#11421)

pull/11422/head
penguindark 2021-09-06 23:12:54 +02:00 committed by GitHub
parent fae0f8d821
commit bd10a63839
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 52 additions and 5 deletions

View File

@ -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'
}

View File

@ -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

View File

@ -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`])

View File

@ -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 {