compiler: Allow `or` usage when assigning to struct fields. (#2893)
parent
79a02a4c09
commit
6349bd33d3
|
@ -117,7 +117,7 @@ fn (p mut Parser) gen_handle_option_or_else(_typ, name string, fn_call_ph int) s
|
||||||
is_mut: false
|
is_mut: false
|
||||||
is_used: true
|
is_used: true
|
||||||
})
|
})
|
||||||
if is_assign {
|
if is_assign && !name.contains('.') { // don't initialize struct fields
|
||||||
p.genln('$typ $name;')
|
p.genln('$typ $name;')
|
||||||
}
|
}
|
||||||
p.genln('if (!$tmp .ok) {')
|
p.genln('if (!$tmp .ok) {')
|
||||||
|
|
|
@ -1361,7 +1361,9 @@ fn ($v.name mut $v.typ) $p.cur_fn.name (...) {
|
||||||
p.next()
|
p.next()
|
||||||
p.fspace()
|
p.fspace()
|
||||||
pos := p.cgen.cur_line.len
|
pos := p.cgen.cur_line.len
|
||||||
|
p.is_var_decl = true
|
||||||
expr_type := p.bool_expression()
|
expr_type := p.bool_expression()
|
||||||
|
p.is_var_decl = false
|
||||||
//if p.expected_type.starts_with('array_') {
|
//if p.expected_type.starts_with('array_') {
|
||||||
//p.warn('expecting array got $expr_type')
|
//p.warn('expecting array got $expr_type')
|
||||||
//}
|
//}
|
||||||
|
@ -1377,9 +1379,17 @@ fn ($v.name mut $v.typ) $p.cur_fn.name (...) {
|
||||||
typ := expr_type.replace('Option_', '')
|
typ := expr_type.replace('Option_', '')
|
||||||
p.cgen.resetln(left + 'opt_ok($expr, sizeof($typ))')
|
p.cgen.resetln(left + 'opt_ok($expr, sizeof($typ))')
|
||||||
}
|
}
|
||||||
|
else if expr_type.starts_with('Option_') &&
|
||||||
|
p.assigned_type == expr_type['Option_'.len..] && p.tok == .key_orelse
|
||||||
|
{
|
||||||
|
line := p.cgen.cur_line
|
||||||
|
vname := line[..pos].replace('=','') // TODO cgen line hack
|
||||||
|
p.cgen.resetln(line.replace(line[..line.index('=')+1], ''))
|
||||||
|
p.gen_handle_option_or_else(expr_type, vname, ph)
|
||||||
|
}
|
||||||
else if expr_type[0]==`[` {
|
else if expr_type[0]==`[` {
|
||||||
// assignment to a fixed_array `mut a:=[3]int a=[1,2,3]!!`
|
// assignment to a fixed_array `mut a:=[3]int a=[1,2,3]!!`
|
||||||
expr := p.cgen.cur_line[pos..].all_after('{').all_before('}')
|
expr := p.cgen.cur_line[pos..].all_after('{').all_before('}') // TODO cgen line hack
|
||||||
left := p.cgen.cur_line[..pos].all_before('=')
|
left := p.cgen.cur_line[..pos].all_before('=')
|
||||||
cline_pos := p.cgen.cur_line[pos..]
|
cline_pos := p.cgen.cur_line[pos..]
|
||||||
etype := cline_pos.all_before(' {')
|
etype := cline_pos.all_before(' {')
|
||||||
|
|
|
@ -75,6 +75,40 @@ fn foo_ok() ?int {
|
||||||
return 777
|
return 777
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn foo_str() ?string {
|
||||||
|
return 'something'
|
||||||
|
}
|
||||||
|
|
||||||
fn test_q() {
|
fn test_q() {
|
||||||
//assert foo_ok()? == true
|
//assert foo_ok()? == true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Person {
|
||||||
|
mut:
|
||||||
|
name string
|
||||||
|
age int
|
||||||
|
title ?string
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_field_or() {
|
||||||
|
name := foo_str() or {
|
||||||
|
'nada'
|
||||||
|
}
|
||||||
|
assert name == 'something'
|
||||||
|
|
||||||
|
mut p := Person {}
|
||||||
|
p.name = foo_str() or {
|
||||||
|
'nothing'
|
||||||
|
}
|
||||||
|
assert p.name == 'something'
|
||||||
|
|
||||||
|
p.age = foo_ok() or {
|
||||||
|
panic('no age')
|
||||||
|
}
|
||||||
|
assert p.age == 777
|
||||||
|
|
||||||
|
mytitle := p.title or {
|
||||||
|
'default'
|
||||||
|
}
|
||||||
|
assert mytitle == 'default'
|
||||||
|
}
|
Loading…
Reference in New Issue