diff --git a/src/passes/2-simplify/pascaligo.ml b/src/passes/2-simplify/pascaligo.ml index e7863e4ba..6d2384e9a 100644 --- a/src/passes/2-simplify/pascaligo.ml +++ b/src/passes/2-simplify/pascaligo.ml @@ -116,17 +116,6 @@ module Errors = struct ] in error ~data title message - let unsupported_deep_access_for_collection for_col = - let title () = "deep access in loop over collection" in - let message () = - Format.asprintf "currently, we do not support deep \ - accesses in loops over collection" in - let data = [ - ("pattern_loc", - fun () -> Format.asprintf "%a" Location.pp_lift @@ for_col.Region.region) - ] in - error ~data title message - (* Logging *) let simplifying_instruction t = @@ -1047,10 +1036,8 @@ and simpl_for_collect : Raw.for_collect -> (_ -> expression result) result = fun (fun (prev : type_name list) (ass_exp : expression) -> match ass_exp.expression with | E_assign ( name , _ , _ ) -> - if (String.contains name '#') then - ok prev - else - ok (name::prev) + if (String.contains name '#') then ok prev + else ok (name::prev) | _ -> ok prev ) [] for_body in @@ -1063,12 +1050,13 @@ and simpl_for_collect : Raw.for_collect -> (_ -> expression result) result = fun match exp.expression with (* replace references to fold accumulator as rhs *) | E_assign ( name , path , expr ) -> ( - match path with - | [] -> ok @@ e_assign "#COMPILER#acc" [Access_record name] expr - (* This fails for deep accesses, see LIGO-131 LIGO-134 *) - | _ -> - (* ok @@ e_assign "#COMPILER#acc" ((Access_record name)::path) expr) *) - fail @@ unsupported_deep_access_for_collection fc.block ) + let path' = List.filter + ( fun el -> + match el with + | Access_record name -> not (String.contains name '#') + | _ -> true ) + ((Access_record name)::path) in + ok @@ e_assign "#COMPILER#acc" path' expr) | E_variable name -> ( if (List.mem name captured_name_list) then (* replace references to fold accumulator as lhs *) @@ -1107,16 +1095,10 @@ and simpl_for_collect : Raw.for_collect -> (_ -> expression result) result = fun let ( arg_access: Types.access_path -> expression ) = e_accessor (e_variable "arguments") in ( match fc.collection with | Map _ -> - (* let acc = arg_access [Access_tuple 0 ; Access_tuple 0] in + let acc = arg_access [Access_tuple 0 ] in let collec_elt_v = arg_access [Access_tuple 1 ; Access_tuple 0] in - let collec_elt_k = arg_access [Access_tuple 1 ; Access_tuple 1] in *) - (* The above should work, but not yet (see LIGO-131) *) - let temp_kv = arg_access [Access_tuple 1] in - let acc = arg_access [Access_tuple 0] in - let collec_elt_v = e_accessor (e_variable "#COMPILER#temp_kv") [Access_tuple 0] in - let collec_elt_k = e_accessor (e_variable "#COMPILER#temp_kv") [Access_tuple 1] in + let collec_elt_k = arg_access [Access_tuple 1 ; Access_tuple 1] in e_let_in ("#COMPILER#acc", None) acc @@ - e_let_in ("#COMPILER#temp_kv", None) temp_kv @@ e_let_in ("#COMPILER#collec_elt_k", None) collec_elt_v @@ e_let_in ("#COMPILER#collec_elt_v", None) collec_elt_k (for_body) | _ -> diff --git a/src/test/contracts/loop.ligo b/src/test/contracts/loop.ligo index ef3af8527..9640a864e 100644 --- a/src/test/contracts/loop.ligo +++ b/src/test/contracts/loop.ligo @@ -134,20 +134,26 @@ function for_collection_map_k (var nee : unit) : string is block { end } with st -// function nested_for_collection (var nee : unit) : (int*string) is block { -// var myint : int := 0; -// var myst : string := ""; -// var mylist : list(int) := list 1 ; 2 ; 3 end ; -// for i : int in list mylist -// begin -// myint := myint + i ; -// var myset : set(string) := set "1" ; "2" ; "3" end ; -// for st : string in set myset -// begin -// myst := myst ^ st ; -// end -// end -// } with (myint,myst) +function nested_for_collection (var nee : unit) : (int*string) is block { + var myint : int := 0; + var mystoo : string := ""; + var mylist : list(int) := list 1 ; 2 ; 3 end ; + var mymap : map(string,string) := map " one" -> "," ; "two" -> " " end ; + + for i in list mylist + begin + myint := myint + i ; + var myset : set(string) := set "1" ; "2" ; "3" end ; + for st in set myset + begin + mystoo := mystoo ^ st ; + for k -> v in map mymap + begin + mystoo := mystoo ^ k ^ v ; + end + end + end +} with (myint,mystoo) function dummy (const n : nat) : nat is block { while False block { skip } diff --git a/src/test/integration_tests.ml b/src/test/integration_tests.ml index 1c7eb60ae..7d44abdaa 100644 --- a/src/test/integration_tests.ml +++ b/src/test/integration_tests.ml @@ -812,9 +812,10 @@ let loop () : unit result = let%bind () = let expected = (e_int 20) in expect_eq program "for_collection_comp_with_acc" input expected in - (* let%bind () = - let expected = e_pair (e_int 6) (e_string "123123123") in - expect_eq program "nested_for_collection" input expected in *) + let%bind () = + let expected = e_pair (e_int 6) + (e_string "1 one,two 2 one,two 3 one,two 1 one,two 2 one,two 3 one,two 1 one,two 2 one,two 3 one,two ") in + expect_eq program "nested_for_collection" input expected in let%bind () = let ez lst = let open Ast_simplified.Combinators in