@@ -646,6 +646,16 @@ let rec cut n l =
646646
647647let try_ids = Hashtbl. create 8
648648
649+ let stdlib_option_call_extra exp =
650+ let rec aux = function
651+ | [] -> None
652+ | (Texp_stdlib_option_call info , _ , _ ) :: _ -> Some info
653+ | _ :: rest -> aux rest
654+ in
655+ aux exp.exp_extra
656+
657+ let lambda_none = Lconst (Const_pointer (0 , Pt_shape_none ))
658+
649659let extract_directive_for_fn exp =
650660 exp.exp_attributes
651661 |> List. find_map (fun ({txt} , payload ) ->
@@ -755,10 +765,11 @@ and transl_exp0 (e : Typedtree.expression) : Lambda.lambda =
755765 (Lprim
756766 (Pccall (set_transformed_jsx d ~transformed_jsx ), argl, e.exp_loc))
757767 | _ -> wrap (Lprim (prim, argl, e.exp_loc))))
758- | Texp_apply {funct; args = oargs ; partial; transformed_jsx} ->
768+ | Texp_apply {funct; args = oargs ; partial; transformed_jsx} -> (
759769 let inlined, funct =
760770 Translattribute. get_and_remove_inlined_attribute funct
761771 in
772+ let option_call_info = stdlib_option_call_extra e in
762773 let uncurried_partial_application =
763774 (* In case of partial application foo(args, ...) when some args are missing,
764775 get the arity *)
@@ -771,8 +782,17 @@ and transl_exp0 (e : Typedtree.expression) : Lambda.lambda =
771782 | None -> None
772783 else None
773784 in
774- transl_apply ~inlined ~uncurried_partial_application ~transformed_jsx
775- (transl_exp funct) oargs e.exp_loc
785+ match option_call_info with
786+ | Some info when not partial -> (
787+ match oargs with
788+ | (Nolabel, Some opt_expr ) :: _ ->
789+ transl_stdlib_option_call e opt_expr info oargs
790+ | _ ->
791+ transl_apply ~inlined ~uncurried_partial_application ~transformed_jsx
792+ (transl_exp funct) oargs e.exp_loc)
793+ | _ ->
794+ transl_apply ~inlined ~uncurried_partial_application ~transformed_jsx
795+ (transl_exp funct) oargs e.exp_loc)
776796 | Texp_match (arg , pat_expr_list , exn_pat_expr_list , partial ) ->
777797 transl_match e arg pat_expr_list exn_pat_expr_list partial
778798 | Texp_try (body , pat_expr_list ) ->
@@ -924,6 +944,60 @@ and transl_exp0 (e : Typedtree.expression) : Lambda.lambda =
924944 if ! Clflags. noassert then lambda_unit
925945 else Lifthenelse (transl_exp cond, lambda_unit, assert_failed e)
926946
947+ and bind_option_value ~payload_not_nested opt_var opt_loc callback =
948+ let value_expr =
949+ if payload_not_nested then
950+ Lprim (Pval_from_option_not_nest , [opt_var], opt_loc)
951+ else Lprim (Pval_from_option , [opt_var], opt_loc)
952+ in
953+ match callback with
954+ | Stdlib_option_inline_lambda {param; body} ->
955+ bind Strict param value_expr (transl_exp body)
956+ | Stdlib_option_inline_ident expr ->
957+ let func = transl_exp expr in
958+ let value_id = Ident. create " __res_option_value" in
959+ let apply =
960+ Lapply
961+ {
962+ ap_func = func;
963+ ap_args = [Lvar value_id];
964+ ap_inlined = Default_inline ;
965+ ap_loc = expr.exp_loc;
966+ ap_transformed_jsx = false ;
967+ }
968+ in
969+ bind Strict value_id value_expr apply
970+
971+ and transl_stdlib_option_call exp opt_expr info oargs =
972+ match oargs with
973+ | (Nolabel , Some _ ) :: (Nolabel , Some _ ) :: _ | (Nolabel, Some _ ) :: [] ->
974+ let opt_lam = transl_exp opt_expr in
975+ let opt_id = Ident. create " __res_option_opt" in
976+ let opt_var = Lvar opt_id in
977+ let callback_result =
978+ bind_option_value ~payload_not_nested: info.payload_not_nested opt_var
979+ exp.exp_loc info.callback
980+ in
981+ let some_branch =
982+ match info.call_kind with
983+ | Stdlib_option_forEach -> callback_result
984+ | Stdlib_option_map {result_cannot_contain_undefined} ->
985+ let tag =
986+ if result_cannot_contain_undefined then Blk_some_not_nested
987+ else Blk_some
988+ in
989+ Lprim (Pmakeblock tag, [callback_result], exp.exp_loc)
990+ | Stdlib_option_flatMap -> callback_result
991+ in
992+ let none_branch =
993+ match info.call_kind with
994+ | Stdlib_option_forEach -> lambda_unit
995+ | Stdlib_option_map _ | Stdlib_option_flatMap -> lambda_none
996+ in
997+ let cond = Lprim (Pis_not_none , [opt_var], exp.exp_loc) in
998+ bind Strict opt_id opt_lam (Lifthenelse (cond, some_branch, none_branch))
999+ | _ -> assert false
1000+
9271001and transl_list expr_list = List. map transl_exp expr_list
9281002
9291003and transl_guard guard rhs =
0 commit comments