diff --git a/vlib/compiler/expression.v b/vlib/compiler/expression.v index 21b159e75a..538e1b1f73 100644 --- a/vlib/compiler/expression.v +++ b/vlib/compiler/expression.v @@ -329,17 +329,7 @@ fn (p mut Parser) name_expr() string { is_or_else := p.tok == .key_orelse if p.tok == .question { // `files := os.ls('.')?` - if p.cur_fn.name != 'main__main' { - p.error('`func()?` syntax can only be used inside `fn main()` for now') - } - p.next() - tmp := p.get_tmp() - p.cgen.set_placeholder(fn_call_ph, '$f.typ $tmp = ') - p.genln(';') - p.genln('if (!${tmp}.ok) v_panic(${tmp}.error);') - typ := f.typ[7..] // option_xxx - p.gen('*($typ*) ${tmp}.data;') - return typ + return p.gen_handle_question_suffix(f, fn_call_ph) } else if !p.is_var_decl && is_or_else { f.typ = p.gen_handle_option_or_else(f.typ, '', fn_call_ph) diff --git a/vlib/compiler/gen_c.v b/vlib/compiler/gen_c.v index a3e6e67f88..3ce761219e 100644 --- a/vlib/compiler/gen_c.v +++ b/vlib/compiler/gen_c.v @@ -144,6 +144,21 @@ fn (p mut Parser) gen_handle_option_or_else(_typ, name string, fn_call_ph int) s return typ } +// `files := os.ls('.')?` +fn (p mut Parser) gen_handle_question_suffix(f Fn, ph int) string { + if p.cur_fn.name != 'main__main' { + p.error('`func()?` syntax can only be used inside `fn main()` for now') + } + p.check(.question) + tmp := p.get_tmp() + p.cgen.set_placeholder(ph, '$f.typ $tmp = ') + p.genln(';') + p.genln('if (!${tmp}.ok) v_panic(${tmp}.error);') + typ := f.typ[7..] // option_xxx + p.gen('*($typ*) ${tmp}.data;') + return typ +} + fn types_to_c(types []Type, table &Table) string { mut sb := strings.new_builder(10) for t in types { diff --git a/vlib/compiler/parser.v b/vlib/compiler/parser.v index f530c9dd27..d35b2fefcb 100644 --- a/vlib/compiler/parser.v +++ b/vlib/compiler/parser.v @@ -1868,7 +1868,11 @@ struct $typ.name { p.fn_call(mut method, method_ph, '', str_typ) // optional method call `a.method() or {}`, no return assignment is_or_else := p.tok == .key_orelse - if !p.is_var_decl && is_or_else { + if p.tok == .question { + // `files := os.ls('.')?` + return p.gen_handle_question_suffix(method, method_ph) + } + else if !p.is_var_decl && is_or_else { method.typ = p.gen_handle_option_or_else(method.typ, '', method_ph) } else if !p.is_var_decl && !is_or_else && !p.inside_return_expr &&