mirror of
https://github.com/vlang/v.git
synced 2025-09-16 07:52:32 +03:00
all: implement &&=
and ||=
(#21678)
This commit is contained in:
parent
2de0b36a6e
commit
add1621181
7 changed files with 81 additions and 1 deletions
|
@ -673,6 +673,15 @@ or use an explicit `unsafe{ a[..] }`, if you do not want a copy of the slice.',
|
|||
right.pos())
|
||||
}
|
||||
}
|
||||
.boolean_and_assign, .boolean_or_assign {
|
||||
if c.table.final_sym(left_type_unwrapped).kind != .bool {
|
||||
c.error('operator ${node.op.str()} not defined on left operand type `${left_sym.name}`',
|
||||
left.pos())
|
||||
} else if c.table.final_sym(right_type_unwrapped).kind != .bool {
|
||||
c.error('operator ${node.op.str()} not defined on right operand type `${right_sym.name}`',
|
||||
right.pos())
|
||||
}
|
||||
}
|
||||
.unsigned_right_shift_assign {
|
||||
if node.left.len != 1 || node.right.len != 1 {
|
||||
c.error('unsupported operation: unable to lower expression for unsigned shift assignment.',
|
||||
|
|
12
vlib/v/checker/tests/mismatch_bool_assign_err.out
Normal file
12
vlib/v/checker/tests/mismatch_bool_assign_err.out
Normal file
|
@ -0,0 +1,12 @@
|
|||
vlib/v/checker/tests/mismatch_bool_assign_err.vv:2:1: error: operator ||= not defined on left operand type `int`
|
||||
1 | mut b := 12
|
||||
2 | b ||= 34
|
||||
| ^
|
||||
3 | println(b)
|
||||
4 |
|
||||
vlib/v/checker/tests/mismatch_bool_assign_err.vv:6:1: error: operator &&= not defined on left operand type `string`
|
||||
4 |
|
||||
5 | mut c := 'str'
|
||||
6 | c &&= 's'
|
||||
| ^
|
||||
7 | println(c)
|
7
vlib/v/checker/tests/mismatch_bool_assign_err.vv
Normal file
7
vlib/v/checker/tests/mismatch_bool_assign_err.vv
Normal file
|
@ -0,0 +1,7 @@
|
|||
mut b := 12
|
||||
b ||= 34
|
||||
println(b)
|
||||
|
||||
mut c := 'str'
|
||||
c &&= 's'
|
||||
println(c)
|
|
@ -535,6 +535,28 @@ fn (mut g Gen) assign_stmt(node_ ast.AssignStmt) {
|
|||
op_overloaded = true
|
||||
}
|
||||
}
|
||||
|
||||
if left_sym.kind == .bool && right_sym.kind == .bool
|
||||
&& node.op in [.boolean_or_assign, .boolean_and_assign] {
|
||||
extracted_op := match node.op {
|
||||
.boolean_or_assign {
|
||||
'||'
|
||||
}
|
||||
.boolean_and_assign {
|
||||
'&&'
|
||||
}
|
||||
else {
|
||||
'unknown op'
|
||||
}
|
||||
}
|
||||
g.expr(left)
|
||||
g.write(' = ')
|
||||
g.expr(left)
|
||||
g.write(' ${extracted_op} ')
|
||||
g.expr(val)
|
||||
g.writeln(';')
|
||||
return
|
||||
}
|
||||
if right_sym.info is ast.FnType && is_decl {
|
||||
if is_inside_ternary {
|
||||
g.out.write_string(util.tabs(g.indent - g.inside_ternary))
|
||||
|
|
|
@ -872,6 +872,12 @@ pub fn (mut s Scanner) text_scan() token.Token {
|
|||
}
|
||||
}
|
||||
`&` {
|
||||
if nextc == `&` {
|
||||
if s.look_ahead(2) == `=` {
|
||||
s.pos += 2
|
||||
return s.new_token(.boolean_and_assign, '', 3)
|
||||
}
|
||||
}
|
||||
if nextc == `=` {
|
||||
s.pos++
|
||||
return s.new_token(.and_assign, '', 2)
|
||||
|
@ -885,6 +891,10 @@ pub fn (mut s Scanner) text_scan() token.Token {
|
|||
}
|
||||
`|` {
|
||||
if nextc == `|` {
|
||||
if s.look_ahead(2) == `=` {
|
||||
s.pos += 2
|
||||
return s.new_token(.boolean_or_assign, '', 3)
|
||||
}
|
||||
s.pos++
|
||||
return s.new_token(.logical_or, '', 2)
|
||||
}
|
||||
|
|
8
vlib/v/tests/bool_assign_operator_test.v
Normal file
8
vlib/v/tests/bool_assign_operator_test.v
Normal file
|
@ -0,0 +1,8 @@
|
|||
fn test_bool_assign_operator() {
|
||||
mut flag := true
|
||||
flag ||= false
|
||||
assert flag == true
|
||||
|
||||
flag &&= false
|
||||
assert flag == false
|
||||
}
|
|
@ -67,6 +67,8 @@ pub enum Kind {
|
|||
right_shift_assign // <<=
|
||||
left_shift_assign // >>=
|
||||
unsigned_right_shift_assign // >>>=
|
||||
boolean_and_assign // &&=
|
||||
boolean_or_assign // ||=
|
||||
lcbr // {
|
||||
rcbr // }
|
||||
lpar // (
|
||||
|
@ -186,7 +188,7 @@ pub enum AtKind {
|
|||
|
||||
pub const assign_tokens = [Kind.assign, .plus_assign, .minus_assign, .mult_assign, .div_assign,
|
||||
.xor_assign, .mod_assign, .or_assign, .and_assign, .right_shift_assign, .left_shift_assign,
|
||||
.unsigned_right_shift_assign]
|
||||
.unsigned_right_shift_assign, .boolean_and_assign, .boolean_or_assign]
|
||||
|
||||
pub const valid_at_tokens = ['@VROOT', '@VMODROOT', '@VEXEROOT', '@FN', '@METHOD', '@MOD', '@STRUCT',
|
||||
'@VEXE', '@FILE', '@LINE', '@COLUMN', '@VHASH', '@VCURRENTHASH', '@VMOD_FILE', '@VMODHASH',
|
||||
|
@ -261,6 +263,8 @@ fn build_token_str() []string {
|
|||
s[Kind.right_shift_assign] = '>>='
|
||||
s[Kind.unsigned_right_shift_assign] = '>>>='
|
||||
s[Kind.left_shift_assign] = '<<='
|
||||
s[Kind.boolean_or_assign] = '||='
|
||||
s[Kind.boolean_and_assign] = '&&='
|
||||
s[Kind.lcbr] = '{'
|
||||
s[Kind.rcbr] = '}'
|
||||
s[Kind.lpar] = '('
|
||||
|
@ -468,6 +472,8 @@ pub fn build_precedences() []Precedence {
|
|||
p[Kind.unsigned_right_shift_assign] = .assign
|
||||
p[Kind.mult_assign] = .assign
|
||||
p[Kind.xor_assign] = .assign
|
||||
p[Kind.boolean_or_assign] = .assign
|
||||
p[Kind.boolean_and_assign] = .assign
|
||||
p[Kind.key_in] = .in_as
|
||||
p[Kind.not_in] = .in_as
|
||||
p[Kind.key_as] = .in_as
|
||||
|
@ -583,6 +589,8 @@ pub fn kind_to_string(k Kind) string {
|
|||
.right_shift_assign { 'right_shift_assign' }
|
||||
.left_shift_assign { 'left_shift_assign' }
|
||||
.unsigned_right_shift_assign { 'unsigned_right_shift_assign' }
|
||||
.boolean_and_assign { 'boolean_and_assign' }
|
||||
.boolean_or_assign { 'boolean_or_assign' }
|
||||
.lcbr { 'lcbr' }
|
||||
.rcbr { 'rcbr' }
|
||||
.lpar { 'lpar' }
|
||||
|
@ -707,6 +715,8 @@ pub fn kind_from_string(s string) !Kind {
|
|||
'right_shift_assign' { .right_shift_assign }
|
||||
'left_shift_assign' { .left_shift_assign }
|
||||
'unsigned_right_shift_assign' { .unsigned_right_shift_assign }
|
||||
'boolean_and_assign' { .boolean_and_assign }
|
||||
'boolean_or_assign' { .boolean_or_assign }
|
||||
'lcbr' { .lcbr }
|
||||
'rcbr' { .rcbr }
|
||||
'lpar' { .lpar }
|
||||
|
@ -793,6 +803,8 @@ pub fn assign_op_to_infix_op(op Kind) Kind {
|
|||
.right_shift_assign { .right_shift }
|
||||
.unsigned_right_shift_assign { .unsigned_right_shift }
|
||||
.left_shift_assign { .left_shift }
|
||||
.boolean_and_assign { .and }
|
||||
.boolean_or_assign { .logical_or }
|
||||
else { ._end_ }
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue