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

parser: allow ! only with bools

This commit is contained in:
luoheng 2019-09-21 23:21:45 +08:00 committed by Alexander Medvednikov
parent c01edc650d
commit f1d5f8e2bf
5 changed files with 50 additions and 39 deletions

View File

@ -45,7 +45,7 @@ fn find_windows_kit_internal(key RegKey, versions []string) ?string {
alloc_length := (required_bytes + 2) alloc_length := (required_bytes + 2)
mut value := &u16(malloc(alloc_length)) mut value := &u16(malloc(alloc_length))
if !value { if isnil(value) {
continue continue
} }

View File

@ -2079,6 +2079,44 @@ struct IndexCfg {
} }
// in and dot have higher priority than `!`
fn (p mut Parser) indot_expr() string {
ph := p.cgen.add_placeholder()
mut typ := p.term()
if p.tok == .dot {
for p.tok == .dot {
typ = p.dot(typ, ph)
}
}
// `a in [1, 2, 3]`
// `key in map`
if p.tok == .key_in {
p.fgen(' ')
p.check(.key_in)
p.fgen(' ')
p.gen('), ')
arr_typ := p.expression()
is_map := arr_typ.starts_with('map_')
if !arr_typ.starts_with('array_') && !is_map {
p.error('`in` requires an array/map')
}
T := p.table.find_type(arr_typ)
if !is_map && !T.has_method('contains') {
p.error('$arr_typ has no method `contains`')
}
// `typ` is element's type
if is_map {
p.cgen.set_placeholder(ph, '_IN_MAP( (')
}
else {
p.cgen.set_placeholder(ph, '_IN($typ, (')
}
p.gen(')')
return 'bool'
}
return typ
}
// returns resulting type // returns resulting type
fn (p mut Parser) expression() string { fn (p mut Parser) expression() string {
if p.scanner.file_path.contains('test_test') { if p.scanner.file_path.contains('test_test') {
@ -2086,7 +2124,7 @@ fn (p mut Parser) expression() string {
p.print_tok() p.print_tok()
} }
ph := p.cgen.add_placeholder() ph := p.cgen.add_placeholder()
mut typ := p.term() mut typ := p.indot_expr()
is_str := typ=='string' is_str := typ=='string'
is_ustr := typ=='ustring' is_ustr := typ=='ustring'
// `a << b` ==> `array_push(&a, b)` // `a << b` ==> `array_push(&a, b)`
@ -2119,43 +2157,12 @@ fn (p mut Parser) expression() string {
return 'int' return 'int'
} }
} }
// `a in [1, 2, 3]`
// `key in map`
if p.tok == .key_in {
p.fgen(' ')
p.check(.key_in)
p.fgen(' ')
p.gen('), ')
arr_typ := p.expression()
is_map := arr_typ.starts_with('map_')
if !arr_typ.starts_with('array_') && !is_map {
p.error('`in` requires an array/map')
}
T := p.table.find_type(arr_typ)
if !is_map && !T.has_method('contains') {
p.error('$arr_typ has no method `contains`')
}
// `typ` is element's type
if is_map {
p.cgen.set_placeholder(ph, '_IN_MAP( (')
}
else {
p.cgen.set_placeholder(ph, '_IN($typ, (')
}
p.gen(')')
return 'bool'
}
if p.tok == .righ_shift { if p.tok == .righ_shift {
p.next() p.next()
p.gen(' >> ') p.gen(' >> ')
p.check_types(p.expression(), typ) p.check_types(p.expression(), typ)
return 'int' return 'int'
} }
if p.tok == .dot {
for p.tok == .dot {
typ = p.dot(typ, ph)
}
}
// + - | ^ // + - | ^
for p.tok == .plus || p.tok == .minus || p.tok == .pipe || p.tok == .amp || for p.tok == .plus || p.tok == .minus || p.tok == .pipe || p.tok == .amp ||
p.tok == .xor { p.tok == .xor {
@ -2261,8 +2268,12 @@ fn (p mut Parser) unary() string {
case Token.not: case Token.not:
p.gen('!') p.gen('!')
p.check(.not) p.check(.not)
typ = 'bool' // typ should be bool type
p.bool_expression() typ = p.indot_expr()
if typ != 'bool' {
p.error('operator ! requires bool type, not `$typ`')
}
case Token.bit_not: case Token.bit_not:
p.gen('~') p.gen('~')
p.check(.bit_not) p.check(.bit_not)
@ -2313,7 +2324,7 @@ fn (p mut Parser) factor() string {
p.fgen('sizeof(') p.fgen('sizeof(')
p.next() p.next()
p.check(.lpar) p.check(.lpar)
mut sizeof_typ := p.get_type() mut sizeof_typ := p.get_type()
p.check(.rpar) p.check(.rpar)
p.gen('$sizeof_typ)') p.gen('$sizeof_typ)')
p.fgen('$sizeof_typ)') p.fgen('$sizeof_typ)')

View File

@ -146,7 +146,7 @@ fn run_repl() []string {
cerror(err) cerror(err)
return []string return []string
} }
if !func_call && !s.exit_code { if !func_call && s.exit_code == 0 {
for r.temp_lines.len > 0 { for r.temp_lines.len > 0 {
if !r.temp_lines[0].starts_with('print') { if !r.temp_lines[0].starts_with('print') {
r.lines << r.temp_lines[0] r.lines << r.temp_lines[0]

View File

@ -10,7 +10,7 @@ module gl
pub fn init_glad() { pub fn init_glad() {
ok := C.gladLoadGL() ok := C.gladLoadGL()
if !ok { if isnil(ok) {
println('Failed to initialize glad OpenGL context') println('Failed to initialize glad OpenGL context')
exit(1) exit(1)
} }

View File

@ -513,7 +513,7 @@ fn _parse(rawurl string, via_request bool) ?URL {
} }
} }
if (url.scheme != '' || !via_request && !rest.starts_with('///')) && rest.starts_with('//') { if ((url.scheme != '' || !via_request) && !rest.starts_with('///')) && rest.starts_with('//') {
parts := split(rest.right(2), '/', false) parts := split(rest.right(2), '/', false)
authority := parts[0] authority := parts[0]
rest = parts[1] rest = parts[1]