scanner: fix interpolation with string args (#7214)
							parent
							
								
									cf755d40b7
								
							
						
					
					
						commit
						5fa1e403ec
					
				|  | @ -26,6 +26,7 @@ pub mut: | ||||||
| 	is_inside_string            bool | 	is_inside_string            bool | ||||||
| 	is_inter_start              bool // for hacky string interpolation TODO simplify
 | 	is_inter_start              bool // for hacky string interpolation TODO simplify
 | ||||||
| 	is_inter_end                bool | 	is_inter_end                bool | ||||||
|  | 	is_enclosed_inter           bool | ||||||
| 	is_debug                    bool | 	is_debug                    bool | ||||||
| 	line_comment                string | 	line_comment                string | ||||||
| 	// prev_tok                 TokenKind
 | 	// prev_tok                 TokenKind
 | ||||||
|  | @ -34,6 +35,7 @@ pub mut: | ||||||
| 	is_print_colored_error      bool | 	is_print_colored_error      bool | ||||||
| 	is_print_rel_paths_on_error bool | 	is_print_rel_paths_on_error bool | ||||||
| 	quote                       byte // which quote is used to denote current string: ' or "
 | 	quote                       byte // which quote is used to denote current string: ' or "
 | ||||||
|  | 	inter_quote                 byte | ||||||
| 	line_ends                   []int // the positions of source lines ends   (i.e. \n signs)
 | 	line_ends                   []int // the positions of source lines ends   (i.e. \n signs)
 | ||||||
| 	nr_lines                    int // total number of lines in the source file that were scanned
 | 	nr_lines                    int // total number of lines in the source file that were scanned
 | ||||||
| 	is_vh                       bool // Keep newlines
 | 	is_vh                       bool // Keep newlines
 | ||||||
|  | @ -716,12 +718,14 @@ fn (mut s Scanner) text_scan() token.Token { | ||||||
| 			`}` { | 			`}` { | ||||||
| 				// s = `hello $name !`
 | 				// s = `hello $name !`
 | ||||||
| 				// s = `hello ${name} !`
 | 				// s = `hello ${name} !`
 | ||||||
| 				if s.is_inside_string { | 				if s.is_enclosed_inter { | ||||||
| 					s.pos++ | 					s.pos++ | ||||||
| 					if s.text[s.pos] == s.quote { | 					if s.text[s.pos] == s.quote { | ||||||
| 						s.is_inside_string = false | 						s.is_inside_string = false | ||||||
|  | 						s.is_enclosed_inter = false | ||||||
| 						return s.new_token(.string, '', 1) | 						return s.new_token(.string, '', 1) | ||||||
| 					} | 					} | ||||||
|  | 					s.is_enclosed_inter = false | ||||||
| 					ident_string := s.ident_string() | 					ident_string := s.ident_string() | ||||||
| 					return s.new_token(.string, ident_string, ident_string.len + 2) // + two quotes
 | 					return s.new_token(.string, ident_string, ident_string.len + 2) // + two quotes
 | ||||||
| 				} else { | 				} else { | ||||||
|  | @ -993,8 +997,12 @@ fn (mut s Scanner) ident_string() string { | ||||||
| 	is_quote := q == single_quote || q == double_quote | 	is_quote := q == single_quote || q == double_quote | ||||||
| 	is_raw := is_quote && s.pos > 0 && s.text[s.pos - 1] == `r` | 	is_raw := is_quote && s.pos > 0 && s.text[s.pos - 1] == `r` | ||||||
| 	is_cstr := is_quote && s.pos > 0 && s.text[s.pos - 1] == `c` | 	is_cstr := is_quote && s.pos > 0 && s.text[s.pos - 1] == `c` | ||||||
| 	if is_quote && !s.is_inside_string { | 	if is_quote { | ||||||
| 		s.quote = q | 		if s.is_inside_string { | ||||||
|  | 			s.inter_quote = q | ||||||
|  | 		} else { | ||||||
|  | 			s.quote = q | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 	// if s.file_path.contains('string_test') {
 | 	// if s.file_path.contains('string_test') {
 | ||||||
| 	// println('\nident_string() at char=${s.text[s.pos].str()}')
 | 	// println('\nident_string() at char=${s.text[s.pos].str()}')
 | ||||||
|  | @ -1002,6 +1010,10 @@ fn (mut s Scanner) ident_string() string { | ||||||
| 	// }
 | 	// }
 | ||||||
| 	mut n_cr_chars := 0 | 	mut n_cr_chars := 0 | ||||||
| 	mut start := s.pos | 	mut start := s.pos | ||||||
|  | 	if s.text[start] == s.quote || | ||||||
|  | 		(s.text[start] == s.inter_quote && (s.is_inter_start || s.is_enclosed_inter)) { | ||||||
|  | 		start++ | ||||||
|  | 	} | ||||||
| 	s.is_inside_string = false | 	s.is_inside_string = false | ||||||
| 	slash := `\\` | 	slash := `\\` | ||||||
| 	for { | 	for { | ||||||
|  | @ -1016,6 +1028,9 @@ fn (mut s Scanner) ident_string() string { | ||||||
| 			// handle '123\\'  slash at the end
 | 			// handle '123\\'  slash at the end
 | ||||||
| 			break | 			break | ||||||
| 		} | 		} | ||||||
|  | 		if c == s.inter_quote && (s.is_inter_start || s.is_enclosed_inter) { | ||||||
|  | 			break | ||||||
|  | 		} | ||||||
| 		if c == `\r` { | 		if c == `\r` { | ||||||
| 			n_cr_chars++ | 			n_cr_chars++ | ||||||
| 		} | 		} | ||||||
|  | @ -1054,6 +1069,7 @@ fn (mut s Scanner) ident_string() string { | ||||||
| 		// ${var} (ignore in vfmt mode) (skip \$)
 | 		// ${var} (ignore in vfmt mode) (skip \$)
 | ||||||
| 		if prevc == `$` && c == `{` && !is_raw && s.count_symbol_before(s.pos - 2, slash) % 2 == 0 { | 		if prevc == `$` && c == `{` && !is_raw && s.count_symbol_before(s.pos - 2, slash) % 2 == 0 { | ||||||
| 			s.is_inside_string = true | 			s.is_inside_string = true | ||||||
|  | 			s.is_enclosed_inter = true | ||||||
| 			// so that s.pos points to $ at the next step
 | 			// so that s.pos points to $ at the next step
 | ||||||
| 			s.pos -= 2 | 			s.pos -= 2 | ||||||
| 			break | 			break | ||||||
|  | @ -1068,9 +1084,6 @@ fn (mut s Scanner) ident_string() string { | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	mut lit := '' | 	mut lit := '' | ||||||
| 	if s.text[start] == s.quote { |  | ||||||
| 		start++ |  | ||||||
| 	} |  | ||||||
| 	mut end := s.pos | 	mut end := s.pos | ||||||
| 	if s.is_inside_string { | 	if s.is_inside_string { | ||||||
| 		end++ | 		end++ | ||||||
|  |  | ||||||
|  | @ -0,0 +1,9 @@ | ||||||
|  | fn show_info(a string) string { | ||||||
|  | 	return a | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | fn test_interpolation_string_args() { | ||||||
|  | 	assert '${show_info("abc")}' == 'abc' | ||||||
|  | 	assert '${show_info("bac")}' == 'bac' | ||||||
|  | 	assert '${"aaa"}' == 'aaa' | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue