From b8e87689289e890bfd0f73712691c6799a7a8ac0 Mon Sep 17 00:00:00 2001 From: yuyi Date: Sat, 28 May 2022 17:02:17 +0800 Subject: [PATCH] parser, cgen: fix cross assign with parentheses (#14545) --- vlib/v/gen/c/assign.v | 16 ++++++++++++++++ vlib/v/parser/assign.v | 10 ++++++++++ .../tests/cross_assign_with_parentheses_test.v | 17 +++++++++++++++++ 3 files changed, 43 insertions(+) create mode 100644 vlib/v/tests/cross_assign_with_parentheses_test.v diff --git a/vlib/v/gen/c/assign.v b/vlib/v/gen/c/assign.v index 33ad955cac..f45f40deaf 100644 --- a/vlib/v/gen/c/assign.v +++ b/vlib/v/gen/c/assign.v @@ -762,6 +762,22 @@ fn (mut g Gen) gen_cross_tmp_variable(left []ast.Expr, val ast.Expr) { g.gen_cross_tmp_variable(left, val.right) } } + ast.ParExpr { + g.write('(') + g.gen_cross_tmp_variable(left, val.expr) + g.write(')') + } + ast.CallExpr { + fn_name := val.name.replace('.', '__') + g.write('${fn_name}(') + for i, arg in val.args { + g.gen_cross_tmp_variable(left, arg.expr) + if i != val.args.len - 1 { + g.write(', ') + } + } + g.write(')') + } ast.PrefixExpr { g.write(val.op.str()) g.gen_cross_tmp_variable(left, val.right) diff --git a/vlib/v/parser/assign.v b/vlib/v/parser/assign.v index f1603ea9c5..0c3ab4cfe8 100644 --- a/vlib/v/parser/assign.v +++ b/vlib/v/parser/assign.v @@ -141,6 +141,16 @@ fn (mut p Parser) check_cross_variables(exprs []ast.Expr, val ast.Expr) bool { return p.check_cross_variables(exprs, val.left) || p.check_cross_variables(exprs, val.right) } + ast.ParExpr { + return p.check_cross_variables(exprs, val.expr) + } + ast.CallExpr { + for arg in val.args { + if p.check_cross_variables(exprs, arg.expr) { + return true + } + } + } ast.PrefixExpr { return p.check_cross_variables(exprs, val.right) } diff --git a/vlib/v/tests/cross_assign_with_parentheses_test.v b/vlib/v/tests/cross_assign_with_parentheses_test.v new file mode 100644 index 0000000000..9e81f1bf67 --- /dev/null +++ b/vlib/v/tests/cross_assign_with_parentheses_test.v @@ -0,0 +1,17 @@ +import math + +const ep = 1e-14 + +fn agm(aa f64, gg f64) f64 { + mut a, mut g := aa, gg + for math.abs(a - g) > math.abs(a) * ep { + a, g = (a + g) * .5, math.sqrt(a * g) + } + return a +} + +fn test_cross_assign_with_parentheses() { + ret := agm(1.0, 1.0 / math.sqrt2) + println(ret) + assert ret == 0.8472130847939792 +}