From 4e64a58ac108f355a50dc4d3275741feb3ed92f9 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Sun, 3 Nov 2019 23:57:26 +0300 Subject: [PATCH] scanner: fix string interpolation in raw strings --- vlib/builtin/string_test.v | 7 +++++++ vlib/compiler/parser.v | 2 +- vlib/compiler/scanner.v | 10 +++++----- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/vlib/builtin/string_test.v b/vlib/builtin/string_test.v index e5ff82253d..dcf98255eb 100644 --- a/vlib/builtin/string_test.v +++ b/vlib/builtin/string_test.v @@ -498,3 +498,10 @@ fn test_atoi() { } } +fn test_raw_inter() { + world := 'world' + s := r'hello\n$world' + assert s == r'hello\n$world' + assert s.contains('$') +} + diff --git a/vlib/compiler/parser.v b/vlib/compiler/parser.v index 674f6f038d..b38b523371 100644 --- a/vlib/compiler/parser.v +++ b/vlib/compiler/parser.v @@ -2733,7 +2733,7 @@ fn (p mut Parser) string_expr() { // `C.puts('hi')` => `puts("hi");` /* Calling a C function sometimes requires a call to a string method - C.fun('ssss'.to_wide()) => fun(string_to_wide(tos2((byte*)('ssss')))) + C.fun('ssss'.to_wide()) => fun(string_to_wide(tos3("ssss"))) */ if (p.calling_c && p.peek() != .dot) || (p.pref.translated && p.mod == 'main') { p.gen('"$f"') diff --git a/vlib/compiler/scanner.v b/vlib/compiler/scanner.v index 485d4171b1..432a6266d1 100644 --- a/vlib/compiler/scanner.v +++ b/vlib/compiler/scanner.v @@ -650,11 +650,11 @@ fn (s Scanner) count_symbol_before(p int, sym byte) int { return count } -// println('array out of bounds $idx len=$a.len') -// This is really bad. It needs a major clean up fn (s mut Scanner) ident_string() string { q := s.text[s.pos] - if (q == single_quote || q == double_quote) && !s.inside_string{ + is_quote := q == single_quote || q == double_quote + is_raw := is_quote && s.text[s.pos-1] == `r` + if is_quote && !s.inside_string { s.quote = q } //if s.file_path.contains('string_test') { @@ -688,14 +688,14 @@ fn (s mut Scanner) ident_string() string { s.error('0 character in a string literal') } // ${var} - if c == `{` && prevc == `$` && s.count_symbol_before(s.pos-2, slash) % 2 == 0 { + if c == `{` && prevc == `$` && !is_raw && s.count_symbol_before(s.pos-2, slash) % 2 == 0 { s.inside_string = true // so that s.pos points to $ at the next step s.pos -= 2 break } // $var - if (c.is_letter() || c == `_`) && prevc == `$` && s.count_symbol_before(s.pos-2, slash) % 2 == 0 { + if (c.is_letter() || c == `_`) && prevc == `$` && !is_raw && s.count_symbol_before(s.pos-2, slash) % 2 == 0 { s.inside_string = true s.inter_start = true s.pos -= 2