diff --git a/vlib/v/scanner/scanner.v b/vlib/v/scanner/scanner.v index 726ab051b0..daaf469eaa 100644 --- a/vlib/v/scanner/scanner.v +++ b/vlib/v/scanner/scanner.v @@ -54,6 +54,7 @@ pub mut: all_tokens []token.Token // *only* used in comments_mode: .toplevel_comments, contains all tokens tidx int eofs int + inter_cbr_count int pref &pref.Preferences error_details []string errors []errors.Error @@ -803,7 +804,11 @@ fn (mut s Scanner) text_scan() token.Token { `{` { // Skip { in `${` in strings if s.is_inside_string { - continue + if s.text[s.pos - 1] == `$` { + continue + } else { + s.inter_cbr_count++ + } } return s.new_token(.lcbr, '', 1) } @@ -817,7 +822,7 @@ fn (mut s Scanner) text_scan() token.Token { `}` { // s = `hello $name !` // s = `hello ${name} !` - if s.is_enclosed_inter { + if s.is_enclosed_inter && s.inter_cbr_count == 0 { if s.pos < s.text.len - 1 { s.pos++ } else { @@ -832,6 +837,9 @@ fn (mut s Scanner) text_scan() token.Token { ident_string := s.ident_string() return s.new_token(.string, ident_string, ident_string.len + 2) // + two quotes } else { + if s.inter_cbr_count > 0 { + s.inter_cbr_count-- + } return s.new_token(.rcbr, '', 1) } } diff --git a/vlib/v/tests/string_interpolation_inner_cbr_test.v b/vlib/v/tests/string_interpolation_inner_cbr_test.v new file mode 100644 index 0000000000..a1c03df9f4 --- /dev/null +++ b/vlib/v/tests/string_interpolation_inner_cbr_test.v @@ -0,0 +1,21 @@ +struct St {} + +fn foo() ?int { + return 22 +} + +fn test_string_interpolation_inner_cbr() { + s1 := '${foo() or { 11 }}' + println(s1) + assert s1 == '22' + + s2 := '${St{}}' + println(s2) + assert s2 == 'St{}' + + s3 := '${{ + 'a': 1 + }}' + println(s3) + assert s3 == "{'a': 1}" +}