Skip to content

Commit a96bd46

Browse files
committed
Deconstruct tuples in let and fun
1 parent 87bd2f2 commit a96bd46

File tree

5 files changed

+96
-31
lines changed

5 files changed

+96
-31
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ distclean: clean
2727

2828
# All of these tests must be run with with_tezos=true
2929

30-
NTESTS=19
30+
NTESTS=20
3131
SIMPLE_TESTS= `seq -f 'test%.0f' 0 $(NTESTS)`
3232
MORE_TESTS=test_ifcons test_if test_loop test_option test_transfer test_left \
3333
test_extfun test_left_constr test_closure test_closure2 test_closure3 \

tests/others/broker.liq

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ let%entry main
1919
else
2020
if Current.time () < storage.timeout then (* Before timeout *)
2121
(* We compute ((1 + P) + N) tez for keeping the contract alive *)
22-
let pn = storage.pn in
23-
let cost = 1.00tz + pn.(0) + pn.(1) in
22+
let (pn0, pn1) = storage.pn in
23+
let cost = 1.00tz + pn0 + pn1 in
2424
let b = Current.balance () in
2525
if cost < b then
2626
(* # Not enough cash, we just accept the transaction
@@ -30,15 +30,17 @@ let%entry main
3030
(* # Enough cash, successful ending
3131
# We update the global*)
3232
let storage = storage.state <- "success" in
33+
let (pn0, _) = storage.pn in
3334
let (_result, storage) =
34-
Contract.call storage.x storage.pn.(0) storage () in
35+
Contract.call storage.x pn0 storage () in
36+
let (_, pn1) = storage.pn in
3537
let (_result, storage) =
36-
Contract.call storage.a storage.pn.(1) storage () in
38+
Contract.call storage.a pn1 storage () in
3739
( (), storage )
3840
else
3941
(* # After timeout, we refund
4042
# We update the global *)
41-
let p = storage.pn.(0) in
43+
let (p, _) = storage.pn in
4244
let storage = storage.state <- "timeout" in
4345
(* # We try to transfer the fee to the broker *)
4446
let bal = Current.balance () in

tests/test20.liq

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
type storage = tez * int * ((nat * unit) * bool)
2+
3+
let%entry main
4+
(parameter : unit)
5+
(storage : storage)
6+
: (nat * tez) * storage =
7+
8+
let x, y = 0p, 1p in
9+
let amount, _, ((n, _), b) = storage in
10+
((n + x + y, amount), storage)

tests/test_extfun.liq

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
[%%version 0.11]
33

4-
let f ( arg : unit * int ) = arg.(0)
4+
let f ((x : unit), (_ : int) ) = x
55

66
let%entry main
77
(parameter : int)

tools/liquidity/liquidFromOCaml.ml

Lines changed: 77 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,41 @@ and translate_pair exp =
390390

391391
let mk desc = { desc; ty = (); bv = StringSet.empty; fail = false }
392392

393+
let deconstruct_pat env pat =
394+
let rec deconstruct_pat_aux acc indexes = function
395+
| { ppat_desc = Ppat_constraint (pat, ty) } ->
396+
let acc, _ = deconstruct_pat_aux acc indexes pat in
397+
acc, translate_type env ty
398+
399+
| { ppat_desc = Ppat_var { txt = var; loc } } ->
400+
(var, loc_of_loc loc, indexes) :: acc, Tunit (* Dummy type value *)
401+
402+
| { ppat_desc = Ppat_any; ppat_loc } ->
403+
("_", loc_of_loc ppat_loc, indexes) :: acc, Tunit (* Dummy type value *)
404+
405+
| { ppat_desc = Ppat_tuple pats } ->
406+
let _, acc, tys =
407+
List.fold_left (fun (i, acc, tys) pat ->
408+
let acc, ty = deconstruct_pat_aux acc (i :: indexes) pat in
409+
i + 1, acc, ty :: tys
410+
) (0, acc, []) pats
411+
in
412+
acc, Ttuple (List.rev tys)
413+
414+
| { ppat_loc } ->
415+
error_loc ppat_loc "cannot deconstruct this pattern"
416+
in
417+
deconstruct_pat_aux [] [] pat
418+
419+
let access_of_deconstruct var_name loc indexes =
420+
let a = mk (Var (var_name, loc, [])) in
421+
List.fold_right (fun i a ->
422+
mk (Apply (Prim_tuple_get, loc, [
423+
a;
424+
mk (Const (Tnat, CNat (LiquidPrinter.integer_of_int i)))
425+
]))
426+
) indexes a
427+
393428
let rec translate_code env exp =
394429
let desc =
395430
match exp with
@@ -463,16 +498,27 @@ let rec translate_code env exp =
463498
translate_code env arg_exp,
464499
translate_code env body)
465500

466-
| { pexp_desc = Pexp_let (Nonrecursive,
467-
[
468-
{
469-
pvb_pat = { ppat_desc =
470-
Ppat_var { txt = var; loc } };
471-
pvb_expr = var_exp;
472-
}
473-
], body) } ->
474-
Let (var, loc_of_loc loc,
475-
translate_code env var_exp, translate_code env body)
501+
| { pexp_desc = Pexp_let (Nonrecursive, [ {
502+
pvb_pat = pat;
503+
pvb_expr = var_exp;
504+
} ], body); pexp_loc } ->
505+
506+
let vars_infos, _ = deconstruct_pat env pat in
507+
let exp, body = translate_code env var_exp, translate_code env body in
508+
begin match vars_infos with
509+
| [] -> assert false
510+
| [v, loc, []] -> Let (v, loc, exp, body)
511+
| _ ->
512+
let var_name =
513+
String.concat "_" (List.rev_map (fun (v,_,_) -> v) vars_infos) in
514+
let lets_body =
515+
List.fold_left (fun e (v, loc, indexes) ->
516+
let access = access_of_deconstruct var_name loc indexes in
517+
mk (Let (v, loc, access, e))
518+
) body vars_infos
519+
in
520+
Let (var_name, loc_of_loc pexp_loc, exp, lets_body)
521+
end
476522

477523
| { pexp_desc = Pexp_sequence (exp1, exp2) } ->
478524
Seq (translate_code env exp1, translate_code env exp2)
@@ -529,21 +575,28 @@ let rec translate_code env exp =
529575
MatchVariant(e, loc_of_loc pexp_loc, args)
530576
end
531577

532-
| { pexp_desc =
533-
Pexp_fun (
534-
Nolabel, None,
535-
{ ppat_desc =
536-
Ppat_constraint(
537-
{ ppat_desc =
538-
Ppat_var { txt = arg_name } },
539-
arg_type)
540-
},
541-
body_exp) } ->
578+
| { pexp_desc = Pexp_fun (Nolabel, None, pat, body_exp) } ->
542579
let body_exp = translate_code env body_exp in
543-
let arg_type = translate_type env arg_type in
544-
Lambda (arg_name, arg_type, loc_of_loc exp.pexp_loc,
545-
body_exp,
546-
Tunit) (* not yet inferred *)
580+
let vars_infos, arg_type = deconstruct_pat env pat in
581+
begin match vars_infos with
582+
| [] -> assert false
583+
| [arg_name, loc, []] ->
584+
Lambda (arg_name, arg_type, loc_of_loc exp.pexp_loc,
585+
body_exp,
586+
Tunit) (* not yet inferred *)
587+
| _ ->
588+
let arg_name =
589+
String.concat "_" (List.rev_map (fun (v,_,_) -> v) vars_infos) in
590+
let lets_body =
591+
List.fold_left (fun e (v, loc, indexes) ->
592+
let access = access_of_deconstruct arg_name loc indexes in
593+
mk (Let (v, loc, access, e))
594+
) body_exp vars_infos
595+
in
596+
Lambda (arg_name, arg_type, loc_of_loc exp.pexp_loc,
597+
lets_body,
598+
Tunit) (* not yet inferred *)
599+
end
547600

548601
| { pexp_desc = Pexp_record (lab_x_exp_list, None) } ->
549602
let lab_x_exp_list =

0 commit comments

Comments
 (0)