gen/c: avoid double evaluation of string being sliced
parent
0ca87ad09f
commit
d9f4be8c93
|
|
@ -64,6 +64,15 @@ fn (mut g Gen) range_expr(node ast.IndexExpr, range ast.RangeExpr) {
|
|||
mut gen_or := node.or_expr.kind != .absent || node.is_option
|
||||
mut tmp_left := ''
|
||||
|
||||
if !range.has_high && sym.kind != .array_fixed {
|
||||
tmp_left = g.new_tmp_var()
|
||||
tmp_type := g.typ(node.left_type)
|
||||
g.insert_before_stmt('${util.tabs(g.indent)}$tmp_type $tmp_left;')
|
||||
// (tmp = left, slice_func(tmp, low, tmp.len))
|
||||
g.write('($tmp_left = ')
|
||||
g.expr(node.left)
|
||||
g.write(', ')
|
||||
}
|
||||
if sym.kind == .string {
|
||||
if node.is_gated {
|
||||
g.write('string_substr_ni(')
|
||||
|
|
@ -78,33 +87,12 @@ fn (mut g Gen) range_expr(node ast.IndexExpr, range ast.RangeExpr) {
|
|||
g.write('string_substr(')
|
||||
}
|
||||
}
|
||||
if node.left_type.is_ptr() {
|
||||
g.write('*')
|
||||
}
|
||||
g.expr(node.left)
|
||||
} else if sym.kind == .array {
|
||||
if !range.has_high {
|
||||
tmp_left = g.new_tmp_var()
|
||||
tmp_type := g.typ(node.left_type)
|
||||
g.insert_before_stmt('${util.tabs(g.indent)}$tmp_type $tmp_left;')
|
||||
// (tmp = expr, array_slice(...))
|
||||
g.write('($tmp_left = ')
|
||||
g.expr(node.left)
|
||||
g.write(', ')
|
||||
}
|
||||
if node.is_gated {
|
||||
g.write('array_slice_ni(')
|
||||
} else {
|
||||
g.write('array_slice(')
|
||||
}
|
||||
if node.left_type.is_ptr() {
|
||||
g.write('*')
|
||||
}
|
||||
if range.has_high {
|
||||
g.expr(node.left)
|
||||
} else {
|
||||
g.write(tmp_left)
|
||||
}
|
||||
} else if sym.kind == .array_fixed {
|
||||
// Convert a fixed array to V array when doing `fixed_arr[start..end]`
|
||||
info := sym.info as ast.ArrayFixed
|
||||
|
|
@ -132,7 +120,18 @@ fn (mut g Gen) range_expr(node ast.IndexExpr, range ast.RangeExpr) {
|
|||
g.expr(node.left)
|
||||
g.write(')')
|
||||
} else {
|
||||
g.expr(node.left)
|
||||
t := g.table.type_to_str(node.left_type)
|
||||
g.error('unexpected slice of type $t', node.left.pos())
|
||||
}
|
||||
if sym.kind != .array_fixed {
|
||||
if node.left_type.is_ptr() {
|
||||
g.write('*')
|
||||
}
|
||||
if range.has_high {
|
||||
g.expr(node.left)
|
||||
} else {
|
||||
g.write(tmp_left)
|
||||
}
|
||||
}
|
||||
g.write(', ')
|
||||
if range.has_low {
|
||||
|
|
@ -146,17 +145,13 @@ fn (mut g Gen) range_expr(node ast.IndexExpr, range ast.RangeExpr) {
|
|||
} else if sym.kind == .array_fixed {
|
||||
info := sym.info as ast.ArrayFixed
|
||||
g.write('$info.size')
|
||||
} else if sym.kind == .array {
|
||||
} else {
|
||||
if node.left_type.is_ptr() {
|
||||
g.write('$tmp_left->')
|
||||
} else {
|
||||
g.write('${tmp_left}.')
|
||||
}
|
||||
g.write('len)')
|
||||
} else {
|
||||
g.write('(')
|
||||
g.expr(node.left)
|
||||
g.write(').len')
|
||||
}
|
||||
g.write(')')
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ fn test_fixed_array_can_be_assigned() {
|
|||
}
|
||||
v = [8]f64{init: 3.0}
|
||||
assert v[1] == 3.0
|
||||
assert v[..].len == 8
|
||||
}
|
||||
|
||||
fn test_fixed_array_assignment() {
|
||||
|
|
|
|||
|
|
@ -6,3 +6,23 @@ fn test_arr_rval() {
|
|||
b := unsafe { *&[]int(&a) }[..]
|
||||
assert b == a
|
||||
}
|
||||
|
||||
fn geta(mut n []int) []int {
|
||||
n[0]++
|
||||
return [1]
|
||||
}
|
||||
|
||||
fn gets(mut n []int) string {
|
||||
n[0]++
|
||||
return "1"
|
||||
}
|
||||
|
||||
fn test_double_eval() {
|
||||
mut n := [0]
|
||||
r := geta(mut n)[..]
|
||||
assert n[0] == 1
|
||||
|
||||
s := gets(mut n)[..]
|
||||
assert s.len == 1 // use s
|
||||
assert n[0] == 2
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue