cgen: string interpolation: optimize away some partial strings of 0 length
							parent
							
								
									19390871e9
								
							
						
					
					
						commit
						59aa31cee5
					
				|  | @ -2425,16 +2425,18 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) { | |||
| 	// Build the string with %
 | ||||
| 	mut fieldwidths := []int{} | ||||
| 	mut specs := []byte{} | ||||
| 	mut num_fmts := 1 | ||||
| 	mut end_string := false | ||||
| 	for i, val in node.vals { | ||||
| 		escaped_val := val.replace_each(['"', '\\"', '\r\n', '\\n', '\n', '\\n', '%', '%%']) | ||||
| 		g.write(escaped_val) | ||||
| 		if i >= node.exprs.len { | ||||
| 			fieldwidths << 0 | ||||
| 			specs << `_` | ||||
| 			if escaped_val.len > 0 { | ||||
| 				end_string = true | ||||
| 				g.write('\\000') | ||||
| 				g.write(escaped_val) | ||||
| 			} | ||||
| 			continue | ||||
| 		} | ||||
| 		num_fmts++ | ||||
| 		g.write(escaped_val) | ||||
| 		sym := g.table.get_type_symbol(node.expr_types[i]) | ||||
| 		sfmt := node.expr_fmts[i] | ||||
| 		mut fspec := `_` // placeholder
 | ||||
|  | @ -2507,7 +2509,7 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) { | |||
| 			if fspec == `p` { | ||||
| 				g.write('${fmt}p') | ||||
| 			} else { | ||||
| 				g.write('${fmt}l${fspec:c}') | ||||
| 				g.write('${fmt}"PRI${fspec:c}PTR"') | ||||
| 			} | ||||
| 		} else if node.expr_types[i].is_int() { | ||||
| 			if fspec == `c` { | ||||
|  | @ -2533,9 +2535,16 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) { | |||
| 			// TODO: better check this case
 | ||||
| 			g.write('${fmt}"PRId32"') | ||||
| 		} | ||||
| 		g.write('\\000') | ||||
| 		if i < node.exprs.len - 1 { | ||||
| 			g.write('\\000') | ||||
| 		} | ||||
| 	} | ||||
| 	g.write('", $num_fmts, ') | ||||
| 	num_string_parts := if end_string { | ||||
| 		node.exprs.len+1 | ||||
| 	} else { | ||||
| 		node.exprs.len | ||||
| 	} | ||||
| 	g.write('", $num_string_parts, ') | ||||
| 	// Build args
 | ||||
| 	for i, expr in node.exprs { | ||||
| 		if node.expr_types[i] == table.string_type { | ||||
|  |  | |||
|  | @ -70,8 +70,7 @@ string _STR(const char *fmt, int nfmts, ...) { | |||
| 				//v_panic(tos3('Invaid format specifier'));
 | ||||
| 			} | ||||
| 		} else { | ||||
| 			if (k) | ||||
| 				_STR_PRINT_ARG(fmt, &buf, &nbytes, &memsize, k); | ||||
| 			_STR_PRINT_ARG(fmt, &buf, &nbytes, &memsize, k); | ||||
| 		} | ||||
| 		fmt += k+1; | ||||
| 	} | ||||
|  |  | |||
|  | @ -98,8 +98,10 @@ fn test_inttypes_string_interpolation() { | |||
| 	assert '${s:X}:${us:x}:${u16(uc):04x}' == 'A460:d431:00d9' | ||||
| 	assert '${i:x}:${ui:X}:${int(s):x}' == '9f430000:CBF6EFC7:ffffa460' | ||||
| 	assert '${l:x}:${ul:X}' == '9537727cad98876c:EF2B7D4001165BD2' | ||||
| 	// TODO this does not work on Windows
 | ||||
| 	// assert '${vp:p}:$bp' == '0xcbf6efc7:0x39e53208c'
 | ||||
| 	// default pointer format is platform dependent, so try a few
 | ||||
| 	assert '${vp:p}:$bp' == '0xcbf6efc7:0x39e53208c' || | ||||
| 		'${vp:p}:$bp' == 'CBF6EFC7:39E53208C' || | ||||
| 		'${vp:p}:$bp' == '00000000CBF6EFC7:000000039E53208C' | ||||
| } | ||||
| 
 | ||||
| fn test_utf8_string_interpolation() { | ||||
|  | @ -108,9 +110,9 @@ fn test_utf8_string_interpolation() { | |||
| 	m := '10€' | ||||
| 	assert '$a $st $m' == 'à-côté Sträßle 10€' | ||||
| 	assert '>${a:10}< >${st:-8}< >${m:5}<-' == '>    à-côté< >Sträßle < >  10€<-' | ||||
| 	e := '\u20AC' // Eurosign
 | ||||
| 	// TODO: this fails with MSVC and tcc
 | ||||
| 	// assert '100.00 $e' == '100.00 €'
 | ||||
| 	// e := '\u20AC' // Eurosign doesn' work with MSVC and tcc
 | ||||
| 	e := '€' | ||||
| 	assert '100.00 $e' == '100.00 €' | ||||
| 	m2 := 'Москва́' // cyrillic а́: combination of U+0430 and U+0301, UTF-8: d0 b0 cc 81
 | ||||
| 	d := 'Antonín Dvořák' // latin á: U+00E1, UTF-8: c3 a1
 | ||||
| 	assert ':${m2:7}:${d:-15}:' == ': Москва́:Antonín Dvořák :' | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue