scanner: fix string interpolation in raw strings

pull/2633/head
Alexander Medvednikov 2019-11-03 23:57:26 +03:00
parent 3449a8bc4d
commit 4e64a58ac1
3 changed files with 13 additions and 6 deletions

View File

@ -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('$')
}

View File

@ -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"')

View File

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