From 15518be07d693c4032961efb93f0e5ff6c918342 Mon Sep 17 00:00:00 2001 From: Michael Ankele Date: Mon, 9 Sep 2024 21:54:34 +0200 Subject: [PATCH] optional pipes --- src/lib/kaba/parser/Concretifier.cpp | 33 ++++++++++++++++++++- test/regression/optional/optional-pipe.kaba | 18 +++++++++++ test/regression/optional/optional-pipe.reg | 3 ++ 3 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 test/regression/optional/optional-pipe.kaba create mode 100644 test/regression/optional/optional-pipe.reg diff --git a/src/lib/kaba/parser/Concretifier.cpp b/src/lib/kaba/parser/Concretifier.cpp index 7783ba93..70168b49 100644 --- a/src/lib/kaba/parser/Concretifier.cpp +++ b/src/lib/kaba/parser/Concretifier.cpp @@ -2379,7 +2379,38 @@ shared Concretifier::try_build_pipe_map_optional_unwrap(const shared if (input->type->param[0] != pt) return nullptr; - return nullptr; + auto ff = f->as_func(); + bool needs_wrapping = !ff->literal_return_type->is_optional(); + auto t_out = ff->literal_return_type; + if (needs_wrapping) + t_out = tree->request_implicit_class_optional(ff->literal_return_type, token_id); + + auto b = new Block(block->function, block, t_out); + auto v = b->add_var(b->function->create_slightly_hidden_name(), input->type); + + b->add(auto_implementer->add_assign(block->function, "...", add_node_local(v), input)); + + auto cif = add_node_statement(StatementID::If, token_id, t_out); + cif->set_num_params(3); + + auto f_has_val = input->type->get_member_func(Identifier::func::OptionalHasValue, TypeBool, {}); + cif->set_param(0, add_node_member_call(f_has_val, add_node_local(v), token_id)); + auto call = add_node_call(ff, token_id); + call->set_param(0, add_node_local(v)->change_type(input->type->param[0])); + if (needs_wrapping) { + for (auto c: t_out->get_constructors()) + if (c->num_params == 2 and c->literal_param_type[1] == pt) { + cif->set_param(1, add_node_constructor(c, token_id)); + cif->params[1]->params[1] = call; + } + } else { + cif->set_param(1, call); + } + cif->set_param(2, add_node_constructor(t_out->get_default_constructor(), token_id)); + + b->add(cif); + + return b; } shared Concretifier::try_build_pipe_map_direct(const shared &input, Node *f, const Class *rt, const Class *pt, Block *block, const Class *ns, int token_id) { diff --git a/test/regression/optional/optional-pipe.kaba b/test/regression/optional/optional-pipe.kaba new file mode 100644 index 00000000..79557434 --- /dev/null +++ b/test/regression/optional/optional-pipe.kaba @@ -0,0 +1,18 @@ +func f(x: f32) -> f32 + return x*x + + +func g(x: f32) -> f32? + if x > 1 + return x*x + else + return nil + +func main() + let o = 13.0 as f32? + + print(o |> f |> f) + + print(o |> g) + print(o |> sin |> g) + diff --git a/test/regression/optional/optional-pipe.reg b/test/regression/optional/optional-pipe.reg new file mode 100644 index 00000000..2c4f1aab --- /dev/null +++ b/test/regression/optional/optional-pipe.reg @@ -0,0 +1,3 @@ +28561.000000 +169.000000 +nil