From fbb622cc03e631de13f79762d94e6d31315bd87d Mon Sep 17 00:00:00 2001 From: Sander Spies Date: Mon, 20 Jan 2020 19:03:00 +0100 Subject: [PATCH 1/4] Add support for tuple destructuring in ReasonLIGO --- src/passes/1-parser/reasonligo/Parser.mly | 18 ++++++++++++++++-- src/test/integration_tests.ml | 6 ++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/passes/1-parser/reasonligo/Parser.mly b/src/passes/1-parser/reasonligo/Parser.mly index 804bcddea..c4ad40826 100644 --- a/src/passes/1-parser/reasonligo/Parser.mly +++ b/src/passes/1-parser/reasonligo/Parser.mly @@ -428,8 +428,22 @@ fun_expr: {p.value with inside = arg_to_pattern p.value.inside} in PPar {p with value} | EUnit u -> PUnit u - | e -> let open! SyntaxError - in raise (Error (WrongFunctionArguments e)) + | ETuple { value; region } -> + PTuple { value = Utils.nsepseq_map arg_to_pattern value; region} + | EAnnot {region; value = {inside = ETuple _ as t, colon, typ; _}} -> + let value = { pattern = arg_to_pattern t; colon; type_expr = typ} in + PPar { + value = { + lpar = Region.ghost; + rpar = Region.ghost; + inside = PTyped {region; value} + }; + region + } + | e -> ( + let open! SyntaxError in + raise (Error (WrongFunctionArguments e)) + ) in let fun_args_to_pattern = function EAnnot { diff --git a/src/test/integration_tests.ml b/src/test/integration_tests.ml index 394bcc4f0..0f9ebfb8f 100644 --- a/src/test/integration_tests.ml +++ b/src/test/integration_tests.ml @@ -1946,6 +1946,11 @@ let tuple_param_destruct () : unit result = let%bind () = expect_eq program "sum" (e_tuple [e_int 10; e_int 10]) (e_int 20) in ok () +let tuple_param_destruct_religo () : unit result = + let%bind program = retype_file "./contracts/tuple_param_destruct.religo" in + let%bind () = expect_eq program "sum" (e_tuple [e_int 10; e_int 10]) (e_int 20) + in ok () + let let_in_multi_bind () : unit result = let%bind program = mtype_file "./contracts/let_in_multi_bind.mligo" in let%bind () = expect_eq program "sum" (e_tuple [e_int 10; e_int 10]) (e_int 20) in @@ -2159,6 +2164,7 @@ let main = test_suite "Integration (End to End)" [ test "attributes (religo)" attributes_religo; test "let in multi-bind (mligo)" let_in_multi_bind ; test "tuple param destruct (mligo)" tuple_param_destruct ; + test "tuple param destruct (religo)" tuple_param_destruct_religo ; test "empty case" empty_case ; test "empty case (mligo)" empty_case_mligo ; test "empty case (religo)" empty_case_religo ; From e959ef4f6fe0ff625daee10f4e9d35fc169ed55c Mon Sep 17 00:00:00 2001 From: Sander Spies Date: Mon, 20 Jan 2020 19:04:02 +0100 Subject: [PATCH 2/4] Forgot to add test file. --- src/test/contracts/tuple_param_destruct.religo | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/test/contracts/tuple_param_destruct.religo diff --git a/src/test/contracts/tuple_param_destruct.religo b/src/test/contracts/tuple_param_destruct.religo new file mode 100644 index 000000000..389bf9835 --- /dev/null +++ b/src/test/contracts/tuple_param_destruct.religo @@ -0,0 +1 @@ +let sum = ((result, i) : (int, int)) : int => result + i; From 483f591f62ad29380463d108ffa12b44cabb4ae7 Mon Sep 17 00:00:00 2001 From: Sander Spies Date: Tue, 21 Jan 2020 14:57:13 +0100 Subject: [PATCH 3/4] Typo --- src/passes/2-simplify/cameligo.ml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/passes/2-simplify/cameligo.ml b/src/passes/2-simplify/cameligo.ml index fb16694fb..d4445c7bd 100644 --- a/src/passes/2-simplify/cameligo.ml +++ b/src/passes/2-simplify/cameligo.ml @@ -36,7 +36,7 @@ module Errors = struct ] in error ~data title message - let unsuppported_let_in_function (patterns : Raw.pattern list) = + let unsupported_let_in_function (patterns : Raw.pattern list) = let title () = "unsupported 'let ... in' function" in let message () = "defining functions via 'let ... in' is not supported yet" in let patterns_loc = @@ -354,7 +354,7 @@ let rec simpl_expression : (* let f p1 ps... = rhs in body *) | (f, p1 :: ps) -> - fail @@ unsuppported_let_in_function (f :: p1 :: ps) + fail @@ unsupported_let_in_function (f :: p1 :: ps) end | Raw.EAnnot a -> let Raw.{inside=expr, _, type_expr; _}, loc = r_split a in From f104b5e512ea0e6fe968a635771677f8622d8d0b Mon Sep 17 00:00:00 2001 From: Sander Spies Date: Tue, 21 Jan 2020 21:23:31 +0100 Subject: [PATCH 4/4] Handle parentheses when destructuring. --- src/passes/1-parser/reasonligo/Parser.mly | 2 +- src/passes/2-simplify/cameligo.ml | 11 ++++++++--- src/test/contracts/tuple_param_destruct.mligo | 3 ++- src/test/contracts/tuple_param_destruct.religo | 3 ++- src/test/integration_tests.ml | 10 ++++++---- 5 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/passes/1-parser/reasonligo/Parser.mly b/src/passes/1-parser/reasonligo/Parser.mly index c4ad40826..a6eea7961 100644 --- a/src/passes/1-parser/reasonligo/Parser.mly +++ b/src/passes/1-parser/reasonligo/Parser.mly @@ -430,7 +430,7 @@ fun_expr: | EUnit u -> PUnit u | ETuple { value; region } -> PTuple { value = Utils.nsepseq_map arg_to_pattern value; region} - | EAnnot {region; value = {inside = ETuple _ as t, colon, typ; _}} -> + | EAnnot {region; value = {inside = t, colon, typ; _}} -> let value = { pattern = arg_to_pattern t; colon; type_expr = typ} in PPar { value = { diff --git a/src/passes/2-simplify/cameligo.ml b/src/passes/2-simplify/cameligo.ml index d4445c7bd..917d001bf 100644 --- a/src/passes/2-simplify/cameligo.ml +++ b/src/passes/2-simplify/cameligo.ml @@ -179,6 +179,10 @@ let rec tuple_pattern_to_typed_vars : Raw.pattern -> _ = fun pattern -> | Raw.PVar _ -> bind_list [pattern_to_typed_var pattern] | other -> (fail @@ wrong_pattern "parenthetical, tuple, or variable" other) +let rec unpar_pattern : Raw.pattern -> Raw.pattern = function + | PPar p -> unpar_pattern p.value.inside + | _ as p -> p + let rec simpl_type_expression : Raw.type_expr -> type_expression result = fun te -> trace (simple_info "simplifying this type expression...") @@ match te with @@ -541,7 +545,8 @@ and simpl_fun lamb' : expr result = (match pt with | Raw.PTyped pt -> begin - match pt.value.pattern with + let pt_pattern = unpar_pattern pt.value.pattern in + match pt_pattern with | Raw.PVar _ -> params | Raw.PTuple _ -> [Raw.PTyped @@ -581,10 +586,10 @@ and simpl_fun lamb' : expr result = match destruct with (* Handle tuple parameter destructuring *) (* In this section we create a let ... in that binds the original parameters *) | Raw.PPar pp -> - (match pp.value.inside with + (match unpar_pattern pp.value.inside with | Raw.PTyped pt -> let vars = pt.value in - (match vars.pattern with + (match unpar_pattern vars.pattern with | PTuple vars -> let let_in_binding: Raw.let_binding = {binders = (PTuple vars, []) ; diff --git a/src/test/contracts/tuple_param_destruct.mligo b/src/test/contracts/tuple_param_destruct.mligo index 6dfe30fe4..d9cfc6513 100644 --- a/src/test/contracts/tuple_param_destruct.mligo +++ b/src/test/contracts/tuple_param_destruct.mligo @@ -1 +1,2 @@ -let sum (result, i : int * int) : int = result + i +let sum (result, i : int * int) : int = result - i +let parentheses ((((result, i))) : ((int * int))) : int = result - i diff --git a/src/test/contracts/tuple_param_destruct.religo b/src/test/contracts/tuple_param_destruct.religo index 389bf9835..3641ab8d0 100644 --- a/src/test/contracts/tuple_param_destruct.religo +++ b/src/test/contracts/tuple_param_destruct.religo @@ -1 +1,2 @@ -let sum = ((result, i) : (int, int)) : int => result + i; +let sum = ((result, i) : (int, int)) : int => result - i; +let parentheses = (((((result, i)))) : (((int, int)))) : int => result - i; diff --git a/src/test/integration_tests.ml b/src/test/integration_tests.ml index 0f9ebfb8f..6abe31226 100644 --- a/src/test/integration_tests.ml +++ b/src/test/integration_tests.ml @@ -1943,13 +1943,15 @@ let type_tuple_destruct () : unit result = let tuple_param_destruct () : unit result = let%bind program = mtype_file "./contracts/tuple_param_destruct.mligo" in - let%bind () = expect_eq program "sum" (e_tuple [e_int 10; e_int 10]) (e_int 20) - in ok () + let%bind () = expect_eq program "sum" (e_tuple [e_int 20; e_int 10]) (e_int 10) in + let%bind () = expect_eq program "parentheses" (e_tuple [e_int 20; e_int 10]) (e_int 10) in + ok () let tuple_param_destruct_religo () : unit result = let%bind program = retype_file "./contracts/tuple_param_destruct.religo" in - let%bind () = expect_eq program "sum" (e_tuple [e_int 10; e_int 10]) (e_int 20) - in ok () + let%bind () = expect_eq program "sum" (e_tuple [e_int 20; e_int 10]) (e_int 10) in + let%bind () = expect_eq program "parentheses" (e_tuple [e_int 20; e_int 10]) (e_int 10) in + ok () let let_in_multi_bind () : unit result = let%bind program = mtype_file "./contracts/let_in_multi_bind.mligo" in