require `else` in `match` statements

pull/3006/head
Alexander Medvednikov 2019-12-07 16:58:43 +03:00
parent a594e009f2
commit 2fb7fba856
11 changed files with 69 additions and 34 deletions

View File

@ -97,7 +97,7 @@ const (
pub fn (_str string) to_wide() &u16 { pub fn (_str string) to_wide() &u16 {
$if windows { $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) mut wstr := &u16(malloc((num_chars + 1) * 2)) // sizeof(wchar_t)
if !isnil(wstr) { if !isnil(wstr) {
C.MultiByteToWideChar(CP_UTF8, 0, _str.str, _str.len, wstr, num_chars) 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 { pub fn string_from_wide(_wstr &u16) string {
$if windows { $if windows {
wstr_len := int(C.wcslen(_wstr)) wstr_len := C.wcslen(_wstr)
return string_from_wide2(_wstr, wstr_len) return string_from_wide2(_wstr, wstr_len)
} $else { } $else {
return '' return ''
@ -120,11 +120,11 @@ pub fn string_from_wide(_wstr &u16) string {
pub fn string_from_wide2(_wstr &u16, len int) string { pub fn string_from_wide2(_wstr &u16, len int) string {
$if windows { $if windows {
num_chars := int(C.WideCharToMultiByte(CP_UTF8, 0, _wstr, len, 0, 0, 0, 0)) num_chars := C.WideCharToMultiByte(CP_UTF8, 0, _wstr, len, 0, 0, 0, 0))
mut str_to := &byte(malloc(num_chars + 1)) mut str_to := malloc(num_chars + 1)
if !isnil(str_to) { if !isnil(str_to) {
C.WideCharToMultiByte(CP_UTF8, 0, _wstr, len, str_to, num_chars, 0, 0) 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) return tos2(str_to)
} $else { } $else {

View File

@ -301,8 +301,9 @@ fn os_name_to_ifdef(name string) string {
'js' {return '_VJS' } 'js' {return '_VJS' }
'solaris'{ return '__sun' } 'solaris'{ return '__sun' }
'haiku' { return '__haiku__' } 'haiku' { return '__haiku__' }
else { verror('bad os ifdef name "$name"') }
} }
verror('bad os ifdef name "$name"') //verror('bad os ifdef name "$name"')
return '' return ''
} }

View File

@ -97,6 +97,7 @@ fn (p mut Parser) bterm() string {
.ge { p.cgen.set_placeholder(ph, 'string_ge(') } .ge { p.cgen.set_placeholder(ph, 'string_ge(') }
.gt { p.cgen.set_placeholder(ph, 'string_gt(') } .gt { p.cgen.set_placeholder(ph, 'string_gt(') }
.lt { p.cgen.set_placeholder(ph, 'string_lt(') } .lt { p.cgen.set_placeholder(ph, 'string_lt(') }
else { }
} }
} }
if is_ustr { if is_ustr {
@ -108,6 +109,7 @@ fn (p mut Parser) bterm() string {
.ge { p.cgen.set_placeholder(ph, 'ustring_ge(') } .ge { p.cgen.set_placeholder(ph, 'ustring_ge(') }
.gt { p.cgen.set_placeholder(ph, 'ustring_gt(') } .gt { p.cgen.set_placeholder(ph, 'ustring_gt(') }
.lt { p.cgen.set_placeholder(ph, 'ustring_lt(') } .lt { p.cgen.set_placeholder(ph, 'ustring_lt(') }
else { }
} }
} }
if is_float && p.cur_fn.name != 'f32_abs' && p.cur_fn.name != 'f64_abs' { 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(') } .ge { p.cgen.set_placeholder(ph, '${expr_type}_ge(') }
.gt { p.cgen.set_placeholder(ph, '${expr_type}_gt(') } .gt { p.cgen.set_placeholder(ph, '${expr_type}_gt(') }
.lt { p.cgen.set_placeholder(ph, '${expr_type}_lt(') } .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) } .mul { p.handle_operator('*', typ, 'op_mul', ph, T) }
.div { p.handle_operator('/', typ, 'op_div', ph, T) } .div { p.handle_operator('/', typ, 'op_div', ph, T) }
.mod { p.handle_operator('%', typ, 'op_mod', ph, T) } .mod { p.handle_operator('%', typ, 'op_mod', ph, T) }
else {}
} }
continue continue
} }

View File

@ -260,6 +260,7 @@ fn (table mut Table) fn_gen_name(f &Fn) string {
`*` { name = name.replace('*', 'op_mul') } `*` { name = name.replace('*', 'op_mul') }
`/` { name = name.replace('/', 'op_div') } `/` { name = name.replace('/', 'op_div') }
`%` { name = name.replace('%', 'op_mod') } `%` { name = name.replace('%', 'op_mod') }
else {}
} }
} }
} }
@ -606,24 +607,50 @@ fn type_default(typ string) string {
return '{0}' return '{0}'
} }
// Default values for other types are not needed because of mandatory initialization // Default values for other types are not needed because of mandatory initialization
match typ { match typ {
'bool'{ return '0'} 'bool'{ return '0'}
'string'{ return 'tos3("")'} 'string'{ return 'tos3("")'}
'i8'{ return '0'} 'i8'{ return '0'}
'i16'{ return '0'} 'i16'{ return '0'}
'i64'{ return '0'} 'i64'{ return '0'}
'u16'{ return '0'} 'u16'{ return '0'}
'u32'{ return '0'} 'u32'{ return '0'}
'u64'{ return '0'} 'u64'{ return '0'}
'byte'{ return '0'} 'byte'{ return '0'}
'int'{ return '0'} 'int'{ return '0'}
'rune'{ return '0'} 'rune'{ return '0'}
'f32'{ return '0.0'} 'f32'{ return '0.0'}
'f64'{ return '0.0'} 'f64'{ return '0.0'}
'byteptr'{ return '0'} 'byteptr'{ return '0'}
'voidptr'{ 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) { fn (p mut Parser) gen_array_push(ph int, typ, expr_type, tmp, elm_type string) {

View File

@ -27,11 +27,9 @@ fn (p mut Parser) match_statement(is_expr bool) string {
// stores typ of resulting variable // stores typ of resulting variable
mut res_typ := '' mut res_typ := ''
defer { defer {
p.check(.rcbr) p.check(.rcbr)
} }
for p.tok != .rcbr { for p.tok != .rcbr {
if p.tok == .key_else { if p.tok == .key_else {
p.check(.key_else) p.check(.key_else)
@ -206,10 +204,10 @@ fn (p mut Parser) match_statement(is_expr bool) string {
p.fgen_nl() p.fgen_nl()
} }
if is_expr { //if is_expr {
// we get here if no else found, ternary requires "else" branch // 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 p.returns = false // only get here when no default, so return is not guaranteed

View File

@ -1173,8 +1173,9 @@ pub fn os_from_string(os string) OS {
verror('use the flag `-cc msvc` to build using msvc') verror('use the flag `-cc msvc` to build using msvc')
} }
'haiku' { return .haiku } 'haiku' { return .haiku }
else { panic('bad os $os') }
} }
println('bad os $os') // todo panic? //println('bad os $os') // todo panic?
return .linux return .linux
} }

View File

@ -80,6 +80,7 @@ fn generate_vh(mod string) {
.key_const { g.generate_const() } .key_const { g.generate_const() }
.key_struct { g.generate_type() } .key_struct { g.generate_type() }
.key_type { g.generate_alias() } .key_type { g.generate_alias() }
else {}
} }
} }
} }

