From 2fb7fba8562e1c41a377ffc455a622eac5c2aade Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Sat, 7 Dec 2019 16:58:43 +0300 Subject: [PATCH] require `else` in `match` statements --- vlib/builtin/utf8.v | 10 +++--- vlib/compiler/cgen.v | 3 +- vlib/compiler/expression.v | 4 +++ vlib/compiler/gen_c.v | 61 +++++++++++++++++++++++++---------- vlib/compiler/if_match.v | 8 ++--- vlib/compiler/main.v | 3 +- vlib/compiler/module_header.v | 1 + vlib/compiler/parser.v | 1 + vlib/compiler/scanner.v | 1 + vlib/compiler/table.v | 10 +++--- vlib/os/os.v | 1 + 11 files changed, 69 insertions(+), 34 deletions(-) diff --git a/vlib/builtin/utf8.v b/vlib/builtin/utf8.v index e57e9f75e7..166ce91eb3 100644 --- a/vlib/builtin/utf8.v +++ b/vlib/builtin/utf8.v @@ -97,7 +97,7 @@ const ( pub fn (_str string) to_wide() &u16 { $if windows { - num_chars := int(C.MultiByteToWideChar(CP_UTF8, 0, _str.str, _str.len, 0, 0)) + num_chars := (C.MultiByteToWideChar(CP_UTF8, 0, _str.str, _str.len, 0, 0)) mut wstr := &u16(malloc((num_chars + 1) * 2)) // sizeof(wchar_t) if !isnil(wstr) { C.MultiByteToWideChar(CP_UTF8, 0, _str.str, _str.len, wstr, num_chars) @@ -111,7 +111,7 @@ pub fn (_str string) to_wide() &u16 { pub fn string_from_wide(_wstr &u16) string { $if windows { - wstr_len := int(C.wcslen(_wstr)) + wstr_len := C.wcslen(_wstr) return string_from_wide2(_wstr, wstr_len) } $else { return '' @@ -120,11 +120,11 @@ pub fn string_from_wide(_wstr &u16) string { pub fn string_from_wide2(_wstr &u16, len int) string { $if windows { - num_chars := int(C.WideCharToMultiByte(CP_UTF8, 0, _wstr, len, 0, 0, 0, 0)) - mut str_to := &byte(malloc(num_chars + 1)) + num_chars := C.WideCharToMultiByte(CP_UTF8, 0, _wstr, len, 0, 0, 0, 0)) + mut str_to := malloc(num_chars + 1) if !isnil(str_to) { C.WideCharToMultiByte(CP_UTF8, 0, _wstr, len, str_to, num_chars, 0, 0) - C.memset(&byte(str_to) + num_chars, 0, 1) + C.memset(str_to + num_chars, 0, 1) } return tos2(str_to) } $else { diff --git a/vlib/compiler/cgen.v b/vlib/compiler/cgen.v index 34d98ec876..793f6f27b9 100644 --- a/vlib/compiler/cgen.v +++ b/vlib/compiler/cgen.v @@ -301,8 +301,9 @@ fn os_name_to_ifdef(name string) string { 'js' {return '_VJS' } 'solaris'{ return '__sun' } 'haiku' { return '__haiku__' } + else { verror('bad os ifdef name "$name"') } } - verror('bad os ifdef name "$name"') + //verror('bad os ifdef name "$name"') return '' } diff --git a/vlib/compiler/expression.v b/vlib/compiler/expression.v index 1d30a30caa..6de9755ded 100644 --- a/vlib/compiler/expression.v +++ b/vlib/compiler/expression.v @@ -97,6 +97,7 @@ fn (p mut Parser) bterm() string { .ge { p.cgen.set_placeholder(ph, 'string_ge(') } .gt { p.cgen.set_placeholder(ph, 'string_gt(') } .lt { p.cgen.set_placeholder(ph, 'string_lt(') } + else { } } } if is_ustr { @@ -108,6 +109,7 @@ fn (p mut Parser) bterm() string { .ge { p.cgen.set_placeholder(ph, 'ustring_ge(') } .gt { p.cgen.set_placeholder(ph, 'ustring_gt(') } .lt { p.cgen.set_placeholder(ph, 'ustring_lt(') } + else { } } } if is_float && p.cur_fn.name != 'f32_abs' && p.cur_fn.name != 'f64_abs' { @@ -119,6 +121,7 @@ fn (p mut Parser) bterm() string { .ge { p.cgen.set_placeholder(ph, '${expr_type}_ge(') } .gt { p.cgen.set_placeholder(ph, '${expr_type}_gt(') } .lt { p.cgen.set_placeholder(ph, '${expr_type}_lt(') } + else { } } } } @@ -573,6 +576,7 @@ fn (p mut Parser) term() string { .mul { p.handle_operator('*', typ, 'op_mul', ph, T) } .div { p.handle_operator('/', typ, 'op_div', ph, T) } .mod { p.handle_operator('%', typ, 'op_mod', ph, T) } + else {} } continue } diff --git a/vlib/compiler/gen_c.v b/vlib/compiler/gen_c.v index 5baaf52489..5e8e2e92fd 100644 --- a/vlib/compiler/gen_c.v +++ b/vlib/compiler/gen_c.v @@ -260,6 +260,7 @@ fn (table mut Table) fn_gen_name(f &Fn) string { `*` { name = name.replace('*', 'op_mul') } `/` { name = name.replace('/', 'op_div') } `%` { name = name.replace('%', 'op_mod') } + else {} } } } @@ -606,24 +607,50 @@ fn type_default(typ string) string { return '{0}' } // Default values for other types are not needed because of mandatory initialization - match typ { - 'bool'{ return '0'} - 'string'{ return 'tos3("")'} - 'i8'{ return '0'} - 'i16'{ return '0'} - 'i64'{ return '0'} - 'u16'{ return '0'} - 'u32'{ return '0'} - 'u64'{ return '0'} - 'byte'{ return '0'} - 'int'{ return '0'} - 'rune'{ return '0'} - 'f32'{ return '0.0'} - 'f64'{ return '0.0'} - 'byteptr'{ return '0'} - 'voidptr'{ return '0'} + match typ { + 'bool'{ return '0'} + 'string'{ return 'tos3("")'} + 'i8'{ return '0'} + 'i16'{ return '0'} + 'i64'{ return '0'} + 'u16'{ return '0'} + 'u32'{ return '0'} + 'u64'{ return '0'} + 'byte'{ return '0'} + 'int'{ return '0'} + 'rune'{ return '0'} + 'f32'{ return '0.0'} + 'f64'{ return '0.0'} + 'byteptr'{ return '0'} + 'voidptr'{ return '0'} +else {} + } + return '{0}' + + + // TODO this results in + // error: expected a field designator, such as '.field = 4' + //- Empty ee= (Empty) { . = {0} } ; + /* + return match typ { + 'bool'{ '0'} + 'string'{ 'tos3("")'} + 'i8'{ '0'} + 'i16'{ '0'} + 'i64'{ '0'} + 'u16'{ '0'} + 'u32'{ '0'} + 'u64'{ '0'} + 'byte'{ '0'} + 'int'{ '0'} + 'rune'{ '0'} + 'f32'{ '0.0'} + 'f64'{ '0.0'} + 'byteptr'{ '0'} + 'voidptr'{ '0'} + else { '{0} '} } - return '{0}' + */ } fn (p mut Parser) gen_array_push(ph int, typ, expr_type, tmp, elm_type string) { diff --git a/vlib/compiler/if_match.v b/vlib/compiler/if_match.v index 7a7e069359..284e7fbbfa 100644 --- a/vlib/compiler/if_match.v +++ b/vlib/compiler/if_match.v @@ -27,11 +27,9 @@ fn (p mut Parser) match_statement(is_expr bool) string { // stores typ of resulting variable mut res_typ := '' - defer { p.check(.rcbr) } - for p.tok != .rcbr { if p.tok == .key_else { p.check(.key_else) @@ -206,10 +204,10 @@ fn (p mut Parser) match_statement(is_expr bool) string { p.fgen_nl() } - if is_expr { + //if is_expr { // we get here if no else found, ternary requires "else" branch - p.error('Match expression requires "else"') - } + p.warn('match expression requires `else`') + //} p.returns = false // only get here when no default, so return is not guaranteed diff --git a/vlib/compiler/main.v b/vlib/compiler/main.v index d851202fd5..1a928c40c0 100644 --- a/vlib/compiler/main.v +++ b/vlib/compiler/main.v @@ -1173,8 +1173,9 @@ pub fn os_from_string(os string) OS { verror('use the flag `-cc msvc` to build using msvc') } 'haiku' { return .haiku } + else { panic('bad os $os') } } - println('bad os $os') // todo panic? + //println('bad os $os') // todo panic? return .linux } diff --git a/vlib/compiler/module_header.v b/vlib/compiler/module_header.v index f4a65e39b9..8a0af95e64 100644 --- a/vlib/compiler/module_header.v +++ b/vlib/compiler/module_header.v @@ -80,6 +80,7 @@ fn generate_vh(mod string) { .key_const { g.generate_const() } .key_struct { g.generate_type() } .key_type { g.generate_alias() } + else {} } } } diff --git a/vlib/compiler/parser.v b/vlib/compiler/parser.v index 681fb8d31a..2e4c068d96 100644 --- a/vlib/compiler/parser.v +++ b/vlib/compiler/parser.v @@ -788,6 +788,7 @@ fn key_to_type_cat(tok TokenKind) TypeCategory { .key_interface { return .interface_ } .key_struct { return .struct_ } .key_union { return .union_ } + else {} } verror('Unknown token: $tok') return .builtin diff --git a/vlib/compiler/scanner.v b/vlib/compiler/scanner.v index 67b42f87e5..052a46ad48 100644 --- a/vlib/compiler/scanner.v +++ b/vlib/compiler/scanner.v @@ -637,6 +637,7 @@ fn (s mut Scanner) scan() ScanRes { } return scan_res(.div, '') } + else { } } $if windows { if c == `\0` { diff --git a/vlib/compiler/table.v b/vlib/compiler/table.v index 7ec10b122e..5d5ceadd0a 100644 --- a/vlib/compiler/table.v +++ b/vlib/compiler/table.v @@ -819,13 +819,13 @@ fn (table &Table) cgen_name_type_pair(name, typ string) string { fn is_valid_int_const(val, typ string) bool { x := val.int() - match typ { - 'byte' { return 0 <= x && x <= 255 } - 'u16' { return 0 <= x && x <= 65535 } + return match typ { + 'byte' { 0 <= x && x <= 255 } + 'u16' { 0 <= x && x <= 65535 } //case 'u32': return 0 <= x && x <= math.MaxU32 //case 'u64': return 0 <= x && x <= math.MaxU64 ////////////// - 'i8' { return -128 <= x && x <= 127 } + 'i8' { -128 <= x && x <= 127 } /* case 'i16': return math.min_i16 <= x && x <= math.max_i16 case 'int': return math.min_i32 <= x && x <= math.max_i32 @@ -833,8 +833,8 @@ fn is_valid_int_const(val, typ string) bool { //case 'i64': //x64 := val.i64() //return i64(-(1<<63)) <= x64 && x64 <= i64((1<<63)-1) + else { true } } - return true } fn (p mut Parser) typ_to_fmt(typ string, level int) string { diff --git a/vlib/os/os.v b/vlib/os/os.v index 5831fe300d..31644f9cb4 100644 --- a/vlib/os/os.v +++ b/vlib/os/os.v @@ -464,6 +464,7 @@ pub fn sigint_to_signal_name(si int) string { 13 {return 'SIGPIPE'} 14 {return 'SIGALRM'} 15 {return 'SIGTERM'} + else { } } $if linux { // From `man 7 signal` on linux: