summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Pure.ml13
-rw-r--r--src/PureMicroPasses.ml25
-rw-r--r--src/SymbolicToPure.ml3
3 files changed, 40 insertions, 1 deletions
diff --git a/src/Pure.ml b/src/Pure.ml
index 96c7d211..bdcb35f8 100644
--- a/src/Pure.ml
+++ b/src/Pure.ml
@@ -34,6 +34,9 @@ type integer_type = T.integer_type [@@deriving show, ord]
*)
type assumed_ty = State | Result | Vec | Option [@@deriving show, ord]
+(* TODO: we should never directly manipulate `Return` and `Fail`, but rather
+ * the monadic functions `return` and `fail` (makes treatment of error and
+ * state-error monads more uniform) *)
let result_return_id = VariantId.of_int 0
let result_fail_id = VariantId.of_int 1
@@ -375,7 +378,15 @@ type unop = Not | Neg of integer_type [@@deriving show, ord]
type fun_id =
| Regular of A.fun_id * T.RegionGroupId.id option
(** Backward id: `Some` if the function is a backward function, `None`
- if it is a forward function *)
+ if it is a forward function.
+
+ TODO: we need to redefine A.fun_id here, to add `fail` and
+ `return` (important to get a unified treatment of the state-error
+ monad). For now, when using the state-error monad: extraction
+ works only if we unfold all the monadic let-bindings, and we
+ then replace the content of the occurrences of `Return` to also
+ return the state (which is really super ugly).
+ *)
| Unop of unop
| Binop of E.binop * integer_type
[@@deriving show, ord]
diff --git a/src/PureMicroPasses.ml b/src/PureMicroPasses.ml
index 61d247ea..6c61b9dc 100644
--- a/src/PureMicroPasses.ml
+++ b/src/PureMicroPasses.ml
@@ -1008,6 +1008,31 @@ let unfold_monadic_let_bindings (config : config) (_ctx : trans_ctx)
let switch_body = Match [ fail_branch; success_branch ] in
let e = Switch (re, switch_body) in
self#visit_expression state_var e
+
+ method! visit_Value state_var rv mp =
+ if config.use_state_monad then
+ match rv.ty with
+ | Adt (Assumed Result, _) -> (
+ match rv.value with
+ | RvAdt av ->
+ (* We only need to replace the content of `Return ...` *)
+ (* TODO: type checking is completely broken at this point... *)
+ let variant_id = Option.get av.variant_id in
+ if variant_id = result_return_id then
+ let res_v = Collections.List.to_cons_nil av.field_values in
+ let state_value = mk_typed_rvalue_from_var state_var in
+ let res = mk_simpl_tuple_rvalue [ state_value; res_v ] in
+ let res = mk_result_return_rvalue res in
+ (mk_value_expression res None).e
+ else super#visit_Value state_var rv mp
+ | _ -> raise (Failure "Unrechable"))
+ | _ -> super#visit_Value state_var rv mp
+ else super#visit_Value state_var rv mp
+ (** We also need to update values, in case this value is `Return ...`.
+
+ TODO: this is super ugly... We need to use the monadic functions
+ `fail` and `return` instead.
+ *)
end
in
(* Update the body *)
diff --git a/src/SymbolicToPure.ml b/src/SymbolicToPure.ml
index f2ed1053..5709ce23 100644
--- a/src/SymbolicToPure.ml
+++ b/src/SymbolicToPure.ml
@@ -972,6 +972,9 @@ and translate_return (_config : config) (opt_v : V.typed_value option)
(* Forward function *)
let v = Option.get opt_v in
let v = typed_value_to_rvalue ctx v in
+ (* TODO: we need to use a `return` function (otherwise we have problems
+ * with the state-error monad). We also need to update the type when using
+ * a state-error monad. *)
let v = mk_result_return_rvalue v in
let e = Value (v, None) in
let ty = v.ty in