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_', '')
|
||||
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]!!`
|
||||
expr := p.cgen.cur_line.right(pos).all_after('{').all_before('}')
|
||||
left := p.cgen.cur_line.left(pos).all_before('=')
|
||||
@ -1433,7 +1433,7 @@ fn (p mut Parser) var_decl() {
|
||||
// first variable
|
||||
names << p.check_name()
|
||||
p.scanner.validate_var_name(names[0])
|
||||
mut new_vars := 0
|
||||
mut new_vars := 0
|
||||
if names[0] != '_' && !p.known_var(names[0]) {
|
||||
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 if p.tok in ...
|
||||
if (p.tok == .assign && !p.is_sql) || p.tok.is_assign() {
|
||||
if is_indexer && is_str && !p.builtin_mod {
|
||||
p.error('strings are immutable')
|
||||
@ -2377,6 +2376,13 @@ fn (p mut Parser) indot_expr() string {
|
||||
if p.tok == .key_in {
|
||||
p.fgen(' ')
|
||||
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.gen('), ')
|
||||
arr_typ := p.expression()
|
||||
|
@ -287,3 +287,12 @@ fn test_multi() {
|
||||
//b := [ [[1,2,3],[4,5,6]], [[1,2]] ]
|
||||
//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 {
|
||||
return is_space(c)
|
||||
return c in [` `,`\n`,`\t`,`\v`,`\f`,`\r`]
|
||||
}
|
||||
|
||||
pub fn (s string) trim_space() string {
|
||||
|
Loading…
Reference in New Issue
Block a user