From d6448727290fb0192fbef50a5bf99e4df59ad45c Mon Sep 17 00:00:00 2001 From: Pierre-Emmanuel Wulfman Date: Fri, 29 May 2020 17:49:37 +0200 Subject: [PATCH] version 2 --- src/passes/3-self_ast_imperative/helpers.ml | 8 ++++---- .../4-imperative_to_sugar/imperative_to_sugar.ml | 10 ++++++---- src/passes/5-self_ast_sugar/helpers.ml | 8 ++++---- src/passes/6-sugar_to_core/sugar_to_core.ml | 16 ++++++++++++---- src/stages/1-ast_imperative/PP.ml | 2 +- src/stages/1-ast_imperative/combinators.ml | 2 +- src/stages/1-ast_imperative/combinators.mli | 2 +- src/stages/1-ast_imperative/types.ml | 2 +- src/stages/2-ast_sugar/PP.ml | 2 +- src/stages/2-ast_sugar/combinators.ml | 2 +- src/stages/2-ast_sugar/combinators.mli | 2 +- src/stages/2-ast_sugar/types.ml | 2 +- 12 files changed, 34 insertions(+), 24 deletions(-) diff --git a/src/passes/3-self_ast_imperative/helpers.ml b/src/passes/3-self_ast_imperative/helpers.ml index 66e0ef7d2..79e3b91c5 100644 --- a/src/passes/3-self_ast_imperative/helpers.ml +++ b/src/passes/3-self_ast_imperative/helpers.ml @@ -210,10 +210,10 @@ let rec map_expression : exp_mapper -> expression -> expression result = fun f e let%bind tuple = self tuple in return @@ E_tuple_accessor {tuple;path} ) - | E_tuple_destruct {tuple;fields;next} -> ( + | E_tuple_destruct {tuple;fields;field_types;next} -> ( let%bind tuple = self tuple in let%bind next = self next in - return @@ E_tuple_destruct {tuple;fields;next} + return @@ E_tuple_destruct {tuple;fields;field_types;next} ) | E_constructor c -> ( let%bind e' = self c.element in @@ -394,10 +394,10 @@ let rec fold_map_expression : 'a fold_mapper -> 'a -> expression -> ('a * expres let%bind (res, tuple) = self init' tuple in ok (res, return @@ E_tuple_accessor {tuple; path}) ) - | E_tuple_destruct {tuple;fields;next} -> ( + | E_tuple_destruct {tuple;fields;field_types;next} -> ( let%bind (res,tuple) = self init' tuple in let%bind (res,next) = self res next in - ok (res, return @@ E_tuple_destruct {tuple;fields;next}) + ok (res, return @@ E_tuple_destruct {tuple;fields;field_types;next}) ) | E_constructor c -> ( let%bind (res,e') = self init' c.element in diff --git a/src/passes/4-imperative_to_sugar/imperative_to_sugar.ml b/src/passes/4-imperative_to_sugar/imperative_to_sugar.ml index 6ee20e2cd..fda433669 100644 --- a/src/passes/4-imperative_to_sugar/imperative_to_sugar.ml +++ b/src/passes/4-imperative_to_sugar/imperative_to_sugar.ml @@ -337,10 +337,11 @@ and compile_expression' : I.expression -> (O.expression option -> O.expression) let%bind tuple = compile_expression tuple in let%bind update = compile_expression update in return @@ O.e_tuple_update ~loc tuple path update - | I.E_tuple_destruct {tuple; fields; next} -> + | I.E_tuple_destruct {tuple; fields; field_types; next} -> let%bind tuple = compile_expression tuple in let%bind next = compile_expression next in - return @@ O.e_tuple_destruct ~loc tuple fields next + let%bind field_types = bind_map_option (bind_map_list compile_type_expression) field_types in + return @@ O.e_tuple_destruct ~loc tuple fields field_types next | I.E_assign {variable; access_path; expression} -> let accessor ?loc s a = match a with @@ -730,10 +731,11 @@ let rec uncompile_expression' : O.expression -> I.expression result = let%bind tuple = uncompile_expression' tuple in let%bind update = uncompile_expression' update in return @@ I.E_tuple_update {tuple;path;update} - | O.E_tuple_destruct {tuple; fields; next} -> + | O.E_tuple_destruct {tuple; fields; field_types; next} -> let%bind tuple = uncompile_expression' tuple in let%bind next = uncompile_expression' next in - return @@ I.E_tuple_destruct {tuple; fields; next} + let%bind field_types = bind_map_option (bind_map_list uncompile_type_expression) field_types in + return @@ I.E_tuple_destruct {tuple; fields; field_types; next} | O.E_map map -> let%bind map = bind_map_list ( bind_map_pair uncompile_expression' diff --git a/src/passes/5-self_ast_sugar/helpers.ml b/src/passes/5-self_ast_sugar/helpers.ml index 2149ea9f8..95d35d356 100644 --- a/src/passes/5-self_ast_sugar/helpers.ml +++ b/src/passes/5-self_ast_sugar/helpers.ml @@ -230,10 +230,10 @@ let rec map_expression : exp_mapper -> expression -> expression result = fun f e let%bind tuple = self tuple in return @@ E_tuple_accessor {tuple;path} ) - | E_tuple_destruct {tuple;fields;next} -> ( + | E_tuple_destruct {tuple;fields;field_types;next} -> ( let%bind tuple = self tuple in let%bind next = self next in - return @@ E_tuple_destruct {tuple;fields;next} + return @@ E_tuple_destruct {tuple;fields;field_types;next} ) | E_literal _ | E_variable _ | E_skip as e' -> return e' @@ -363,10 +363,10 @@ let rec fold_map_expression : 'a fold_mapper -> 'a -> expression -> ('a * expres let%bind (res, tuple) = self init' tuple in ok (res, return @@ E_tuple_accessor {tuple; path}) ) - | E_tuple_destruct {tuple;fields;next} -> ( + | E_tuple_destruct {tuple;fields;field_types;next} -> ( let%bind (res,tuple) = self init' tuple in let%bind (res,next) = self res next in - ok (res, return @@ E_tuple_destruct {tuple;fields;next}) + ok (res, return @@ E_tuple_destruct {tuple;fields;field_types;next}) ) | E_constructor c -> ( let%bind (res,e') = self init' c.element in diff --git a/src/passes/6-sugar_to_core/sugar_to_core.ml b/src/passes/6-sugar_to_core/sugar_to_core.ml index 22a89faa2..05d2600da 100644 --- a/src/passes/6-sugar_to_core/sugar_to_core.ml +++ b/src/passes/6-sugar_to_core/sugar_to_core.ml @@ -193,14 +193,22 @@ let rec compile_expression : I.expression -> O.expression result = let path = O.Label (string_of_int path) in let%bind update = compile_expression update in return @@ O.E_record_update {record;path;update} - | I.E_tuple_destruct {tuple; fields; next} -> + | I.E_tuple_destruct {tuple; fields; field_types; next} -> + let combine fields field_types = + match field_types with + Some ft -> List.combine fields @@ List.map (fun x -> Some x) ft + | None -> List.map (fun x -> (x, None)) fields + in let%bind record = compile_expression tuple in let%bind next = compile_expression next in - let aux ((index,e) : int * _ ) (field: I.expression_variable) = - let f = fun expr -> O.e_let_in (field, None) false (O.e_record_accessor record (string_of_int index)) expr in + let%bind field_types = bind_map_option (bind_map_list idle_type_expression) field_types in + let aux ((index,e) : int * _ ) (field: O.expression_variable * O.type_expression option) = + let f = fun expr -> O.e_let_in field false (O.e_record_accessor record (string_of_int index)) expr in (index+1, fun expr -> e (f expr)) in - let (_,header) = List.fold_left aux (0, fun e -> e) fields in + let (_,header) = List.fold_left aux (0, fun e -> e) @@ + combine fields field_types + in ok @@ header next and compile_lambda : I.lambda -> O.lambda result = diff --git a/src/stages/1-ast_imperative/PP.ml b/src/stages/1-ast_imperative/PP.ml index 3147e4844..081e5743a 100644 --- a/src/stages/1-ast_imperative/PP.ml +++ b/src/stages/1-ast_imperative/PP.ml @@ -136,7 +136,7 @@ and expression_content ppf (ec : expression_content) = fprintf ppf "%a.%d" expression ta.tuple ta.path | E_tuple_update {tuple; path; update} -> fprintf ppf "{ %a with %d = %a }" expression tuple path expression update - | E_tuple_destruct {tuple; fields; next} -> + | E_tuple_destruct {tuple; fields; next; _} -> fprintf ppf "{ let (%a) = %a in %a" (list_sep_d expression_variable) fields expression tuple diff --git a/src/stages/1-ast_imperative/combinators.ml b/src/stages/1-ast_imperative/combinators.ml index 51a3330ae..586c36c07 100644 --- a/src/stages/1-ast_imperative/combinators.ml +++ b/src/stages/1-ast_imperative/combinators.ml @@ -140,7 +140,7 @@ let e_annotation ?loc anno_expr ty = make_e ?loc @@ E_ascription {anno_expr; typ let e_tuple ?loc lst : expression = make_e ?loc @@ E_tuple lst let e_tuple_accessor ?loc tuple path : expression = make_e ?loc @@ E_tuple_accessor {tuple; path} let e_tuple_update ?loc tuple path update : expression = make_e ?loc @@ E_tuple_update {tuple; path; update} -let e_tuple_destruct ?loc tuple fields next = make_e ?loc @@ E_tuple_destruct {tuple; fields; next} +let e_tuple_destruct ?loc tuple fields field_types next = make_e ?loc @@ E_tuple_destruct {tuple; fields; field_types; next} let e_pair ?loc a b : expression = e_tuple ?loc [a;b] let e_cond ?loc condition then_clause else_clause = make_e ?loc @@ E_cond {condition;then_clause;else_clause} diff --git a/src/stages/1-ast_imperative/combinators.mli b/src/stages/1-ast_imperative/combinators.mli index 8c8047179..68272942c 100644 --- a/src/stages/1-ast_imperative/combinators.mli +++ b/src/stages/1-ast_imperative/combinators.mli @@ -105,7 +105,7 @@ val e_annotation : ?loc:Location.t -> expression -> type_expression -> expressio val e_tuple : ?loc:Location.t -> expression list -> expression val e_tuple_accessor : ?loc:Location.t -> expression -> int -> expression val e_tuple_update : ?loc:Location.t -> expression -> int -> expression -> expression -val e_tuple_destruct : ?loc:Location.t -> expression -> expression_variable list -> expression -> expression +val e_tuple_destruct : ?loc:Location.t -> expression -> expression_variable list -> type_expression list option -> expression -> expression val e_pair : ?loc:Location.t -> expression -> expression -> expression val e_cond: ?loc:Location.t -> expression -> expression -> expression -> expression diff --git a/src/stages/1-ast_imperative/types.ml b/src/stages/1-ast_imperative/types.ml index 1989c9e7f..19ab16d58 100644 --- a/src/stages/1-ast_imperative/types.ml +++ b/src/stages/1-ast_imperative/types.ml @@ -145,7 +145,7 @@ and sequence = { and tuple_accessor = {tuple: expression; path: int} and tuple_update = {tuple: expression; path: int ; update: expression} -and tuple_destruct = {tuple: expression; fields : expression_variable list; next : expression} +and tuple_destruct = {tuple: expression; fields : expression_variable list; field_types : type_expression list option; next : expression} and assign = { variable : expression_variable; diff --git a/src/stages/2-ast_sugar/PP.ml b/src/stages/2-ast_sugar/PP.ml index 394115870..31b991f07 100644 --- a/src/stages/2-ast_sugar/PP.ml +++ b/src/stages/2-ast_sugar/PP.ml @@ -129,7 +129,7 @@ and expression_content ppf (ec : expression_content) = fprintf ppf "%a.%d" expression ta.tuple ta.path | E_tuple_update {tuple; path; update} -> fprintf ppf "{ %a with %d = %a }" expression tuple path expression update - | E_tuple_destruct {tuple; fields; next} -> + | E_tuple_destruct {tuple; fields; next; _} -> fprintf ppf "{ let (%a) = %a in %a" (list_sep_d expression_variable) fields expression tuple diff --git a/src/stages/2-ast_sugar/combinators.ml b/src/stages/2-ast_sugar/combinators.ml index 8d45a624d..dcf8ed421 100644 --- a/src/stages/2-ast_sugar/combinators.ml +++ b/src/stages/2-ast_sugar/combinators.ml @@ -129,7 +129,7 @@ let e_annotation ?loc anno_expr ty = make_e ?loc @@ E_ascription {anno_expr; typ let e_tuple ?loc lst : expression = make_e ?loc @@ E_tuple lst let e_tuple_accessor ?loc tuple path = make_e ?loc @@ E_tuple_accessor {tuple; path} let e_tuple_update ?loc tuple path update = make_e ?loc @@ E_tuple_update {tuple; path; update} -let e_tuple_destruct ?loc tuple fields next = make_e ?loc @@ E_tuple_destruct {tuple; fields; next} +let e_tuple_destruct ?loc tuple fields field_types next = make_e ?loc @@ E_tuple_destruct {tuple; fields; field_types; next} let e_pair ?loc a b : expression = e_tuple ?loc [a;b] let e_cond ?loc condition then_clause else_clause = make_e ?loc @@ E_cond {condition;then_clause;else_clause} diff --git a/src/stages/2-ast_sugar/combinators.mli b/src/stages/2-ast_sugar/combinators.mli index bdf8b2b5e..94529b898 100644 --- a/src/stages/2-ast_sugar/combinators.mli +++ b/src/stages/2-ast_sugar/combinators.mli @@ -85,7 +85,7 @@ val e_annotation : ?loc:Location.t -> expression -> type_expression -> expressio val e_tuple : ?loc:Location.t -> expression list -> expression val e_tuple_accessor : ?loc:Location.t -> expression -> int -> expression val e_tuple_update : ?loc:Location.t -> expression -> int -> expression -> expression -val e_tuple_destruct : ?loc:Location.t -> expression -> expression_variable list -> expression -> expression +val e_tuple_destruct : ?loc:Location.t -> expression -> expression_variable list -> type_expression list option -> expression -> expression val e_pair : ?loc:Location.t -> expression -> expression -> expression val e_cond: ?loc:Location.t -> expression -> expression -> expression -> expression diff --git a/src/stages/2-ast_sugar/types.ml b/src/stages/2-ast_sugar/types.ml index a24c4ebde..8c3422de6 100644 --- a/src/stages/2-ast_sugar/types.ml +++ b/src/stages/2-ast_sugar/types.ml @@ -139,7 +139,7 @@ and sequence = { and tuple_accessor = {tuple: expression; path: int} and tuple_update = {tuple: expression; path: int ; update: expression} -and tuple_destruct = {tuple: expression; fields : expression_variable list; next : expression} +and tuple_destruct = {tuple: expression; fields : expression_variable list; field_types : type_expression list option; next : expression} and environment_element_definition = | ED_binder