From 52ccdd747f8751a1122c9774d349b54270232157 Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Fri, 4 Dec 2020 12:44:16 +0200 Subject: [PATCH] cgen: allow for `const ( x = opt() ? )` --- vlib/regex/simple_const_regex_test.v | 17 ++++++++++++++++ vlib/v/gen/cgen.v | 17 +++++++++++++++- vlib/v/tests/const_can_use_optionals_test.v | 22 +++++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 vlib/regex/simple_const_regex_test.v create mode 100644 vlib/v/tests/const_can_use_optionals_test.v diff --git a/vlib/regex/simple_const_regex_test.v b/vlib/regex/simple_const_regex_test.v new file mode 100644 index 0000000000..7ffe31c7e8 --- /dev/null +++ b/vlib/regex/simple_const_regex_test.v @@ -0,0 +1,17 @@ +import regex + +const ( + a_or_b = regex.regex_opt('a|b') ? +) + +fn f(s string) bool { + mut re := a_or_b + start, _ := re.match_string(s) + return start != -1 +} + +fn test_const_regex_works() { + assert f('a') == true + assert f('b') == true + assert f('c') == false +} diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index ecebdd9597..11d724b1ca 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -726,6 +726,10 @@ pub fn (mut g Gen) new_tmp_var() string { return '_t$g.tmp_count' } +pub fn (mut g Gen) current_tmp_var() string { + return '_t$g.tmp_count' +} + /* pub fn (mut g Gen) new_tmp_var2() string { g.tmp_count2++ @@ -4125,6 +4129,14 @@ fn (mut g Gen) const_decl(node ast.ConstDecl) { g.stringliterals.writeln('\t_const_$name = $val;') } } + ast.CallExpr { + if val.starts_with('Option_') { + g.inits[field.mod].writeln(val) + g.const_decl_init_later(field.mod, name, g.current_tmp_var(), field.typ) + } else { + g.const_decl_init_later(field.mod, name, val, field.typ) + } + } else { g.const_decl_init_later(field.mod, name, val, field.typ) } @@ -5086,7 +5098,7 @@ fn (mut g Gen) or_block(var_name string, or_block ast.OrExpr, return_type table. g.stmts(stmts) } } else if or_block.kind == .propagate { - if g.file.mod.name == 'main' && g.fn_decl.name == 'main.main' { + if g.file.mod.name == 'main' && (isnil(g.fn_decl) || g.fn_decl.name == 'main.main') { // In main(), an `opt()?` call is sugar for `opt() or { panic(err) }` if g.pref.is_debug { paline, pafile, pamod, pafn := g.panic_debug_info(or_block.pos) @@ -5849,6 +5861,9 @@ fn (mut g Gen) interface_call(typ table.Type, interface_type table.Type) { fn (mut g Gen) panic_debug_info(pos token.Position) (int, string, string, string) { paline := pos.line_nr + 1 + if isnil(g.fn_decl) { + return paline, '', 'main', 'C._vinit' + } pafile := g.fn_decl.file.replace('\\', '/') pafn := g.fn_decl.name.after('.') pamod := g.fn_decl.modname() diff --git a/vlib/v/tests/const_can_use_optionals_test.v b/vlib/v/tests/const_can_use_optionals_test.v new file mode 100644 index 0000000000..c8d5a9c236 --- /dev/null +++ b/vlib/v/tests/const_can_use_optionals_test.v @@ -0,0 +1,22 @@ +const ( + aaa = iopt() ? + bbb = sopt() ? +) + +fn iopt() ?int { + return 1234 +} + +fn sopt() ?string { + return 'xyz' +} + +fn test_iconsts_are_resolved() { + z := aaa + assert z == 1234 +} + +fn test_sconsts_are_resolved() { + z := bbb + assert z == 'xyz' +}