mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
parser: fix a & b == c
precedence
This commit is contained in:
parent
e957fd6f30
commit
f724a956b3
@ -66,6 +66,15 @@ fn test_str_methods() {
|
|||||||
assert u64(-1).str() == '18446744073709551615'
|
assert u64(-1).str() == '18446744073709551615'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn test_and() {
|
||||||
|
c:=[1,2,3,4,5]
|
||||||
|
assert c[0] & 1 != 0
|
||||||
|
assert c[1] & 1 == 0
|
||||||
|
assert c[2] & 1 != 0
|
||||||
|
assert c[3] & 1 == 0
|
||||||
|
assert c[4] & 1 != 0
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
fn test_cmp() {
|
fn test_cmp() {
|
||||||
assert 1 ≠ 2
|
assert 1 ≠ 2
|
||||||
|
@ -32,7 +32,7 @@ fn (p mut Parser) bool_expression() string {
|
|||||||
p.check_types(p.bterm(), typ)
|
p.check_types(p.bterm(), typ)
|
||||||
if typ != 'bool' {
|
if typ != 'bool' {
|
||||||
p.error('logical operators `&&` and `||` require booleans')
|
p.error('logical operators `&&` and `||` require booleans')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if typ == '' {
|
if typ == '' {
|
||||||
println('curline:')
|
println('curline:')
|
||||||
@ -162,7 +162,7 @@ fn (p mut Parser) name_expr() string {
|
|||||||
mut name := p.lit
|
mut name := p.lit
|
||||||
|
|
||||||
// generic type check
|
// generic type check
|
||||||
if name in p.cur_fn.dispatch_of.inst.keys() {
|
if name in p.cur_fn.dispatch_of.inst.keys() {
|
||||||
name = p.cur_fn.dispatch_of.inst[name]
|
name = p.cur_fn.dispatch_of.inst[name]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -227,7 +227,7 @@ fn (p mut Parser) name_expr() string {
|
|||||||
!p.table.known_fn(name) && !p.table.known_const(name) && !is_c
|
!p.table.known_fn(name) && !p.table.known_const(name) && !is_c
|
||||||
{
|
{
|
||||||
name = p.prepend_mod(name)
|
name = p.prepend_mod(name)
|
||||||
}
|
}
|
||||||
// re-check
|
// re-check
|
||||||
if p.known_var_check_new_var(name) {
|
if p.known_var_check_new_var(name) {
|
||||||
return p.get_var_type(name, ptr, deref_nr)
|
return p.get_var_type(name, ptr, deref_nr)
|
||||||
@ -269,7 +269,7 @@ fn (p mut Parser) name_expr() string {
|
|||||||
// `if color == .red` is enough
|
// `if color == .red` is enough
|
||||||
// no need in `if color == Color.red`
|
// no need in `if color == Color.red`
|
||||||
p.warn('`${enum_type.name}.$val` is unnecessary, use `.$val`')
|
p.warn('`${enum_type.name}.$val` is unnecessary, use `.$val`')
|
||||||
}
|
}
|
||||||
// println('enum val $val')
|
// println('enum val $val')
|
||||||
p.gen(mod_gen_name(enum_type.mod) + '__' + enum_type.name + '_' + val)// `color = main__Color_green`
|
p.gen(mod_gen_name(enum_type.mod) + '__' + enum_type.name + '_' + val)// `color = main__Color_green`
|
||||||
p.next()
|
p.next()
|
||||||
@ -286,7 +286,7 @@ fn (p mut Parser) name_expr() string {
|
|||||||
return p.get_const_type(name, ptr)
|
return p.get_const_type(name, ptr)
|
||||||
}
|
}
|
||||||
// TODO: V script? Try os module.
|
// TODO: V script? Try os module.
|
||||||
// Function (not method, methods are handled in `.dot()`)
|
// Function (not method, methods are handled in `.dot()`)
|
||||||
mut f := p.table.find_fn_is_script(name, p.v_script) or {
|
mut f := p.table.find_fn_is_script(name, p.v_script) or {
|
||||||
// First pass, the function can be defined later.
|
// First pass, the function can be defined later.
|
||||||
if p.first_pass() {
|
if p.first_pass() {
|
||||||
@ -336,7 +336,7 @@ fn (p mut Parser) name_expr() string {
|
|||||||
if p.tok == .question {
|
if p.tok == .question {
|
||||||
// `files := os.ls('.')?`
|
// `files := os.ls('.')?`
|
||||||
return p.gen_handle_question_suffix(f, fn_call_ph)
|
return p.gen_handle_question_suffix(f, fn_call_ph)
|
||||||
}
|
}
|
||||||
else if !p.is_var_decl && is_or_else {
|
else if !p.is_var_decl && is_or_else {
|
||||||
f.typ = p.gen_handle_option_or_else(f.typ, '', fn_call_ph)
|
f.typ = p.gen_handle_option_or_else(f.typ, '', fn_call_ph)
|
||||||
}
|
}
|
||||||
@ -471,16 +471,24 @@ fn (p mut Parser) expression() string {
|
|||||||
}
|
}
|
||||||
if is_str && tok_op != .plus {
|
if is_str && tok_op != .plus {
|
||||||
p.error('strings only support `+` operator')
|
p.error('strings only support `+` operator')
|
||||||
}
|
}
|
||||||
expr_type := p.term()
|
expr_type := p.term()
|
||||||
if (tok_op in [.pipe, .amp, .xor]) && !(is_integer_type(expr_type) &&
|
mut open := false
|
||||||
is_integer_type(typ)) {
|
if tok_op in [.pipe, .amp, .xor] {
|
||||||
p.error('operator ${tok_op.str()} is defined only on integer types')
|
if !(is_integer_type(expr_type) && is_integer_type(typ)) {
|
||||||
}
|
p.error('operator ${tok_op.str()} is defined only on integer types')
|
||||||
|
}
|
||||||
|
p.cgen.set_placeholder(ph, '(')
|
||||||
|
open = true
|
||||||
|
}
|
||||||
p.check_types(expr_type, typ)
|
p.check_types(expr_type, typ)
|
||||||
if (is_str || is_ustr) && tok_op == .plus && !p.is_js {
|
if (is_str || is_ustr) && tok_op == .plus && !p.is_js {
|
||||||
p.gen(')')
|
p.gen(')')
|
||||||
}
|
}
|
||||||
|
if open {
|
||||||
|
p.gen(')')
|
||||||
|
|
||||||
|
}
|
||||||
// Make sure operators are used with correct types
|
// Make sure operators are used with correct types
|
||||||
if !p.pref.translated && !is_str && !is_ustr && !is_num {
|
if !p.pref.translated && !is_str && !is_ustr && !is_num {
|
||||||
T := p.table.find_type(typ)
|
T := p.table.find_type(typ)
|
||||||
@ -546,14 +554,14 @@ fn (p mut Parser) term() string {
|
|||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if is_mod {
|
if is_mod {
|
||||||
if !(is_integer_type(expr_type) && is_integer_type(typ)) {
|
if !(is_integer_type(expr_type) && is_integer_type(typ)) {
|
||||||
p.error('operator `mod` requires integer types')
|
p.error('operator `mod` requires integer types')
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
p.check_types(expr_type, typ)
|
p.check_types(expr_type, typ)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return typ
|
return typ
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user