mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
optimize a in [1,2,3]
to a == 1 || a == 2 || a == 3
This commit is contained in:
parent
62133c6ffa
commit
b242e8d7ff
40
compiler/optimization.v
Normal file
40
compiler/optimization.v
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
module main
|
||||||
|
|
||||||
|
// `a in [1,2,3]` => `a == 1 || a == 2 || a == 3`
|
||||||
|
// avoid allocation
|
||||||
|
// `typ` is the type of `a`
|
||||||
|
// `ph` is for string_eq()
|
||||||
|
fn (p mut Parser) in_optimization(typ string, ph int) {
|
||||||
|
p.check(.lsbr)
|
||||||
|
mut i := 0
|
||||||
|
// Get `a` expr value (can be a string literal, not a variable)
|
||||||
|
expr := p.cgen.cur_line.right(ph)
|
||||||
|
is_str := typ == 'string'
|
||||||
|
//println('!! $p.expr_var.name => $name ($typ)')
|
||||||
|
for p.tok != .rsbr && p.tok != .eof {
|
||||||
|
if i > 0 {
|
||||||
|
if is_str {
|
||||||
|
p.gen(' || string_eq($expr, ')
|
||||||
|
} else {
|
||||||
|
p.gen(' || $expr == ')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if i == 0 {
|
||||||
|
if is_str {
|
||||||
|
p.cgen.set_placeholder(ph, ' string_eq(')
|
||||||
|
p.gen(', ')
|
||||||
|
} else {
|
||||||
|
p.gen(' ==')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p.check_types(p.bool_expression(), typ)
|
||||||
|
if is_str {
|
||||||
|
p.gen(')')
|
||||||
|
}
|
||||||
|
if p.tok != .rsbr {
|
||||||
|
p.check(.comma)
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
p.check(.rsbr)
|
||||||
|
}
|
@ -1389,7 +1389,7 @@ fn ($v.name mut $v.typ) $p.cur_fn.name (...) {
|
|||||||
typ := expr_type.replace('Option_', '')
|
typ := expr_type.replace('Option_', '')
|
||||||
p.cgen.resetln(left + 'opt_ok($expr, sizeof($typ))')
|
p.cgen.resetln(left + 'opt_ok($expr, sizeof($typ))')
|
||||||
}
|
}
|
||||||
else if expr_type[0]==`[` {
|
else if expr_type[0]==`[` {
|
||||||
// assignment to a fixed_array `mut a:=[3]int a=[1,2,3]!!`
|
// assignment to a fixed_array `mut a:=[3]int a=[1,2,3]!!`
|
||||||
expr := p.cgen.cur_line.right(pos).all_after('{').all_before('}')
|
expr := p.cgen.cur_line.right(pos).all_after('{').all_before('}')
|
||||||
left := p.cgen.cur_line.left(pos).all_before('=')
|
left := p.cgen.cur_line.left(pos).all_before('=')
|
||||||
@ -1433,7 +1433,7 @@ fn (p mut Parser) var_decl() {
|
|||||||
// first variable
|
// first variable
|
||||||
names << p.check_name()
|
names << p.check_name()
|
||||||
p.scanner.validate_var_name(names[0])
|
p.scanner.validate_var_name(names[0])
|
||||||
mut new_vars := 0
|
mut new_vars := 0
|
||||||
if names[0] != '_' && !p.known_var(names[0]) {
|
if names[0] != '_' && !p.known_var(names[0]) {
|
||||||
new_vars++
|
new_vars++
|
||||||
}
|
}
|
||||||
@ -2322,7 +2322,6 @@ fn (p mut Parser) index_expr(typ_ string, fn_ph int) string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO move this from index_expr()
|
// TODO move this from index_expr()
|
||||||
// TODO if p.tok in ...
|
|
||||||
if (p.tok == .assign && !p.is_sql) || p.tok.is_assign() {
|
if (p.tok == .assign && !p.is_sql) || p.tok.is_assign() {
|
||||||
if is_indexer && is_str && !p.builtin_mod {
|
if is_indexer && is_str && !p.builtin_mod {
|
||||||
p.error('strings are immutable')
|
p.error('strings are immutable')
|
||||||
@ -2377,6 +2376,13 @@ fn (p mut Parser) indot_expr() string {
|
|||||||
if p.tok == .key_in {
|
if p.tok == .key_in {
|
||||||
p.fgen(' ')
|
p.fgen(' ')
|
||||||
p.check(.key_in)
|
p.check(.key_in)
|
||||||
|
//if p.pref.is_debug && p.tok == .lsbr {
|
||||||
|
if p.tok == .lsbr {
|
||||||
|
// a in [1,2,3] optimization => `a == 1 || a == 2 || a == 3`
|
||||||
|
// avoids an allocation
|
||||||
|
p.in_optimization(typ, ph)
|
||||||
|
return 'bool'
|
||||||
|
}
|
||||||
p.fgen(' ')
|
p.fgen(' ')
|
||||||
p.gen('), ')
|
p.gen('), ')
|
||||||
arr_typ := p.expression()
|
arr_typ := p.expression()
|
||||||
|
@ -287,3 +287,12 @@ fn test_multi() {
|
|||||||
//b := [ [[1,2,3],[4,5,6]], [[1,2]] ]
|
//b := [ [[1,2,3],[4,5,6]], [[1,2]] ]
|
||||||
//assert b[0][0][0] == 1
|
//assert b[0][0][0] == 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn test_in() {
|
||||||
|
a := [1,2,3]
|
||||||
|
assert 1 in a
|
||||||
|
assert 2 in a
|
||||||
|
assert 3 in a
|
||||||
|
assert !(4 in a)
|
||||||
|
assert !(0 in a)
|
||||||
|
}
|
||||||
|
@ -629,12 +629,8 @@ pub fn (a []string) to_c() voidptr {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
fn is_space(c byte) bool {
|
|
||||||
return c in [` `,`\n`,`\t`,`\v`,`\f`,`\r`]
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn (c byte) is_space() bool {
|
pub fn (c byte) is_space() bool {
|
||||||
return is_space(c)
|
return c in [` `,`\n`,`\t`,`\v`,`\f`,`\r`]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (s string) trim_space() string {
|
pub fn (s string) trim_space() string {
|
||||||
|
Loading…
Reference in New Issue
Block a user