improving simplifier
This commit is contained in:
parent
ba00db2b4c
commit
e86c92bc3b
@ -1029,9 +1029,7 @@ and simpl_for_int : Raw.for_int -> (_ -> expression result) result = fun fi ->
|
|||||||
```
|
```
|
||||||
|
|
||||||
We are performing the following steps:
|
We are performing the following steps:
|
||||||
1) Filtering out of the body all the constructions that can't
|
1) Simplifying the for body using ̀simpl_block`
|
||||||
alter the environment (assignements and map/set patches)
|
|
||||||
and simplifying only those.
|
|
||||||
|
|
||||||
2) Detect the free variables and build a list of their names
|
2) Detect the free variables and build a list of their names
|
||||||
(myint and myst in the previous example)
|
(myint and myst in the previous example)
|
||||||
@ -1074,76 +1072,56 @@ 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 | _ ->
|
match fc.collection with | Map _ -> fail @@ unsupported_for_collect_map fc.block | _ ->
|
||||||
let statements = npseq_to_list fc.block.value.statements in
|
|
||||||
(* STEP 1 *)
|
(* STEP 1 *)
|
||||||
let filter_assignments (el : Raw.statement) : Raw.instruction option =
|
let%bind for_body = simpl_block fc.block.value in
|
||||||
match el with
|
let%bind for_body = for_body None in
|
||||||
| Raw.Instr (Assign _ as i) -> Some i
|
|
||||||
| _ -> None in
|
|
||||||
let assign_instrs = List.filter_map filter_assignments statements in
|
|
||||||
let%bind assign_instrs' = bind_map_list
|
|
||||||
(fun el ->
|
|
||||||
let%bind assign' = simpl_instruction el in
|
|
||||||
let%bind assign' = assign' None in
|
|
||||||
ok @@ assign')
|
|
||||||
assign_instrs in
|
|
||||||
(* STEP 2 *)
|
(* STEP 2 *)
|
||||||
let captured_name_list = List.filter_map
|
let%bind captured_name_list = Self_ast_simplified.fold_expression
|
||||||
(fun ass_exp ->
|
(fun (prev : type_name list) (ass_exp : expression) ->
|
||||||
match ass_exp.expression with
|
match ass_exp.expression with
|
||||||
| E_assign ( name, _ , _ ) -> Some name
|
| E_assign ( name , _ , _ ) -> ok (name::prev)
|
||||||
| _ -> None )
|
| _ -> ok prev )
|
||||||
assign_instrs' in
|
[]
|
||||||
|
for_body in
|
||||||
(* STEP 3 *)
|
(* STEP 3 *)
|
||||||
let add_to_record (prev: expression type_name_map) (captured_name: string) =
|
let add_to_record (prev: expression type_name_map) (captured_name: string) =
|
||||||
SMap.add captured_name (e_variable captured_name) prev in
|
SMap.add captured_name (e_variable captured_name) prev in
|
||||||
let init_record = e_record (List.fold_left add_to_record SMap.empty captured_name_list) in
|
let init_record = e_record (List.fold_left add_to_record SMap.empty captured_name_list) in
|
||||||
(* STEP 4 *)
|
(* STEP 4 *)
|
||||||
let%bind for_body = simpl_block fc.block.value in
|
|
||||||
let%bind for_body = for_body None in
|
|
||||||
let replace exp =
|
let replace exp =
|
||||||
(* TODO: map and set updated/remove must also be captured *)
|
|
||||||
match exp.expression with
|
match exp.expression with
|
||||||
(* replace references to fold accumulator as rhs *)
|
(* replace references to fold accumulator as rhs *)
|
||||||
| E_assign ( name , path , expr ) -> (
|
| E_assign ( name , path , expr ) -> (
|
||||||
match path with
|
match path with
|
||||||
| [] -> ok @@ e_assign "#COMPILER#acc" [Access_record name] expr
|
| [] -> ok @@ e_assign "#COMPILER#acc" [Access_record name] expr
|
||||||
(* This fails for deep accesses, see LIGO-131 LIGO-134 *)
|
(* This fails for deep accesses, see LIGO-131 LIGO-134 *)
|
||||||
| _ ->
|
| _ ->
|
||||||
(* ok @@ e_assign "#COMPILER#acc" ((Access_record name)::path) expr) *)
|
(* ok @@ e_assign "#COMPILER#acc" ((Access_record name)::path) expr) *)
|
||||||
fail @@ unsupported_deep_access_for_collection fc.block )
|
fail @@ unsupported_deep_access_for_collection fc.block )
|
||||||
| E_variable name -> (
|
| E_variable name -> (
|
||||||
match fc.collection with
|
if (List.mem name captured_name_list) then
|
||||||
|
(* replace references to fold accumulator as lhs *)
|
||||||
|
ok @@ e_accessor (e_variable "#COMPILER#acc") [Access_record name]
|
||||||
|
else match fc.collection with
|
||||||
(* loop on map *)
|
(* loop on map *)
|
||||||
| Map _ ->
|
| Map _ ->
|
||||||
let k' = e_variable "#COMPILER#collec_elt_k" in
|
let k' = e_variable "#COMPILER#collec_elt_k" in
|
||||||
let v' = e_variable "#COMPILER#collec_elt_v" in
|
if ( name = fc.var.value ) then
|
||||||
( match fc.bind_to with
|
ok @@ k' (* replace references to the the key *)
|
||||||
| Some (_,v) ->
|
else (
|
||||||
if ( name = fc.var.value ) then
|
match fc.bind_to with
|
||||||
ok @@ k' (* replace references to the the key *)
|
| Some (_,v) ->
|
||||||
else if ( name = v.value ) then
|
let v' = e_variable "#COMPILER#collec_elt_v" in
|
||||||
ok @@ v' (* replace references to the the value *)
|
if ( name = v.value ) then
|
||||||
else if (List.mem name captured_name_list) then
|
ok @@ v' (* replace references to the the value *)
|
||||||
(* replace references to fold accumulator as lhs *)
|
else ok @@ exp
|
||||||
ok @@ e_accessor (e_variable "#COMPILER#acc") [Access_record name]
|
| None -> ok @@ exp
|
||||||
else ok @@ exp
|
|
||||||
| None ->
|
|
||||||
if ( name = fc.var.value ) then
|
|
||||||
ok @@ k' (* replace references to the key *)
|
|
||||||
else if (List.mem name captured_name_list) then
|
|
||||||
(* replace references to fold accumulator as lhs *)
|
|
||||||
ok @@ e_accessor (e_variable "#COMPILER#acc") [Access_record name]
|
|
||||||
else ok @@ exp
|
|
||||||
)
|
)
|
||||||
(* loop on set or list *)
|
(* loop on set or list *)
|
||||||
| (Set _ | List _) ->
|
| (Set _ | List _) ->
|
||||||
if (name = fc.var.value ) then
|
if (name = fc.var.value ) then
|
||||||
(* replace references to the collection element *)
|
(* replace references to the collection element *)
|
||||||
ok @@ (e_variable "#COMPILER#collec_elt")
|
ok @@ (e_variable "#COMPILER#collec_elt")
|
||||||
else if (List.mem name captured_name_list) then
|
|
||||||
(* replace references to fold accumulator as lhs *)
|
|
||||||
ok @@ e_accessor (e_variable "#COMPILER#acc") [Access_record name]
|
|
||||||
else ok @@ exp
|
else ok @@ exp
|
||||||
)
|
)
|
||||||
| _ -> ok @@ exp in
|
| _ -> ok @@ exp in
|
||||||
|
Loading…
Reference in New Issue
Block a user