diff --git a/vlib/time/parse.v b/vlib/time/parse.v index d97c162aff..06f3b150d2 100644 --- a/vlib/time/parse.v +++ b/vlib/time/parse.v @@ -42,7 +42,7 @@ pub fn parse_rfc2822(s string) ?Time { mm := pos / 3 + 1 mut tmstr := byteptr(0) unsafe { tmstr = malloc(s.len * 2) } - count := C.sprintf(charptr(tmstr), '%s-%02d-%s %s'.str, fields[3].str, mm, + count := C.sprintf(charptr(tmstr), '%s-%02d-%s %s', fields[3].str, mm, fields[1].str, fields[4].str) t := parse(tos(tmstr, count)) or { diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index b4380686be..3835ee2719 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -944,6 +944,16 @@ fn (g mut Gen) infix_expr(node ast.InfixExpr) { else if node.op == .key_in { right_sym := g.table.get_type_symbol(node.right_type) if right_sym.kind == .array { + match node.right { + ast.ArrayInit { + // `a in [1,2,3]` optimization => `a == 1 || a == 2 || a == 3` + // avoids an allocation + // g.write('/*in opt*/') + g.in_optimization(node.left, it) + return + } + else {} + } styp := g.typ(node.left_type) g.write('_IN($styp, ') g.expr(node.left) @@ -1634,6 +1644,30 @@ fn (g mut Gen) gen_filter(node ast.MethodCallExpr) { g.write(tmp) } +// `a in [1,2,3]` => `a == 1 || a == 2 || a == 3` +fn (g mut Gen) in_optimization(left ast.Expr, right ast.ArrayInit) { + is_str := right.elem_type == table.string_type + for i, array_expr in right.exprs { + if is_str { + g.write('string_eq(') + } + g.expr(left) + if is_str { + g.write(', ') + } + else { + g.write(' == ') + } + g.expr(array_expr) + if is_str { + g.write(')') + } + if i < right.exprs.len - 1 { + g.write(' || ') + } + } +} + fn op_to_fn_name(name string) string { return match name { '+'{ diff --git a/vlib/v/gen/cheaders.v b/vlib/v/gen/cheaders.v index 1d9f4e81c4..2d42d01dc5 100644 --- a/vlib/v/gen/cheaders.v +++ b/vlib/v/gen/cheaders.v @@ -40,6 +40,8 @@ const ( #endif #endif +#define V_COMMIT_HASH "TODO" + ' c_headers = ' diff --git a/vlib/v/gen/tests/3.c b/vlib/v/gen/tests/3.c index 9804a496b3..5b297c264b 100644 --- a/vlib/v/gen/tests/3.c +++ b/vlib/v/gen/tests/3.c @@ -33,6 +33,10 @@ void User_foo(User* u) { array_string zzz = array_repeat(new_array_from_c_array(1, 1, sizeof(string), (string[]){ tos3(""), }), u->age); + int a = 10; + if (a == 10 || a == 20 || a == 30) { + int b = 10; + } } void println(string s) { diff --git a/vlib/v/gen/tests/3.vv b/vlib/v/gen/tests/3.vv index fd3ac63668..c6b7f5852e 100644 --- a/vlib/v/gen/tests/3.vv +++ b/vlib/v/gen/tests/3.vv @@ -26,6 +26,10 @@ fn get_user_opt() ?User { fn (u &User) foo() { age := u.age zzz := [''].repeat(u.age) + a := 10 + if a in [10, 20, 30] { + b := 10 + } } fn println(s string) {}