From 402d849cec742c408fe9ddbb7c3d3f3d38e94257 Mon Sep 17 00:00:00 2001 From: Lesenechal Remi Date: Tue, 29 Oct 2019 15:43:00 +0100 Subject: [PATCH] use intermediary tuple access to get key and value for maps. add tests. --- src/passes/2-simplify/pascaligo.ml | 21 ++++++++------------- src/test/contracts/loop.ligo | 29 +++++++++++++++++++---------- src/test/integration_tests.ml | 6 ++++++ 3 files changed, 33 insertions(+), 23 deletions(-) diff --git a/src/passes/2-simplify/pascaligo.ml b/src/passes/2-simplify/pascaligo.ml index 0200098ae..54b2c2207 100644 --- a/src/passes/2-simplify/pascaligo.ml +++ b/src/passes/2-simplify/pascaligo.ml @@ -138,16 +138,6 @@ module Errors = struct ] in error ~data title message - let unsupported_for_collect_map for_col = - let title () = "for loop over map" in - let message () = - Format.asprintf "for loops over map are not supported yet" in - let data = [ - ("loop_loc", - fun () -> Format.asprintf "%a" Location.pp_lift @@ for_col.Region.region) - ] in - error ~data title message - (* Logging *) let simplifying_instruction t = @@ -1071,7 +1061,6 @@ and simpl_for_int : Raw.for_int -> (_ -> expression result) result = fun fi -> **) and simpl_for_collect : Raw.for_collect -> (_ -> expression result) result = fun fc -> - match fc.collection with | Map _ -> fail @@ unsupported_for_collect_map fc.block | _ -> (* STEP 1 *) let%bind for_body = simpl_block fc.block.value in let%bind for_body = for_body None in @@ -1136,10 +1125,16 @@ 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 ; 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 + 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 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 bbf887460..b873853b7 100644 --- a/src/test/contracts/loop.ligo +++ b/src/test/contracts/loop.ligo @@ -116,16 +116,25 @@ function for_collection_empty (var nee : unit) : int is block { end } with acc -// function for_collection_map (var nee : unit) : (int * string) is block { -// var acc : int := 0 ; -// var st : string := "" ; -// var mymap : map(string,int) := map "one" -> 1 ; "two" -> 2 ; "three" -> 3 end ; -// for k -> v : (string * int) in map mymap -// begin -// acc := acc + v ; -// st := k^st ; -// end -// } with (acc, st) +function for_collection_map_kv (var nee : unit) : (int * string) is block { + var acc : int := 0 ; + var st : string := "" ; + var mymap : map(string,int) := map "1" -> 1 ; "2" -> 2 ; "3" -> 3 end ; + for k -> v : (string * int) in map mymap + begin + acc := acc + v ; + st := st^k ; + end +} with (acc, st) + +function for_collection_map_k (var nee : unit) : string is block { + var st : string := "" ; + var mymap : map(string,int) := map "1" -> 1 ; "2" -> 2 ; "3" -> 3 end ; + for k : string in map mymap + begin + st := st^k ; + end +} with st 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 734b28dba..8a644d1b2 100644 --- a/src/test/integration_tests.ml +++ b/src/test/integration_tests.ml @@ -667,6 +667,12 @@ let loop () : unit result = let%bind () = let expected = e_pair (e_int 6) (e_string "totototo") in expect_eq program "for_collection_set" input expected in + let%bind () = + let expected = e_pair (e_int 6) (e_string "123") in + expect_eq program "for_collection_map_kv" input expected in + let%bind () = + let expected = (e_string "123") in + expect_eq program "for_collection_map_k" input expected in let%bind () = let expected = (e_int 0) in expect_eq program "for_collection_empty" input expected in