From 06e153d429a9d8d384f42757bc54f577045411a2 Mon Sep 17 00:00:00 2001 From: yuyi Date: Sun, 28 Aug 2022 14:12:08 +0800 Subject: [PATCH] ast, cgen: implement sumtype with fntype partly (related #15557) (#15567) --- vlib/v/ast/table.v | 14 +++++++++++++- vlib/v/gen/c/cgen.v | 14 ++++++++++++-- vlib/v/tests/inout/sumtype_with_fntype.out | 1 + vlib/v/tests/inout/sumtype_with_fntype.vv | 8 ++++++++ 4 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 vlib/v/tests/inout/sumtype_with_fntype.out create mode 100644 vlib/v/tests/inout/sumtype_with_fntype.vv diff --git a/vlib/v/ast/table.v b/vlib/v/ast/table.v index 70398a65e..66012b625 100644 --- a/vlib/v/ast/table.v +++ b/vlib/v/ast/table.v @@ -1195,7 +1195,7 @@ pub fn (mut t Table) find_or_register_fn_type(f Fn, is_anon bool, has_decl bool) cname := if f.name.len == 0 { 'anon_fn_${t.fn_type_signature(f)}' } else { - util.no_dots(f.name.clone()) + util.no_dots(f.name.clone()).replace_each([' ', '', '(', '_', ')', '']) } anon := f.name.len == 0 || is_anon existing_idx := t.type_idxs[name] @@ -1295,6 +1295,9 @@ pub fn (t &Table) sumtype_has_variant(parent Type, variant Type, is_as bool) boo .alias { return t.sumtype_check_alias_variant(parent, variant, is_as) } + .function { + return t.sumtype_check_function_variant(parent_info, variant, is_as) + } else { return t.sumtype_check_variant_in_type(parent_info, variant, is_as) } @@ -1303,6 +1306,15 @@ pub fn (t &Table) sumtype_has_variant(parent Type, variant Type, is_as bool) boo return false } +fn (t &Table) sumtype_check_function_variant(parent_info SumType, variant Type, is_as bool) bool { + for v in parent_info.variants { + if '$v.idx' == '$variant.idx' && (!is_as || v.nr_muls() == variant.nr_muls()) { + return true + } + } + return false +} + fn (t &Table) sumtype_check_variant_in_type(parent_info SumType, variant Type, is_as bool) bool { for v in parent_info.variants { if v.idx() == variant.idx() && (!is_as || v.nr_muls() == variant.nr_muls()) { diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 13b743873..29efaaf00 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -2102,7 +2102,12 @@ fn (mut g Gen) get_sumtype_casting_fn(got_ ast.Type, exp_ ast.Type) string { fn (mut g Gen) write_sumtype_casting_fn(fun SumtypeCastingFn) { got, exp := fun.got, fun.exp got_sym, exp_sym := g.table.sym(got), g.table.sym(exp) - got_cname, exp_cname := got_sym.cname, exp_sym.cname + mut got_cname, exp_cname := got_sym.cname, exp_sym.cname + if got_sym.info is ast.FnType { + if got_sym.info.is_anon { + got_cname = 'anon_fn_${g.table.fn_type_signature(got_sym.info.func)}' + } + } mut sb := strings.new_builder(128) sb.writeln('static inline $exp_cname ${fun.fn_name}($got_cname* x) {') sb.writeln('\t$got_cname* ptr = memdup(x, sizeof($got_cname));') @@ -2231,7 +2236,12 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type_raw ast.Type, expected_typ } // cast to sum type exp_styp := g.typ(expected_type) - got_styp := g.typ(got_type) + mut got_styp := g.typ(got_type) + if got_sym.info is ast.FnType { + if got_sym.info.is_anon { + got_styp = 'anon_fn_${g.table.fn_type_signature(got_sym.info.func)}' + } + } if expected_type != ast.void_type { unwrapped_expected_type := g.unwrap_generic(expected_type) unwrapped_exp_sym := g.table.sym(unwrapped_expected_type) diff --git a/vlib/v/tests/inout/sumtype_with_fntype.out b/vlib/v/tests/inout/sumtype_with_fntype.out new file mode 100644 index 000000000..bfe65323f --- /dev/null +++ b/vlib/v/tests/inout/sumtype_with_fntype.out @@ -0,0 +1 @@ +Fns diff --git a/vlib/v/tests/inout/sumtype_with_fntype.vv b/vlib/v/tests/inout/sumtype_with_fntype.vv new file mode 100644 index 000000000..935562c85 --- /dev/null +++ b/vlib/v/tests/inout/sumtype_with_fntype.vv @@ -0,0 +1,8 @@ +type Fns = bool | fn (int) int + +fn main() { + f := Fns(fn (a int) int { + return a + }) + println(typeof(f).name) +} -- 2.30.2