Skip to content

Commit

Permalink
all: add r and R switches for repeating in string interpolation, …
Browse files Browse the repository at this point in the history
…`'${"abc":3r}'` == 'abcabcabc' (#20197)
  • Loading branch information
penguindark committed Dec 17, 2023
1 parent 51aaf3c commit ae16878
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 3 deletions.
14 changes: 14 additions & 0 deletions vlib/builtin/string_int_test.v
Expand Up @@ -350,3 +350,17 @@ fn test_interpolate_literal_limits() {
assert '10 ${u32(0o377777_77777)}' == '10 4294967295'
assert '11 ${i64(-2147483647)}' == '11 -2147483647'
}

fn test_string_repetition() {
a := 'pippo'
assert '${'pera':r}' == ''
assert '${'pera':R}' == ''
assert '${'pera':0r}' == ''
assert '${'pera':0R}' == ''
assert '${'pera':1r}' == 'pera'
assert '${'pera':1R}' == 'PERA'
assert '${'pera':2r}' == 'perapera'
assert '${'pera':2R}' == 'PERAPERA'
assert '${a:2r}' == 'pippopippo'
assert '${a:2R}' == 'PIPPOPIPPO'
}
24 changes: 24 additions & 0 deletions vlib/builtin/string_interpolation.v
Expand Up @@ -33,6 +33,7 @@ pub enum StrIntpType {
si_g64
si_s
si_p
si_r
si_vp
}

Expand All @@ -56,6 +57,7 @@ pub fn (x StrIntpType) str() string {
.si_e64 { 'f64' } // e64 format use f64 data
.si_s { 's' }
.si_p { 'p' }
.si_r { 'r' } // repeat string
.si_vp { 'vp' }
}
}
Expand All @@ -75,6 +77,7 @@ pub mut:
d_f32 f32
d_f64 f64
d_s string
d_r string
d_p voidptr
d_vp voidptr
}
Expand Down Expand Up @@ -224,6 +227,27 @@ fn (data &StrIntpData) process_str_intp_data(mut sb strings.Builder) {
return
}

if typ == .si_r {
if width > 0 {
mut s := ''
if upper_case {
s = data.d.d_s.to_upper()
} else {
s = data.d.d_s.clone()
}

for _ in 1 .. (1 + (if width > 0 {
width
} else {
0
})) {
sb.write_string(s)
}
s.free()
}
return
}

// signed int
if typ in [.si_i8, .si_i16, .si_i32, .si_i64] {
mut d := data.d.d_i64
Expand Down
6 changes: 3 additions & 3 deletions vlib/v/checker/str.v
Expand Up @@ -68,7 +68,7 @@ fn (mut c Checker) string_inter_lit(mut node ast.StringInterLiteral) ast.Type {
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`, `_`] {
`b`, `_`, `r`, `R`] {
c.error('unknown format specifier `${fmt:c}`', node.fmt_poss[i])
}
if fmt == `_` { // set default representation for type if none has been given
Expand Down Expand Up @@ -99,14 +99,14 @@ fn (mut c Checker) string_inter_lit(mut node ast.StringInterLiteral) ast.Type {
&& 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`])
|| (typ.is_string() && fmt !in [`s`, `S`, `r`, `R`])
|| (typ.idx() in [ast.i64_type_idx, ast.f64_type_idx] && fmt == `c`))
&& !(typ.is_ptr() && fmt in [`p`, `x`, `X`]) {
c.error('illegal format specifier `${fmt:c}` for type `${c.table.get_type_name(ftyp)}`',
node.fmt_poss[i])
}
if c.table.final_sym(typ).kind in [.array, .array_fixed, .struct_, .interface_, .none_, .map, .sum_type]
&& fmt in [`E`, `F`, `G`, `e`, `f`, `g`, `d`, `u`, `x`, `X`, `o`, `c`, `p`, `b`]
&& fmt in [`E`, `F`, `G`, `e`, `f`, `g`, `d`, `u`, `x`, `X`, `o`, `c`, `p`, `b`, `r`, `R`]
&& !(typ.is_ptr() && fmt in [`p`, `x`, `X`]) {
c.error('illegal format specifier `${fmt:c}` for type `${c.table.get_type_name(ftyp)}`',
node.fmt_poss[i])
Expand Down
1 change: 1 addition & 0 deletions vlib/v/gen/c/auto_str_methods.v
Expand Up @@ -1139,6 +1139,7 @@ fn data_str(x StrIntpType) string {
.si_e32 { 'd_f32' } // e32 format use f32 data
.si_e64 { 'd_f64' } // e64 format use f64 data
.si_s { 'd_s' }
.si_r { 'd_r' } // repeat string
.si_p { 'd_p' }
.si_vp { 'd_vp' }
}
Expand Down
2 changes: 2 additions & 0 deletions vlib/v/gen/c/str_intp.v
Expand Up @@ -76,6 +76,8 @@ fn (mut g Gen) str_format(node ast.StringInterLiteral, i int, fmts []u8) (u64, s
}
*/
fmt_type = .si_s
} else if fspec in [`r`, `R`] {
fmt_type = .si_r
} else if typ.is_float() {
if fspec in [`g`, `G`] {
match typ {
Expand Down
3 changes: 3 additions & 0 deletions vlib/v/gen/js/auto_str_methods.v
Expand Up @@ -125,6 +125,7 @@ pub enum StrIntpType {
si_g64
si_s
si_p
si_r
si_vp
}

Expand All @@ -148,6 +149,7 @@ pub fn type_to_str(x StrIntpType) string {
.si_e64 { return 'f64' } // e64 format use f64 data
.si_s { return 's' }
.si_p { return 'p' }
.si_r { return 'r' } // repeat string
.si_vp { return 'vp' }
}
}
Expand All @@ -172,6 +174,7 @@ pub fn data_str(x StrIntpType) string {
.si_e64 { return 'd_f64' } // e64 format use f64 data
.si_s { return 'd_s' }
.si_p { return 'd_p' }
.si_r { return 'd_r' } // repeat string
.si_vp { return 'd_vp' }
}
}
Expand Down

0 comments on commit ae16878

Please sign in to comment.