1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

checker, ast: add field promoted_type for InfixExpr, filled in by the checker, to save duplicate work in the backends (#17158)

This commit is contained in:
l-m 2023-01-29 19:06:05 +00:00 committed by GitHub
parent 4747e70d9d
commit bb512f782e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 22 additions and 10 deletions

View File

@ -1350,6 +1350,7 @@ fn (t Tree) infix_expr(node ast.InfixExpr) &Node {
obj.add_terse('left_type', t.type_node(node.left_type)) obj.add_terse('left_type', t.type_node(node.left_type))
obj.add_terse('right', t.expr(node.right)) obj.add_terse('right', t.expr(node.right))
obj.add_terse('right_type', t.type_node(node.right_type)) obj.add_terse('right_type', t.type_node(node.right_type))
obj.add_terse('promoted_type', t.type_node(node.promoted_type))
obj.add('auto_locked', t.string_node(node.auto_locked)) obj.add('auto_locked', t.string_node(node.auto_locked))
obj.add_terse('or_block', t.or_expr(node.or_block)) obj.add_terse('or_block', t.or_expr(node.or_block))
obj.add_terse('is_stmt', t.bool_node(node.is_stmt)) obj.add_terse('is_stmt', t.bool_node(node.is_stmt))

View File

@ -866,12 +866,13 @@ pub:
pos token.Pos pos token.Pos
is_stmt bool is_stmt bool
pub mut: pub mut:
left Expr left Expr
right Expr right Expr
left_type Type left_type Type
right_type Type right_type Type
auto_locked string promoted_type Type = void_type
or_block OrExpr auto_locked string
or_block OrExpr
// //
ct_left_value_evaled bool ct_left_value_evaled bool
ct_left_value ComptTimeConstValue = empty_comptime_const_expr() ct_left_value ComptTimeConstValue = empty_comptime_const_expr()

View File

@ -23,6 +23,7 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
if node.op == .amp && left_type.is_bool() && right_type.is_bool() && right_type.is_ptr() { if node.op == .amp && left_type.is_bool() && right_type.is_bool() && right_type.is_ptr() {
pos := node.pos.extend(node.right.pos()) pos := node.pos.extend(node.right.pos())
c.error('the right expression should be separated from the `&&` by a space', pos) c.error('the right expression should be separated from the `&&` by a space', pos)
node.promoted_type = ast.bool_type
return ast.bool_type return ast.bool_type
} }
node.right_type = right_type node.right_type = right_type
@ -188,6 +189,7 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
node.pos) node.pos)
} }
} }
node.promoted_type = ast.bool_type
return ast.bool_type return ast.bool_type
} }
.plus, .minus, .mul, .div, .mod, .xor, .amp, .pipe { .plus, .minus, .mul, .div, .mod, .xor, .amp, .pipe {
@ -367,6 +369,7 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
c.error('only `==` and `!=` are defined on arrays', node.pos) c.error('only `==` and `!=` are defined on arrays', node.pos)
} else if left_sym.kind == .struct_ } else if left_sym.kind == .struct_
&& (left_sym.info as ast.Struct).generic_types.len > 0 { && (left_sym.info as ast.Struct).generic_types.len > 0 {
node.promoted_type = ast.bool_type
return ast.bool_type return ast.bool_type
} else if left_sym.kind == .struct_ && right_sym.kind == .struct_ } else if left_sym.kind == .struct_ && right_sym.kind == .struct_
&& node.op in [.eq, .lt] { && node.op in [.eq, .lt] {
@ -489,11 +492,13 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
c.error('cannot append `${right_sym.name}` to `${left_sym.name}`', right_pos) c.error('cannot append `${right_sym.name}` to `${left_sym.name}`', right_pos)
return ast.void_type return ast.void_type
} else { } else {
return c.check_shift(mut node, left_type, right_type) node.promoted_type = c.check_shift(mut node, left_type, right_type)
return node.promoted_type
} }
} }
.right_shift { .right_shift {
return c.check_shift(mut node, left_type, right_type) node.promoted_type = c.check_shift(mut node, left_type, right_type)
return node.promoted_type
} }
.unsigned_right_shift { .unsigned_right_shift {
modified_left_type := if !left_type.is_int() { modified_left_type := if !left_type.is_int() {
@ -538,7 +543,9 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
or_block: node.or_block or_block: node.or_block
} }
return c.check_shift(mut node, left_type, right_type) node.promoted_type = c.check_shift(mut node, left_type, right_type)
return node.promoted_type
} }
.key_is, .not_is { .key_is, .not_is {
right_expr := node.right right_expr := node.right
@ -579,6 +586,7 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
} }
} }
} }
node.promoted_type = ast.bool_type
return ast.bool_type return ast.bool_type
} }
.arrow { // `chan <- elem` .arrow { // `chan <- elem`
@ -677,6 +685,7 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
} }
if left_type.nr_muls() > 0 && right_type.is_int() { if left_type.nr_muls() > 0 && right_type.is_int() {
// pointer arithmetic is fine, it is checked in other places // pointer arithmetic is fine, it is checked in other places
node.promoted_type = return_type
return return_type return return_type
} }
c.error('infix expr: cannot use `${right_sym.name}` (right expression) as `${left_sym.name}`', c.error('infix expr: cannot use `${right_sym.name}` (right expression) as `${left_sym.name}`',
@ -698,7 +707,8 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
c.warn('`++` and `--` are statements, not expressions', node.pos) c.warn('`++` and `--` are statements, not expressions', node.pos)
} }
*/ */
return if node.op.is_relational() { ast.bool_type } else { return_type } node.promoted_type = if node.op.is_relational() { ast.bool_type } else { return_type }
return node.promoted_type
} }
fn (mut c Checker) check_div_mod_by_zero(expr ast.Expr, op_kind token.Kind) { fn (mut c Checker) check_div_mod_by_zero(expr ast.Expr, op_kind token.Kind) {