compiler: Allow `or` usage when assigning to struct fields. (#2893)

pull/2899/head^2
ʇʞʌp 2019-11-25 22:07:35 -08:00 committed by Alexander Medvednikov
parent 79a02a4c09
commit 6349bd33d3
3 changed files with 47 additions and 3 deletions

View File

@ -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_used: true
})
if is_assign {
if is_assign && !name.contains('.') { // don't initialize struct fields
p.genln('$typ $name;')
}
p.genln('if (!$tmp .ok) {')

View File

@ -1361,7 +1361,9 @@ fn ($v.name mut $v.typ) $p.cur_fn.name (...) {
p.next()
p.fspace()
pos := p.cgen.cur_line.len
p.is_var_decl = true
expr_type := p.bool_expression()
p.is_var_decl = false
//if p.expected_type.starts_with('array_') {
//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_', '')
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]==`[` {
// 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('=')
cline_pos := p.cgen.cur_line[pos..]
etype := cline_pos.all_before(' {')

View File

@ -75,6 +75,40 @@ fn foo_ok() ?int {
return 777
}
fn foo_str() ?string {
return 'something'
}
fn test_q() {
//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'
}