force `()` in complex bool expressions: `(a && b) || c` instead of `a && b || c`

pull/1473/head
Alexander Medvednikov 2019-08-04 10:18:31 +02:00
parent 58117f1312
commit 350e13679c
7 changed files with 33 additions and 9 deletions

View File

@ -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()

View File

@ -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" ')
}

View File

@ -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)

View File

@ -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)
}

View File

@ -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 {

View File

@ -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
}

View File

@ -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)
}