v: implement expr.remove_para (#24669)

This commit is contained in:
Swastik Baranwal 2025-06-08 15:21:29 +05:30 committed by GitHub
parent a5f400ee77
commit c0bdb4a47b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 19 additions and 30 deletions

View File

@ -2728,6 +2728,15 @@ pub fn (expr Expr) is_reference() bool {
} }
} }
// remove_par removes all parenthesis and gets the innermost Expr
pub fn (mut expr Expr) remove_par() Expr {
mut e := expr
for mut e is ParExpr {
e = e.expr
}
return e
}
// is `expr` a literal, i.e. it does not depend on any other declarations (C compile time constant) // is `expr` a literal, i.e. it does not depend on any other declarations (C compile time constant)
pub fn (expr Expr) is_literal() bool { pub fn (expr Expr) is_literal() bool {
return match expr { return match expr {

View File

@ -339,10 +339,7 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
if left is ast.ParExpr && is_decl { if left is ast.ParExpr && is_decl {
c.error('parentheses are not supported on the left side of `:=`', left.pos()) c.error('parentheses are not supported on the left side of `:=`', left.pos())
} }
left = left.remove_par()
for left is ast.ParExpr {
left = (left as ast.ParExpr).expr
}
is_assign := node.op in [.assign, .decl_assign] is_assign := node.op in [.assign, .decl_assign]
match mut left { match mut left {
ast.Ident { ast.Ident {
@ -943,9 +940,7 @@ or use an explicit `unsafe{ a[..] }`, if you do not want a copy of the slice.',
c.inside_ref_lit = old_inside_ref_lit c.inside_ref_lit = old_inside_ref_lit
if right_node.op == .amp { if right_node.op == .amp {
mut expr := right_node.right mut expr := right_node.right
for mut expr is ast.ParExpr { expr = expr.remove_par()
expr = expr.expr
}
if mut expr is ast.Ident { if mut expr is ast.Ident {
if mut expr.obj is ast.Var { if mut expr.obj is ast.Var {
v := expr.obj v := expr.obj

View File

@ -4767,10 +4767,7 @@ fn (mut c Checker) prefix_expr(mut node ast.PrefixExpr) ast.Type {
c.inside_ref_lit = old_inside_ref_lit c.inside_ref_lit = old_inside_ref_lit
node.right_type = right_type node.right_type = right_type
mut expr := node.right mut expr := node.right
// if ParExpr get the innermost expr expr = expr.remove_par()
for mut expr is ast.ParExpr {
expr = expr.expr
}
if node.op == .amp { if node.op == .amp {
if expr is ast.Nil { if expr is ast.Nil {
c.error('invalid operation: cannot take address of nil', expr.pos()) c.error('invalid operation: cannot take address of nil', expr.pos())

View File

@ -1983,9 +1983,7 @@ fn (mut c Checker) check_type_and_visibility(name string, type_idx int, expected
fn (mut c Checker) method_call(mut node ast.CallExpr, mut continue_check &bool) ast.Type { fn (mut c Checker) method_call(mut node ast.CallExpr, mut continue_check &bool) ast.Type {
// `(if true { 'foo.bar' } else { 'foo.bar.baz' }).all_after('foo.')` // `(if true { 'foo.bar' } else { 'foo.bar.baz' }).all_after('foo.')`
mut left_expr := node.left mut left_expr := node.left
for mut left_expr is ast.ParExpr { left_expr = left_expr.remove_par()
left_expr = left_expr.expr
}
if mut left_expr is ast.IfExpr { if mut left_expr is ast.IfExpr {
if left_expr.branches.len > 0 && left_expr.has_else { if left_expr.branches.len > 0 && left_expr.has_else {
mut last_stmt := left_expr.branches[0].stmts.last() mut last_stmt := left_expr.branches[0].stmts.last()

View File

@ -856,9 +856,7 @@ fn expr_is_single_line(expr ast.Expr) bool {
pub fn (mut f Fmt) assert_stmt(node ast.AssertStmt) { pub fn (mut f Fmt) assert_stmt(node ast.AssertStmt) {
f.write('assert ') f.write('assert ')
mut expr := node.expr mut expr := node.expr
for mut expr is ast.ParExpr { expr = expr.remove_par()
expr = expr.expr
}
f.expr(expr) f.expr(expr)
if node.extra !is ast.EmptyExpr { if node.extra !is ast.EmptyExpr {
f.write(', ') f.write(', ')
@ -2935,9 +2933,7 @@ pub fn (mut f Fmt) or_expr(node ast.OrExpr) {
pub fn (mut f Fmt) par_expr(node ast.ParExpr) { pub fn (mut f Fmt) par_expr(node ast.ParExpr) {
mut expr := node.expr mut expr := node.expr
for mut expr is ast.ParExpr { expr = expr.remove_par()
expr = expr.expr
}
requires_paren := expr !is ast.Ident || node.comments.len > 0 requires_paren := expr !is ast.Ident || node.comments.len > 0
if requires_paren { if requires_paren {
f.par_level++ f.par_level++

View File

@ -729,9 +729,7 @@ fn expr_is_single_line(expr ast.Expr) bool {
pub fn (mut f Gen) assert_stmt(node ast.AssertStmt) { pub fn (mut f Gen) assert_stmt(node ast.AssertStmt) {
f.write('assert ') f.write('assert ')
mut expr := node.expr mut expr := node.expr
for mut expr is ast.ParExpr { expr = expr.remove_par()
expr = expr.expr
}
f.expr(expr) f.expr(expr)
f.writeln('') f.writeln('')
} }
@ -2058,9 +2056,7 @@ pub fn (mut f Gen) par_expr(node ast.ParExpr) {
f.write('(') f.write('(')
} }
mut expr := node.expr mut expr := node.expr
for mut expr is ast.ParExpr { expr = expr.remove_par()
expr = expr.expr
}
f.expr(expr) f.expr(expr)
if requires_paren { if requires_paren {
f.par_level-- f.par_level--

View File

@ -790,9 +790,7 @@ fn (mut p Parser) infix_expr(left ast.Expr) ast.Expr {
p.inside_assign_rhs = old_assign_rhs p.inside_assign_rhs = old_assign_rhs
if op in [.plus, .minus, .mul, .div, .mod, .lt, .eq] && mut right is ast.PrefixExpr { if op in [.plus, .minus, .mul, .div, .mod, .lt, .eq] && mut right is ast.PrefixExpr {
mut right_expr := right.right mut right_expr := right.right
for mut right_expr is ast.ParExpr { right_expr = right_expr.remove_par()
right_expr = right_expr.expr
}
if right.op in [.plus, .minus, .mul, .div, .mod, .lt, .eq] && right_expr.is_pure_literal() { if right.op in [.plus, .minus, .mul, .div, .mod, .lt, .eq] && right_expr.is_pure_literal() {
p.error_with_pos('invalid expression: unexpected token `${op}`', right_op_pos) p.error_with_pos('invalid expression: unexpected token `${op}`', right_op_pos)
} }