ligo/src/passes/4-imperative_to_sugar/imperative_to_sugar.ml

187 lines
7.4 KiB
OCaml
Raw Normal View History

module I = Ast_imperative
module O = Ast_sugar
2020-03-13 02:20:39 +04:00
open Trace
let rec compile_type_expression : I.type_expression -> O.type_expression result =
2020-03-13 02:20:39 +04:00
fun te ->
let return te = ok @@ O.make_t te in
match te.type_content with
| I.T_sum sum ->
let sum = I.CMap.to_kv_list sum in
let%bind sum =
bind_map_list (fun (k,v) ->
let%bind v = compile_type_expression v in
2020-03-13 02:20:39 +04:00
ok @@ (k,v)
) sum
in
return @@ O.T_sum (O.CMap.of_list sum)
| I.T_record record ->
let record = I.LMap.to_kv_list record in
let%bind record =
bind_map_list (fun (k,v) ->
let%bind v = compile_type_expression v in
2020-03-13 02:20:39 +04:00
ok @@ (k,v)
) record
in
return @@ O.T_record (O.LMap.of_list record)
| I.T_arrow {type1;type2} ->
let%bind type1 = compile_type_expression type1 in
let%bind type2 = compile_type_expression type2 in
2020-03-13 02:20:39 +04:00
return @@ T_arrow {type1;type2}
| I.T_variable type_variable -> return @@ T_variable type_variable
| I.T_constant type_constant -> return @@ T_constant type_constant
| I.T_operator type_operator ->
let%bind type_operator = compile_type_operator type_operator in
2020-03-13 02:20:39 +04:00
return @@ T_operator type_operator
and compile_type_operator : I.type_operator -> O.type_operator result =
2020-03-13 02:20:39 +04:00
fun t_o ->
match t_o with
| TC_contract c ->
let%bind c = compile_type_expression c in
2020-03-13 02:20:39 +04:00
ok @@ O.TC_contract c
| TC_option o ->
let%bind o = compile_type_expression o in
2020-03-13 02:20:39 +04:00
ok @@ O.TC_option o
| TC_list l ->
let%bind l = compile_type_expression l in
2020-03-13 02:20:39 +04:00
ok @@ O.TC_list l
| TC_set s ->
let%bind s = compile_type_expression s in
2020-03-13 02:20:39 +04:00
ok @@ O.TC_set s
| TC_map (k,v) ->
let%bind (k,v) = bind_map_pair compile_type_expression (k,v) in
2020-03-13 02:20:39 +04:00
ok @@ O.TC_map (k,v)
| TC_big_map (k,v) ->
let%bind (k,v) = bind_map_pair compile_type_expression (k,v) in
2020-03-13 02:20:39 +04:00
ok @@ O.TC_big_map (k,v)
| TC_arrow (i,o) ->
let%bind (i,o) = bind_map_pair compile_type_expression (i,o) in
2020-03-13 02:20:39 +04:00
ok @@ O.TC_arrow (i,o)
let rec compile_expression : I.expression -> O.expression result =
2020-03-13 02:20:39 +04:00
fun e ->
let return expr = ok @@ O.make_expr ~loc:e.location expr in
match e.expression_content with
| I.E_literal literal -> return @@ O.E_literal literal
| I.E_constant {cons_name;arguments} ->
let%bind arguments = bind_map_list compile_expression arguments in
2020-03-13 02:20:39 +04:00
return @@ O.E_constant {cons_name;arguments}
| I.E_variable name -> return @@ O.E_variable name
| I.E_application {expr1;expr2} ->
let%bind expr1 = compile_expression expr1 in
let%bind expr2 = compile_expression expr2 in
2020-03-13 02:20:39 +04:00
return @@ O.E_application {expr1; expr2}
| I.E_lambda lambda ->
let%bind lambda = compile_lambda lambda in
2020-03-13 02:20:39 +04:00
return @@ O.E_lambda lambda
| I.E_recursive {fun_name;fun_type;lambda} ->
let%bind fun_type = compile_type_expression fun_type in
let%bind lambda = compile_lambda lambda in
2020-03-13 02:20:39 +04:00
return @@ O.E_recursive {fun_name;fun_type;lambda}
| I.E_let_in {let_binder;mut=_;inline;rhs;let_result} ->
2020-03-13 02:20:39 +04:00
let (binder,ty_opt) = let_binder in
let%bind ty_opt = bind_map_option compile_type_expression ty_opt in
let%bind rhs = compile_expression rhs in
let%bind let_result = compile_expression let_result in
2020-03-13 02:20:39 +04:00
return @@ O.E_let_in {let_binder=(binder,ty_opt);inline;rhs;let_result}
| I.E_skip -> return @@ O.E_skip
| I.E_constructor {constructor;element} ->
let%bind element = compile_expression element in
2020-03-13 02:20:39 +04:00
return @@ O.E_constructor {constructor;element}
| I.E_matching {matchee; cases} ->
let%bind matchee = compile_expression matchee in
let%bind cases = compile_matching cases in
2020-03-13 02:20:39 +04:00
return @@ O.E_matching {matchee;cases}
| I.E_record record ->
let record = I.LMap.to_kv_list record in
let%bind record =
bind_map_list (fun (k,v) ->
let%bind v =compile_expression v in
2020-03-13 02:20:39 +04:00
ok @@ (k,v)
) record
in
return @@ O.E_record (O.LMap.of_list record)
| I.E_record_accessor {expr;label} ->
let%bind expr = compile_expression expr in
2020-03-13 02:20:39 +04:00
return @@ O.E_record_accessor {expr;label}
| I.E_record_update {record;path;update} ->
let%bind record = compile_expression record in
let%bind update = compile_expression update in
2020-03-13 02:20:39 +04:00
return @@ O.E_record_update {record;path;update}
| I.E_map map ->
let%bind map = bind_map_list (
bind_map_pair compile_expression
2020-03-13 02:20:39 +04:00
) map
in
return @@ O.E_map map
| I.E_big_map big_map ->
let%bind big_map = bind_map_list (
bind_map_pair compile_expression
2020-03-13 02:20:39 +04:00
) big_map
in
return @@ O.E_big_map big_map
| I.E_list lst ->
let%bind lst = bind_map_list compile_expression lst in
2020-03-13 02:20:39 +04:00
return @@ O.E_list lst
| I.E_set set ->
let%bind set = bind_map_list compile_expression set in
2020-03-13 02:20:39 +04:00
return @@ O.E_set set
| I.E_look_up look_up ->
let%bind look_up = bind_map_pair compile_expression look_up in
2020-03-13 02:20:39 +04:00
return @@ O.E_look_up look_up
| I.E_ascription {anno_expr; type_annotation} ->
let%bind anno_expr = compile_expression anno_expr in
let%bind type_annotation = compile_type_expression type_annotation in
2020-03-13 02:20:39 +04:00
return @@ O.E_ascription {anno_expr; type_annotation}
and compile_lambda : I.lambda -> O.lambda result =
2020-03-13 02:20:39 +04:00
fun {binder;input_type;output_type;result}->
let%bind input_type = bind_map_option compile_type_expression input_type in
let%bind output_type = bind_map_option compile_type_expression output_type in
let%bind result = compile_expression result in
2020-03-13 02:20:39 +04:00
ok @@ O.{binder;input_type;output_type;result}
and compile_matching : I.matching_expr -> O.matching_expr result =
2020-03-13 02:20:39 +04:00
fun m ->
match m with
| I.Match_bool {match_true;match_false} ->
let%bind match_true = compile_expression match_true in
let%bind match_false = compile_expression match_false in
2020-03-13 02:20:39 +04:00
ok @@ O.Match_bool {match_true;match_false}
| I.Match_list {match_nil;match_cons} ->
let%bind match_nil = compile_expression match_nil in
2020-03-13 02:20:39 +04:00
let (hd,tl,expr,tv) = match_cons in
let%bind expr = compile_expression expr in
2020-03-13 02:20:39 +04:00
ok @@ O.Match_list {match_nil; match_cons=(hd,tl,expr,tv)}
| I.Match_option {match_none;match_some} ->
let%bind match_none = compile_expression match_none in
2020-03-13 02:20:39 +04:00
let (n,expr,tv) = match_some in
let%bind expr = compile_expression expr in
2020-03-13 02:20:39 +04:00
ok @@ O.Match_option {match_none; match_some=(n,expr,tv)}
| I.Match_tuple ((lst,expr), tv) ->
let%bind expr = compile_expression expr in
2020-03-13 02:20:39 +04:00
ok @@ O.Match_tuple ((lst,expr), tv)
| I.Match_variant (lst,tv) ->
let%bind lst = bind_map_list (
fun ((c,n),expr) ->
let%bind expr = compile_expression expr in
2020-03-13 02:20:39 +04:00
ok @@ ((c,n),expr)
) lst
in
ok @@ O.Match_variant (lst,tv)
let compile_declaration : I.declaration Location.wrap -> _ =
2020-03-13 02:20:39 +04:00
fun {wrap_content=declaration;location} ->
let return decl = ok @@ Location.wrap ~loc:location decl in
match declaration with
| I.Declaration_constant (n, te_opt, inline, expr) ->
let%bind expr = compile_expression expr in
let%bind te_opt = bind_map_option compile_type_expression te_opt in
2020-03-13 02:20:39 +04:00
return @@ O.Declaration_constant (n, te_opt, inline, expr)
| I.Declaration_type (n, te) ->
let%bind te = compile_type_expression te in
2020-03-13 02:20:39 +04:00
return @@ O.Declaration_type (n,te)
let compile_program : I.program -> O.program result =
2020-03-13 02:20:39 +04:00
fun p ->
bind_map_list compile_declaration p