use intermediary tuple access to get key and value for maps. add tests.

This commit is contained in:
Lesenechal Remi 2019-10-29 15:43:00 +01:00
parent fd901548af
commit 402d849cec
3 changed files with 33 additions and 23 deletions

View File

@ -138,16 +138,6 @@ module Errors = struct
] in ] in
error ~data title message 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 *) (* Logging *)
let simplifying_instruction t = 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 -> 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 *) (* STEP 1 *)
let%bind for_body = simpl_block fc.block.value in let%bind for_body = simpl_block fc.block.value in
let%bind for_body = for_body None 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 let ( arg_access: Types.access_path -> expression ) = e_accessor (e_variable "arguments") in
( match fc.collection with ( match fc.collection with
| Map _ -> | 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_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#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_k", None) collec_elt_v @@
e_let_in ("#COMPILER#collec_elt_v", None) collec_elt_k (for_body) e_let_in ("#COMPILER#collec_elt_v", None) collec_elt_k (for_body)
| _ -> | _ ->

View File

@ -116,16 +116,25 @@ function for_collection_empty (var nee : unit) : int is block {
end end
} with acc } with acc
// function for_collection_map (var nee : unit) : (int * string) is block { function for_collection_map_kv (var nee : unit) : (int * string) is block {
// var acc : int := 0 ; var acc : int := 0 ;
// var st : string := "" ; var st : string := "" ;
// var mymap : map(string,int) := map "one" -> 1 ; "two" -> 2 ; "three" -> 3 end ; var mymap : map(string,int) := map "1" -> 1 ; "2" -> 2 ; "3" -> 3 end ;
// for k -> v : (string * int) in map mymap for k -> v : (string * int) in map mymap
// begin begin
// acc := acc + v ; acc := acc + v ;
// st := k^st ; st := st^k ;
// end end
// } with (acc, st) } 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 { function dummy (const n : nat) : nat is block {
while (False) block { skip } while (False) block { skip }

View File

@ -667,6 +667,12 @@ let loop () : unit result =
let%bind () = let%bind () =
let expected = e_pair (e_int 6) (e_string "totototo") in let expected = e_pair (e_int 6) (e_string "totototo") in
expect_eq program "for_collection_set" input expected 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%bind () =
let expected = (e_int 0) in let expected = (e_int 0) in
expect_eq program "for_collection_empty" input expected in expect_eq program "for_collection_empty" input expected in