From 350e13679cd0a27180c8344380db2373d3e86c06 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Sun, 4 Aug 2019 10:18:31 +0200 Subject: [PATCH] force `()` in complex bool expressions: `(a && b) || c` instead of `a && b || c` --- compiler/fn.v | 7 ++++--- compiler/main.v | 2 +- compiler/parser.v | 15 +++++++++++++++ compiler/scanner.v | 2 +- compiler/table.v | 8 ++++---- compiler/tests/fn_test.v | 4 ++++ vlib/builtin/int_test.v | 4 ++++ 7 files changed, 33 insertions(+), 9 deletions(-) diff --git a/compiler/fn.v b/compiler/fn.v index dabd404663..daae71da7a 100644 --- a/compiler/fn.v +++ b/compiler/fn.v @@ -354,9 +354,10 @@ fn (p mut Parser) fn_decl() { if p.tok == .gt && p.prev_tok == .name && p.prev_tok2 == .lt && p.scanner.text[p.scanner.pos-1] != `T` { p.scanner.pos -= 3 - for p.scanner.pos > 0 && is_name_char(p.scanner.text[p.scanner.pos]) || p.scanner.text[p.scanner.pos] == `.` || - p.scanner.text[p.scanner.pos] == `<` { - p.scanner.pos-- + for p.scanner.pos > 0 && (is_name_char(p.scanner.text[p.scanner.pos]) || + p.scanner.text[p.scanner.pos] == `.` || + p.scanner.text[p.scanner.pos] == `<` ) { + p.scanner.pos-- } p.scanner.pos-- p.next() diff --git a/compiler/main.v b/compiler/main.v index 37352b162d..8158e0a918 100644 --- a/compiler/main.v +++ b/compiler/main.v @@ -332,7 +332,7 @@ void init_consts();') } // TODO remove ugly .c include once V has its own json parser // Embed cjson either in embedvlib or in json.o - if imports_json && v.pref.build_mode == .embed_vlib || + if (imports_json && v.pref.build_mode == .embed_vlib) || (v.pref.build_mode == .build && v.out_name.contains('json.o')) { //cgen.genln('#include "cJSON.c" ') } diff --git a/compiler/parser.v b/compiler/parser.v index 1b3fabf2a2..d9e44a2bd0 100644 --- a/compiler/parser.v +++ b/compiler/parser.v @@ -1312,10 +1312,25 @@ fn (p mut Parser) var_decl() { p.var_decl_name = '' } +const ( + and_or_error = 'use `()` to make the boolean expression clear\n' + +'for example: `(a && b) || c` instead of `a && b || c`' +) + fn (p mut Parser) bool_expression() string { tok := p.tok typ := p.bterm() + mut got_and := false // to catch `a && b || c` in one expression without () + mut got_or := false for p.tok == .and || p.tok == .logical_or { + if p.tok == .and { + got_and = true + if got_or { p.error(and_or_error) } + } + if p.tok == .logical_or { + got_or = true + if got_and { p.error(and_or_error) } + } p.gen(' ${p.tok.str()} ') p.check_space(p.tok) p.check_types(p.bterm(), typ) diff --git a/compiler/scanner.v b/compiler/scanner.v index ed76c57194..392484ed2d 100644 --- a/compiler/scanner.v +++ b/compiler/scanner.v @@ -282,7 +282,7 @@ fn (s mut Scanner) scan() ScanRes { return scan_res(.name, name) } // `123`, `.123` - else if c.is_digit() || c == `.` && nextc.is_digit() { + else if c.is_digit() || (c == `.` && nextc.is_digit()) { num := s.ident_number() return scan_res(.number, num) } diff --git a/compiler/table.v b/compiler/table.v index df389c09cd..9d0f197f2d 100644 --- a/compiler/table.v +++ b/compiler/table.v @@ -117,16 +117,16 @@ fn (t &Table) debug_fns() string { // fn (types array_Type) print_to_file(f string) { // } const ( - NUMBER_TYPES = ['number', 'int', 'i8', 'u8', 'i16', 'u16', 'i32', 'u32', 'byte', 'i64', 'u64', 'f32', 'f64'] - FLOAT_TYPES = ['f32', 'f64'] + number_types = ['number', 'int', 'i8', 'u8', 'i16', 'u16', 'i32', 'u32', 'byte', 'i64', 'u64', 'f32', 'f64'] + float_types = ['f32', 'f64'] ) fn is_number_type(typ string) bool { - return NUMBER_TYPES.contains(typ) + return typ in number_types } fn is_float_type(typ string) bool { - return FLOAT_TYPES.contains(typ) + return typ in float_types } fn is_primitive_type(typ string) bool { diff --git a/compiler/tests/fn_test.v b/compiler/tests/fn_test.v index 2505f8f440..45498c0c7d 100644 --- a/compiler/tests/fn_test.v +++ b/compiler/tests/fn_test.v @@ -106,6 +106,10 @@ fn test_mut_ptr() { assert buf[0] == 77 } +fn test_high_fn(f fn(int) int) { + +} + fn test_fns() { // no asserts for now, just test function declarations above } diff --git a/vlib/builtin/int_test.v b/vlib/builtin/int_test.v index 138871618b..b2f669b074 100644 --- a/vlib/builtin/int_test.v +++ b/vlib/builtin/int_test.v @@ -1,7 +1,11 @@ const ( a = 3 + u = u64(1) ) fn test_const() { + b := (true && true) || false + assert b == true assert a == 3 + assert u == u64(1) }