View File

@ -788,6 +788,7 @@ fn key_to_type_cat(tok TokenKind) TypeCategory {
.key_interface { return .interface_ } .key_interface { return .interface_ }
.key_struct { return .struct_ } .key_struct { return .struct_ }
.key_union { return .union_ } .key_union { return .union_ }
else {}
} }
verror('Unknown token: $tok') verror('Unknown token: $tok')
return .builtin return .builtin

View File

@ -637,6 +637,7 @@ fn (s mut Scanner) scan() ScanRes {
} }
return scan_res(.div, '') return scan_res(.div, '')
} }
else { }
} }
$if windows { $if windows {
if c == `\0` { if c == `\0` {

View File

@ -819,13 +819,13 @@ fn (table &Table) cgen_name_type_pair(name, typ string) string {
fn is_valid_int_const(val, typ string) bool { fn is_valid_int_const(val, typ string) bool {
x := val.int() x := val.int()
match typ { return match typ {
'byte' { return 0 <= x && x <= 255 } 'byte' { 0 <= x && x <= 255 }
'u16' { return 0 <= x && x <= 65535 } 'u16' { 0 <= x && x <= 65535 }
//case 'u32': return 0 <= x && x <= math.MaxU32 //case 'u32': return 0 <= x && x <= math.MaxU32
//case 'u64': return 0 <= x && x <= math.MaxU64 //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 'i16': return math.min_i16 <= x && x <= math.max_i16
case 'int': return math.min_i32 <= x && x <= math.max_i32 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': //case 'i64':
//x64 := val.i64() //x64 := val.i64()
//return i64(-(1<<63)) <= x64 && x64 <= i64((1<<63)-1) //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 { fn (p mut Parser) typ_to_fmt(typ string, level int) string {

View File

@ -464,6 +464,7 @@ pub fn sigint_to_signal_name(si int) string {
13 {return 'SIGPIPE'} 13 {return 'SIGPIPE'}
14 {return 'SIGALRM'} 14 {return 'SIGALRM'}
15 {return 'SIGTERM'} 15 {return 'SIGTERM'}
else { }
} }
$if linux { $if linux {
// From `man 7 signal` on linux: // From `man 7 signal` on linux: