cgen/autofree: sb.writeln() optimization fixes

pull/5824/head
Alexander Medvednikov 2020-07-13 18:59:39 +02:00
parent e5a5e76a30
commit 1c682d7b89
3 changed files with 36 additions and 16 deletions

View File

@ -42,10 +42,10 @@ fn main() {
return
}
*/
last_commits := exec('git log --pretty=format:"%h" -n 20').split('\n')
last_commits := exec('git log --pretty=format:"%h" -n 50').split('\n')
// Fetch all unprocessed commits (commits after the last processed commit)
mut commits := []string{}
println('last_commit="$commit_hash"')
println('!last_commit="$commit_hash"')
for i, c in last_commits {
if c == commit_hash {
commits = last_commits[..i].reverse()

View File

@ -1,5 +1,7 @@
import strings
type MyInt = int
fn test_sb() {
mut sb := strings.Builder{}
sb.write('hi')
@ -15,7 +17,20 @@ fn test_sb() {
sb.write('b')
assert sb.len == 2
assert sb.str() == 'ab'
///
// Test interpolation optimization
sb = strings.new_builder(10)
x := 10
y := MyInt(20)
sb.writeln('x = $x y = $y')
res := sb.str()
assert res[res.len-1] == `\n`
println('"$res"')
assert res.trim_space() == 'x = 10 y = 20'
//
sb = strings.new_builder(10)
sb.write('x = $x y = $y')
assert sb.str() == 'x = 10 y = 20'
$if !windows {
// TODO msvc bug
sb = strings.new_builder(10)

View File

@ -146,22 +146,15 @@ fn (mut g Gen) string_inter_literal_sb_optimized(call_expr ast.CallExpr) {
// sb_name := g.cur_call_expr.left
// g.go_before_stmt(0)
g.writeln('// sb inter opt')
write := 'writeln'
/*
if node.vals.len != node.exprs.len {
println('NOPE')
println(node.vals)
println('==========')
println(node.exprs)
}
*/
is_nl := call_expr.name == 'writeln'
// println('optimize sb $call_expr.name')
for i, val in node.vals {
escaped_val := val.replace_each(['"', '\\"', '\r\n', '\\n', '\n', '\\n', '%', '%%'])
// if val == '' {
// break
// continue
// }
g.write('strings__Builder_${write}(&')
g.write('strings__Builder_write(&')
g.expr(call_expr.left)
g.write(', tos_lit("')
g.write(escaped_val)
@ -173,11 +166,23 @@ fn (mut g Gen) string_inter_literal_sb_optimized(call_expr ast.CallExpr) {
// if node.expr_types.len <= i || node.exprs.len <= i {
// continue
// }
g.write('strings__Builder_${write}(&')
if is_nl && i == node.exprs.len - 1 {
g.write('strings__Builder_writeln(&')
} else {
g.write('strings__Builder_write(&')
}
g.expr(call_expr.left)
g.write(', ')
g.write(g.typ(node.expr_types[i]))
g.write('_str(')
typ := node.expr_types[i]
sym := g.table.get_type_symbol(typ)
// if typ.is_number() {
if sym.kind == .alias && (sym.info as table.Alias).parent_type.is_number() {
// Handle number aliases TODO this must be more generic, handled by g.typ()?
g.write('int_str(')
} else {
g.write(g.typ(typ))
g.write('_str(')
}
g.expr(node.exprs[i])
g.writeln('));')
}