From f1d5f8e2bf98e99d732f6c17ac166f50e0f528e4 Mon Sep 17 00:00:00 2001 From: luoheng <1301089462@qq.com> Date: Sat, 21 Sep 2019 23:21:45 +0800 Subject: [PATCH] parser: allow `!` only with bools --- compiler/msvc.v | 2 +- compiler/parser.v | 81 +++++++++++++++++++++++----------------- compiler/repl.v | 2 +- vlib/gl/gl.v | 2 +- vlib/net/urllib/urllib.v | 2 +- 5 files changed, 50 insertions(+), 39 deletions(-) diff --git a/compiler/msvc.v b/compiler/msvc.v index e5e4350e0f..b61e071637 100644 --- a/compiler/msvc.v +++ b/compiler/msvc.v @@ -45,7 +45,7 @@ fn find_windows_kit_internal(key RegKey, versions []string) ?string { alloc_length := (required_bytes + 2) mut value := &u16(malloc(alloc_length)) - if !value { + if isnil(value) { continue } diff --git a/compiler/parser.v b/compiler/parser.v index f616f7bf44..f06fad147e 100644 --- a/compiler/parser.v +++ b/compiler/parser.v @@ -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 fn (p mut Parser) expression() string { if p.scanner.file_path.contains('test_test') { @@ -2086,7 +2124,7 @@ fn (p mut Parser) expression() string { p.print_tok() } ph := p.cgen.add_placeholder() - mut typ := p.term() + mut typ := p.indot_expr() is_str := typ=='string' is_ustr := typ=='ustring' // `a << b` ==> `array_push(&a, b)` @@ -2119,43 +2157,12 @@ fn (p mut Parser) expression() string { 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 { p.next() p.gen(' >> ') p.check_types(p.expression(), typ) 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 || p.tok == .xor { @@ -2261,8 +2268,12 @@ fn (p mut Parser) unary() string { case Token.not: p.gen('!') p.check(.not) - typ = 'bool' - p.bool_expression() + // typ should be bool type + typ = p.indot_expr() + if typ != 'bool' { + p.error('operator ! requires bool type, not `$typ`') + } + case Token.bit_not: p.gen('~') p.check(.bit_not) @@ -2313,7 +2324,7 @@ fn (p mut Parser) factor() string { p.fgen('sizeof(') p.next() p.check(.lpar) - mut sizeof_typ := p.get_type() + mut sizeof_typ := p.get_type() p.check(.rpar) p.gen('$sizeof_typ)') p.fgen('$sizeof_typ)') diff --git a/compiler/repl.v b/compiler/repl.v index a6c21c48e3..9ce19bb70b 100644 --- a/compiler/repl.v +++ b/compiler/repl.v @@ -146,7 +146,7 @@ fn run_repl() []string { cerror(err) return []string } - if !func_call && !s.exit_code { + if !func_call && s.exit_code == 0 { for r.temp_lines.len > 0 { if !r.temp_lines[0].starts_with('print') { r.lines << r.temp_lines[0] diff --git a/vlib/gl/gl.v b/vlib/gl/gl.v index 34f370c2c8..25167cc8fe 100644 --- a/vlib/gl/gl.v +++ b/vlib/gl/gl.v @@ -10,7 +10,7 @@ module gl pub fn init_glad() { ok := C.gladLoadGL() - if !ok { + if isnil(ok) { println('Failed to initialize glad OpenGL context') exit(1) } diff --git a/vlib/net/urllib/urllib.v b/vlib/net/urllib/urllib.v index 0bff386b07..127e789103 100644 --- a/vlib/net/urllib/urllib.v +++ b/vlib/net/urllib/urllib.v @@ -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) authority := parts[0] rest = parts[1]