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

View File

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

View File

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

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_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) {

View File

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

View File

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

View File

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

View File

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

View File

@ -637,6 +637,7 @@ fn (s mut Scanner) scan() ScanRes {
}
return scan_res(.div, '')
}
else { }
}
$if windows {
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 {
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 {

View File

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