From ddc4b7b7a55bca4f8f2e9ea68e579bd460a79729 Mon Sep 17 00:00:00 2001 From: galfour Date: Mon, 18 Nov 2019 16:10:48 +0100 Subject: [PATCH] add anon functions; remove pre-block declarations; update tests --- src/passes/1-parser/pascaligo/AST.ml | 18 +++-- src/passes/1-parser/pascaligo/AST.mli | 32 ++++---- src/passes/1-parser/pascaligo/Parser.mly | 87 +++++++++++++--------- src/passes/1-parser/pascaligo/ParserLog.ml | 32 +++++--- src/passes/2-simplify/pascaligo.ml | 46 +++++++++--- src/test/contracts/big_map.ligo | 6 +- src/test/contracts/closure-1.ligo | 7 +- src/test/contracts/closure-2.ligo | 9 ++- src/test/contracts/closure-3.ligo | 14 ++-- src/test/contracts/closure.ligo | 11 +-- src/test/contracts/condition.ligo | 6 +- src/test/contracts/deep_access.ligo | 31 ++++---- src/test/contracts/failwith.ligo | 2 +- src/test/contracts/function-complex.ligo | 4 +- src/test/contracts/high-order.ligo | 51 ++++++------- src/test/contracts/lambda.ligo | 5 +- src/test/contracts/list.ligo | 15 ++-- src/test/contracts/map.ligo | 28 +++---- src/test/contracts/match.ligo | 23 +++--- src/test/contracts/option.ligo | 12 ++- src/test/contracts/set_arithmetic-1.ligo | 17 +++-- src/test/contracts/shadow.ligo | 7 +- src/test/contracts/simple_access.ligo | 24 +++--- vendors/ligo-utils/simple-utils/region.ml | 2 + vendors/ligo-utils/simple-utils/region.mli | 5 ++ 25 files changed, 286 insertions(+), 208 deletions(-) diff --git a/src/passes/1-parser/pascaligo/AST.ml b/src/passes/1-parser/pascaligo/AST.ml index 0bc785215..5431362ff 100644 --- a/src/passes/1-parser/pascaligo/AST.ml +++ b/src/passes/1-parser/pascaligo/AST.ml @@ -210,9 +210,9 @@ and type_tuple = (type_expr, comma) nsepseq par reg (* Function and procedure declarations *) -and fun_decl = { +and fun_expr = { kwd_function : kwd_function; - name : variable; + name : variable option; param : parameters; colon : colon; ret_type : type_expr; @@ -221,7 +221,11 @@ and fun_decl = { block : block reg option; kwd_with : kwd_with option; return : expr; - terminator : semi option +} + +and fun_decl = { + fun_expr : fun_expr reg ; + terminator : semi option ; } and parameters = (param_decl, semi) nsepseq par reg @@ -266,12 +270,12 @@ and statement = | Data of data_decl and local_decl = - LocalFun of fun_decl reg | LocalData of data_decl and data_decl = LocalConst of const_decl reg | LocalVar of var_decl reg +| LocalFun of fun_decl reg and var_decl = { kwd_var : kwd_var; @@ -464,6 +468,7 @@ and expr = | EUnit of c_Unit | ETuple of tuple_expr | EPar of expr par reg +| EFun of fun_expr reg and annot_expr = (expr * type_expr) @@ -644,7 +649,8 @@ let rec expr_to_region = function | EUnit region | ECase {region;_} | ECond {region; _} -| EPar {region; _} -> region +| EPar {region; _} +| EFun {region; _} -> region and tuple_expr_to_region {region; _} = region @@ -752,7 +758,7 @@ let pattern_to_region = function | PTuple {region; _} -> region let local_decl_to_region = function - LocalFun {region; _} +| LocalData LocalFun {region; _} | LocalData LocalConst {region; _} | LocalData LocalVar {region; _} -> region diff --git a/src/passes/1-parser/pascaligo/AST.mli b/src/passes/1-parser/pascaligo/AST.mli index 32b2ab453..2d0b0fca8 100644 --- a/src/passes/1-parser/pascaligo/AST.mli +++ b/src/passes/1-parser/pascaligo/AST.mli @@ -201,18 +201,23 @@ and type_tuple = (type_expr, comma) nsepseq par reg (* Function declarations *) -and fun_decl ={ - kwd_function : kwd_function; - name : variable; - param : parameters; - colon : colon; - ret_type : type_expr; - kwd_is : kwd_is; - local_decls : local_decl list; - block : block reg option; - kwd_with : kwd_with option; - return : expr; - terminator : semi option } +and fun_expr = { + kwd_function : kwd_function; + name : variable option; + param : parameters; + colon : colon; + ret_type : type_expr; + kwd_is : kwd_is; + local_decls : local_decl list; + block : block reg option; + kwd_with : kwd_with option; + return : expr; +} + +and fun_decl = { + fun_expr : fun_expr reg ; + terminator : semi option ; +} and parameters = (param_decl, semi) nsepseq par reg @@ -256,12 +261,12 @@ and statement = | Data of data_decl and local_decl = - LocalFun of fun_decl reg | LocalData of data_decl and data_decl = LocalConst of const_decl reg | LocalVar of var_decl reg +| LocalFun of fun_decl reg and var_decl = { kwd_var : kwd_var; @@ -454,6 +459,7 @@ and expr = | EUnit of c_Unit | ETuple of tuple_expr | EPar of expr par reg +| EFun of fun_expr reg and annot_expr = (expr * type_expr) diff --git a/src/passes/1-parser/pascaligo/Parser.mly b/src/passes/1-parser/pascaligo/Parser.mly index 63b0d6294..f17611b76 100644 --- a/src/passes/1-parser/pascaligo/Parser.mly +++ b/src/passes/1-parser/pascaligo/Parser.mly @@ -239,17 +239,11 @@ field_decl: and value = {field_name = $1; colon = $2; field_type = $3} in {region; value} } -(* Function declarations *) - -fun_decl: - Function fun_name parameters COLON type_expr Is - seq(local_decl) +fun_expr: + Function option(fun_name) parameters COLON type_expr Is block - With expr option(SEMI) { - let stop = - match $11 with - Some region -> region - | None -> expr_to_region $10 in + With expr { + let stop = expr_to_region $9 in let region = cover $1 stop and value = { kwd_function = $1; @@ -258,18 +252,15 @@ fun_decl: colon = $4; ret_type = $5; kwd_is = $6; - local_decls = $7; - block = Some $8; - kwd_with = Some $9; - return = $10; - terminator = $11} + local_decls = []; + block = Some $7; + kwd_with = Some $8; + return = $9; + } in {region;value}} - | Function fun_name parameters COLON type_expr Is - expr option(SEMI) { - let stop = - match $8 with - Some region -> region - | None -> expr_to_region $7 in + | Function option(fun_name) parameters COLON type_expr Is + expr { + let stop = expr_to_region $7 in let region = cover $1 stop and value = { kwd_function = $1; @@ -282,10 +273,36 @@ fun_decl: block = None; kwd_with = None; return = $7; - terminator = $8; } in {region;value}} + + +(* Function declarations *) + +fun_decl: + fun_expr option(SEMI) { + let stop = + match $2 with + Some region -> region + | None -> $1.region in + let region = cover $1.region stop + and value = { + fun_expr = $1; + terminator = $2; + } + in {region;value}} + +open_fun_decl: + fun_expr { + let region = $1.region + and value = { + fun_expr = $1; + terminator = None; + } + in {region;value}} + + parameters: par(nsepseq(param_decl,SEMI)) { $1 } @@ -341,6 +358,7 @@ statement: open_data_decl: open_const_decl { LocalConst $1 } | open_var_decl { LocalVar $1 } +| open_fun_decl { LocalFun $1 } open_const_decl: Const unqualified_decl(EQ) { @@ -370,13 +388,13 @@ open_var_decl: terminator = None} in {region; value}} -local_decl: - fun_decl { LocalFun $1 } -| data_decl { LocalData $1 } +/* local_decl: */ +/* fun_decl { LocalFun $1 } */ +/* | data_decl { LocalData $1 } */ -data_decl: - const_decl { LocalConst $1 } -| var_decl { LocalVar $1 } +/* data_decl: */ +/* const_decl { LocalConst $1 } */ +/* | var_decl { LocalVar $1 } */ unqualified_decl(OP): var COLON type_expr OP expr { @@ -390,12 +408,12 @@ const_decl: } | open_const_decl { $1 } -var_decl: - open_var_decl SEMI { - let var_decl : AST.var_decl = $1.value in - {$1 with value = {var_decl with terminator = Some $2}} - } -| open_var_decl { $1 } +/* var_decl: */ +/* open_var_decl SEMI { */ +/* let var_decl : AST.var_decl = $1.value in */ +/* {$1 with value = {var_decl with terminator = Some $2}} */ +/* } */ +/* | open_var_decl { $1 } */ instruction: conditional { Cond $1 } @@ -683,6 +701,7 @@ expr: case(expr) { ECase ($1 expr_to_region) } | cond_expr { $1 } | disj_expr { $1 } +| fun_expr { EFun $1 } cond_expr: If expr Then expr option(SEMI) Else expr { diff --git a/src/passes/1-parser/pascaligo/ParserLog.ml b/src/passes/1-parser/pascaligo/ParserLog.ml index e75c975c1..6eedd5e1d 100644 --- a/src/passes/1-parser/pascaligo/ParserLog.ml +++ b/src/passes/1-parser/pascaligo/ParserLog.ml @@ -156,12 +156,13 @@ and print_type_tuple buffer {value; _} = print_nsepseq buffer "," print_type_expr inside; print_token buffer rpar ")" -and print_fun_decl buffer {value; _} = +and print_fun_expr buffer {value; _} = let {kwd_function; name; param; colon; ret_type; kwd_is; local_decls; - block; kwd_with; return; terminator} = value in + block; kwd_with; return;} = value in + let anonymous_name = Region.wrap_ghost "#anonymous" in print_token buffer kwd_function "function"; - print_var buffer name; + print_var buffer @@ Simple_utils.Option.unopt ~default:anonymous_name name; print_parameters buffer param; print_token buffer colon ":"; print_type_expr buffer ret_type; @@ -173,7 +174,11 @@ and print_fun_decl buffer {value; _} = print_token buffer kwd_with "with"; | None -> (); print_expr buffer return; - print_terminator buffer terminator + +and print_fun_decl buffer {value; _} = + let {fun_expr ; terminator;} = value in + print_fun_expr buffer fun_expr; + print_terminator buffer terminator; and print_parameters buffer {value; _} = let {lpar; inside; rpar} = value in @@ -225,12 +230,12 @@ and print_local_decls buffer sequence = List.iter (print_local_decl buffer) sequence and print_local_decl buffer = function - LocalFun decl -> print_fun_decl buffer decl | LocalData decl -> print_data_decl buffer decl and print_data_decl buffer = function LocalConst decl -> print_const_decl buffer decl | LocalVar decl -> print_var_decl buffer decl +| LocalFun decl -> print_fun_decl buffer decl and print_var_decl buffer {value; _} = let {kwd_var; name; colon; var_type; @@ -402,6 +407,7 @@ and print_expr buffer = function | EUnit r -> print_token buffer r "Unit" | ETuple e -> print_tuple_expr buffer e | EPar e -> print_par_expr buffer e +| EFun e -> print_fun_expr buffer e and print_annot_expr buffer (expr , type_expr) = print_expr buffer expr; @@ -795,7 +801,7 @@ and pp_declaration buffer ~pad:(_,pc as pad) = function pp_const_decl buffer ~pad value | FunDecl {value; region} -> pp_loc_node buffer ~pad "FunDecl" region; - pp_fun_decl buffer ~pad value + pp_fun_expr buffer ~pad value.fun_expr.value and pp_const_decl buffer ~pad:(_,pc) decl = pp_ident buffer ~pad:(mk_pad 3 0 pc) decl.name; @@ -861,12 +867,13 @@ and pp_type_tuple buffer ~pad:(_,pc) {value; _} = pp_type_expr buffer ~pad:(mk_pad len rank pc) in List.iteri (List.length components |> apply) components -and pp_fun_decl buffer ~pad:(_,pc) decl = +and pp_fun_expr buffer ~pad:(_,pc) decl = let fields = if decl.local_decls = [] then 5 else 6 in let () = let pad = mk_pad fields 0 pc in - pp_ident buffer ~pad decl.name in + let anonymous_name = Region.wrap_ghost "#anonymous" in + pp_ident buffer ~pad @@ Simple_utils.Option.unopt ~default:anonymous_name decl.name in let () = let pad = mk_pad fields 1 pc in pp_node buffer ~pad ""; @@ -1294,9 +1301,6 @@ and pp_local_decls buffer ~pad:(_,pc) decls = in List.iteri (List.length decls |> apply) decls and pp_local_decl buffer ~pad:(_,pc as pad) = function - LocalFun {value; region} -> - pp_loc_node buffer ~pad "LocalFun" region; - pp_fun_decl buffer ~pad value | LocalData data -> pp_node buffer ~pad "LocalData"; pp_data_decl buffer ~pad:(mk_pad 1 0 pc) data @@ -1308,6 +1312,9 @@ and pp_data_decl buffer ~pad = function | LocalVar {value; region} -> pp_loc_node buffer ~pad "LocalVar" region; pp_var_decl buffer ~pad value +| LocalFun {value; region} -> + pp_loc_node buffer ~pad "LocalFun" region; + pp_fun_expr buffer ~pad value.fun_expr.value and pp_var_decl buffer ~pad:(_,pc) decl = pp_ident buffer ~pad:(mk_pad 3 0 pc) decl.name; @@ -1368,6 +1375,9 @@ and pp_expr buffer ~pad:(_,pc as pad) = function | EPar {value; region} -> pp_loc_node buffer ~pad "EPar" region; pp_expr buffer ~pad:(mk_pad 1 0 pc) value.inside +| EFun {value; region} -> + pp_loc_node buffer ~pad "EFun" region; + pp_fun_expr ~pad buffer value; and pp_list_expr buffer ~pad:(_,pc as pad) = function ECons {value; region} -> diff --git a/src/passes/2-simplify/pascaligo.ml b/src/passes/2-simplify/pascaligo.ml index 0f03eb925..eef0ed11c 100644 --- a/src/passes/2-simplify/pascaligo.ml +++ b/src/passes/2-simplify/pascaligo.ml @@ -117,6 +117,22 @@ module Errors = struct ] in error ~data title message + let unexpected_anonymous_function loc = + let title () = "unexpected anonymous function" in + let message () = "you provided a function declaration without name" in + let data = [ + ("loc" , fun () -> Format.asprintf "%a" Location.pp @@ loc) + ] in + error ~data title message + + let unexpected_named_function loc = + let title () = "unexpected named function" in + let message () = "you provided a function expression with a name (remove it)" in + let data = [ + ("loc" , fun () -> Format.asprintf "%a" Location.pp @@ loc) + ] in + error ~data title message + (* Logging *) let simplifying_instruction t = @@ -410,6 +426,13 @@ let rec simpl_expression (t:Raw.expr) : expr result = let%bind index = simpl_expression lu.index.value.inside in return @@ e_look_up ~loc path index ) + | EFun f -> ( + let (f , loc) = r_split f in + let%bind ((name_opt , _ty_opt) , f') = simpl_fun_expression ~loc f in + match name_opt with + | None -> return @@ f' + | Some _ -> fail @@ unexpected_named_function loc + ) and simpl_logic_expression (t:Raw.logic_expr) : expression result = let return x = ok x in @@ -497,10 +520,6 @@ and simpl_local_declaration : Raw.local_decl -> _ result = fun t -> match t with | LocalData d -> simpl_data_declaration d - | LocalFun f -> - let (f , loc) = r_split f in - let%bind (name , e) = simpl_fun_declaration ~loc f in - return_let_in ~loc name e and simpl_data_declaration : Raw.data_decl -> _ result = fun t -> match t with @@ -516,6 +535,11 @@ and simpl_data_declaration : Raw.data_decl -> _ result = fun t -> let%bind t = simpl_type_expression x.const_type in let%bind expression = simpl_expression x.init in return_let_in ~loc (name , Some t) expression + | LocalFun f -> + let (f , loc) = r_split f in + let%bind ((name_opt , ty_opt) , e) = simpl_fun_expression ~loc f.fun_expr.value in + let%bind name = trace_option (unexpected_anonymous_function loc) name_opt in + return_let_in ~loc (name , ty_opt) e and simpl_param : Raw.param_decl -> (type_name * type_expression) result = fun t -> @@ -531,11 +555,11 @@ and simpl_param : Raw.param_decl -> (type_name * type_expression) result = let%bind type_expression = simpl_type_expression c.param_type in ok (type_name , type_expression) -and simpl_fun_declaration : - loc:_ -> Raw.fun_decl -> ((name * type_expression option) * expression) result = +and simpl_fun_expression : + loc:_ -> Raw.fun_expr -> ((name option * type_expression option) * expression) result = fun ~loc x -> let open! Raw in - let {name;param;ret_type;local_decls;block;return} : fun_decl = x in + let {name;param;ret_type;local_decls;block;return} : fun_expr = x in let statements = match block with | Some block -> npseq_to_list block.value.statements @@ -544,7 +568,7 @@ and simpl_fun_declaration : (match param.value.inside with a, [] -> ( let%bind input = simpl_param a in - let name = name.value in + let name = Option.map (fun (x : _ reg) -> x.value) name in let (binder , input_type) = input in let%bind local_declarations = bind_map_list simpl_local_declaration local_decls in @@ -591,7 +615,8 @@ and simpl_fun_declaration : let expression = e_lambda ~loc binder (Some input_type) (Some output_type) result in let type_annotation = Some (T_function (input_type, output_type)) in - ok ((name.value , type_annotation) , expression) + let name = Option.map (fun (x : _ reg) -> x.value) name in + ok ((name , type_annotation) , expression) ) ) and simpl_declaration : Raw.declaration -> declaration Location.wrap result = @@ -614,7 +639,8 @@ and simpl_declaration : Raw.declaration -> declaration Location.wrap result = bind_map_location simpl_const_decl (Location.lift_region x) | FunDecl x -> ( let (x , loc) = r_split x in - let%bind ((name , ty_opt) , expr) = simpl_fun_declaration ~loc x in + let%bind ((name_opt , ty_opt) , expr) = simpl_fun_expression ~loc x.fun_expr.value in + let%bind name = trace_option (unexpected_anonymous_function loc) name_opt in ok @@ Location.wrap ~loc (Declaration_constant (name , ty_opt , expr)) ) diff --git a/src/test/contracts/big_map.ligo b/src/test/contracts/big_map.ligo index 3d504aa75..e6ab78c58 100644 --- a/src/test/contracts/big_map.ligo +++ b/src/test/contracts/big_map.ligo @@ -2,8 +2,8 @@ type storage_ is big_map(int, int) * unit type foo is big_map(int, int) function main(const p : unit; const s : storage_) : list(operation) * storage_ is - var toto : option (int) := Some(0); block { + var toto : option (int) := Some(0); toto := s.0[23]; s.0[2] := 444; } @@ -32,5 +32,5 @@ function mutimaps (const m : foo ; const n : foo) : foo is block { var bar : foo := m ; bar[42] := 0 ; - n[42] := get_force(42, bar) ; -} with n \ No newline at end of file + n[42] := get_force(42, bar) ; +} with n diff --git a/src/test/contracts/closure-1.ligo b/src/test/contracts/closure-1.ligo index f54cfac37..420c888c9 100644 --- a/src/test/contracts/closure-1.ligo +++ b/src/test/contracts/closure-1.ligo @@ -1,4 +1,5 @@ function foo (const i : int) : int is - function bar (const j : int) : int is - block { skip } with i + j ; - block { skip } with bar (i) + block { + function bar (const j : int) : int is + i + j ; + } with bar (i) diff --git a/src/test/contracts/closure-2.ligo b/src/test/contracts/closure-2.ligo index 5d5b0e721..5e84645e6 100644 --- a/src/test/contracts/closure-2.ligo +++ b/src/test/contracts/closure-2.ligo @@ -1,5 +1,6 @@ function foobar(const i : int) : int is - const j : int = 3 ; - function toto(const k : int) : int is - block { skip } with i + j + k ; - block { skip } with toto(42) + block { + const j : int = 3 ; + function toto(const k : int) : int is + i + j + k ; + } with toto(42) diff --git a/src/test/contracts/closure-3.ligo b/src/test/contracts/closure-3.ligo index 98ad10cb0..a23cdbb22 100644 --- a/src/test/contracts/closure-3.ligo +++ b/src/test/contracts/closure-3.ligo @@ -1,10 +1,12 @@ // This might seem like it's covered by induction with closure-2.ligo -// But it exists to prevent a regression on the bug patched by: +// But it exists to prevent a regression on the bug patched by: // https://gitlab.com/ligolang/ligo/commit/faf3bbc06106de98189f1c1673bd57e78351dc7e function foobar(const i : int) : int is - const j : int = 3 ; - const k : int = 4 ; - function toto(const l : int) : int is - block { skip } with i + j + k + l; - block { skip } with toto(42) + block { + const j : int = 3 ; + const k : int = 4 ; + function toto(const l : int) : int is + i + j + k + l; + + } with toto(42) diff --git a/src/test/contracts/closure.ligo b/src/test/contracts/closure.ligo index e295ec609..ccb8a5e8c 100644 --- a/src/test/contracts/closure.ligo +++ b/src/test/contracts/closure.ligo @@ -1,6 +1,7 @@ function toto (const i : int) : int is - function tata (const j : int) : int is - block { skip } with i + j ; - function titi (const j : int) : int is - block { skip } with i + j ; - block { skip } with tata(i) + titi(i) + block { + function tata (const j : int) : int is + i + j ; + function titi (const j : int) : int is + i + j ; + } with tata(i) + titi(i) diff --git a/src/test/contracts/condition.ligo b/src/test/contracts/condition.ligo index 53a75ed07..baf320f1d 100644 --- a/src/test/contracts/condition.ligo +++ b/src/test/contracts/condition.ligo @@ -1,8 +1,8 @@ // Test if conditional in PascaLIGO function main (const i : int) : int is - var result : int := 23 ; begin + var result : int := 23 ; if i = 2 then result := 42 else @@ -10,7 +10,7 @@ function main (const i : int) : int is end with result function foo (const b : bool) : int is - var x : int := 41 ; begin + var x : int := 41 ; x := 1 + (if b then x else main(x)) ; - end with x \ No newline at end of file + end with x diff --git a/src/test/contracts/deep_access.ligo b/src/test/contracts/deep_access.ligo index bacbf3467..66f9a1d9b 100644 --- a/src/test/contracts/deep_access.ligo +++ b/src/test/contracts/deep_access.ligo @@ -3,20 +3,17 @@ type pii is (int*int) type ppi is record x:pii; y:pii end type ppp is (ppi*ppi) -function main (const toto : unit) : int is -var a : ppp := -( -record -x = (0,1); -y = (10,11); -end -, -record -x = (100,101); -y = (110,111); -end -) -begin - a.0.x.0 := 2; - const b:int = a.0.x.0; -end with b +function main (const toto : unit) : int is block { + var a : ppp := ( + record + x = (0,1); + y = (10,11); + end , + record + x = (100,101); + y = (110,111); + end + ) ; + a.0.x.0 := 2; + const b:int = a.0.x.0; +} with b diff --git a/src/test/contracts/failwith.ligo b/src/test/contracts/failwith.ligo index 6a758b844..16c93f026 100644 --- a/src/test/contracts/failwith.ligo +++ b/src/test/contracts/failwith.ligo @@ -12,8 +12,8 @@ function main (const p : param; const s : unit) : list(operation) * unit is with ((nil : list(operation)), s) function foobar (const i : int) : int is - var p : param := Zero (42n) ; block { + var p : param := Zero (42n) ; if i > 0 then block { i := i + 1 ; if i > 10 then block { diff --git a/src/test/contracts/function-complex.ligo b/src/test/contracts/function-complex.ligo index f1f33c74c..4c361cbfd 100644 --- a/src/test/contracts/function-complex.ligo +++ b/src/test/contracts/function-complex.ligo @@ -1,9 +1,9 @@ // Test a PascaLIGO function with more complex logic than function.ligo function main (const i : int) : int is - var j : int := 0 ; - var k : int := 1 ; begin + var j : int := 0 ; + var k : int := 1 ; j := k + i ; k := i + j ; end with (k + j) diff --git a/src/test/contracts/high-order.ligo b/src/test/contracts/high-order.ligo index 44822f088..107cbd9ff 100644 --- a/src/test/contracts/high-order.ligo +++ b/src/test/contracts/high-order.ligo @@ -1,49 +1,50 @@ // Test a PascaLIGO function which takes another PascaLIGO function as an argument function foobar (const i : int) : int is - function foo (const i : int) : int is - block { skip } with i ; - function bar (const f : int -> int) : int is - block { skip } with f ( i ) ; - block { skip } with bar (foo) ; + block { + function foo (const i : int) : int is + i ; + function bar (const f : int -> int) : int is + f ( i ) ; + } with bar (foo) ; // higher order function with more than one argument function higher2(const i: int; const f: int -> int): int is - block { + block { const ii: int = f(i) } with ii function foobar2 (const i : int) : int is - function foo2 (const i : int) : int is - block { skip } with i; - block { skip } with higher2(i,foo2) + block { + function foo2 (const i : int) : int is + i; + } with higher2(i,foo2) const a : int = 0; function foobar3 (const i : int) : int is - function foo2 (const i : int) : int is - block { skip } with (a+i); - block { skip } with higher2(i,foo2) + block { + function foo2 (const i : int) : int is + (a+i); + } with higher2(i,foo2) function f (const i : int) : int is - block { skip } - with i + i function g (const i : int) : int is - block { skip } - with f(i) + f(i) function foobar4 (const i : int) : int is - block { skip } - with g(g(i)) + g(g(i)) function higher3(const i: int; const f: int -> int; const g: int -> int): int is - block { + block { const ii: int = f(g(i)); } with ii function foobar5 (const i : int) : int is - const a : int = 0; - function foo (const i : int) : int is - block { skip } with (a+i); - function goo (const i : int) : int is - block { skip } with foo(i); - block { skip } with higher3(i,foo,goo) + block { + const a : int = 0; + function foo (const i : int) : int is + (a+i); + function goo (const i : int) : int is + foo(i); + } with higher3(i,foo,goo) diff --git a/src/test/contracts/lambda.ligo b/src/test/contracts/lambda.ligo index cc426e83d..036327729 100644 --- a/src/test/contracts/lambda.ligo +++ b/src/test/contracts/lambda.ligo @@ -2,5 +2,6 @@ function f (const x : unit) : unit is begin skip end with unit function main (const p : unit ; const s : unit) : unit is - var y : unit := f(unit) ; - begin skip end with y + begin + var y : unit := f(unit) ; + end with y diff --git a/src/test/contracts/list.ligo b/src/test/contracts/list.ligo index 0a1d0c05d..af863fb67 100644 --- a/src/test/contracts/list.ligo +++ b/src/test/contracts/list.ligo @@ -25,15 +25,16 @@ const bl : foobar = list end function iter_op (const s : list(int)) : int is - var r : int := 0 ; - function aggregate (const i : int) : unit is - begin - r := r + i ; - end with unit begin + var r : int := 0 ; + function aggregate (const i : int) : unit is + begin + r := r + i ; + end with unit ; list_iter(s , aggregate) ; end with r function map_op (const s : list(int)) : list(int) is - function increment (const i : int) : int is block { skip } with i + 1 - block { skip } with list_map(s , increment) + block { + function increment (const i : int) : int is block { skip } with i + 1 + } with list_map(s , increment) diff --git a/src/test/contracts/map.ligo b/src/test/contracts/map.ligo index 5c169fe25..aad2d3921 100644 --- a/src/test/contracts/map.ligo +++ b/src/test/contracts/map.ligo @@ -48,23 +48,25 @@ function get_ (const m : foobar) : option(int) is end with map_get(42 , m) function iter_op (const m : foobar) : unit is - function aggregate (const i : int ; const j : int) : unit is block - { if (i=j) then skip else failwith("fail") } with unit ; - block {skip} + block { + function aggregate (const i : int ; const j : int) : unit is block + { if (i=j) then skip else failwith("fail") } with unit ; // map_iter(m , aggregate) ; - with map_iter(m, aggregate) ; + } with map_iter(m, aggregate) ; function map_op (const m : foobar) : foobar is - function increment (const i : int ; const j : int) : int is block { skip } with j + 1 ; - block { skip } with map_map(m , increment) ; + block { + function increment (const i : int ; const j : int) : int is block { skip } with j + 1 ; + } with map_map(m , increment) ; function fold_op (const m : foobar) : int is - function aggregate (const i : int ; const j : (int * int)) : int is block { skip } with i + j.0 + j.1 ; - block { skip } with map_fold(m , 10 , aggregate) + block { + function aggregate (const i : int ; const j : (int * int)) : int is block { skip } with i + j.0 + j.1 ; + } with map_fold(m , 10 , aggregate) function deep_op (var m : foobar) : foobar is -var coco : (int*foobar) := (0, m); -block { - remove 42 from map coco.1 ; - coco.1[32] := 16 ; -} with coco.1 + block { + var coco : (int*foobar) := (0, m); + remove 42 from map coco.1 ; + coco.1[32] := 16 ; + } with coco.1 diff --git a/src/test/contracts/match.ligo b/src/test/contracts/match.ligo index 8c7ce4742..167f3d976 100644 --- a/src/test/contracts/match.ligo +++ b/src/test/contracts/match.ligo @@ -1,39 +1,36 @@ // Test the pattern matching functionality of PascaLIGO function match_bool (const i : int) : int is - var result : int := 23 ; begin - case i = 2 of - | True -> result := 42 - | False -> result := 0 - end + var result : int := 23 ; + case i = 2 of + | True -> result := 42 + | False -> result := 0 + end end with result function match_option (const o : option(int)) : int is - var result : int := 23 ; begin - case o of - | None -> skip - | Some (s) -> result := s - end + var result : int := 23 ; + case o of + | None -> skip + | Some (s) -> result := s + end end with result function match_expr_bool (const i : int) : int is - begin skip end with case i = 2 of | True -> 42 | False -> 0 end function match_expr_option (const o : option(int)) : int is - begin skip end with case o of | None -> 42 | Some (s) -> s end function match_expr_list (const l : list(int)) : int is - begin skip end with case l of | nil -> -1 | hd # tl -> hd diff --git a/src/test/contracts/option.ligo b/src/test/contracts/option.ligo index d3d1ef36c..f2fb91260 100644 --- a/src/test/contracts/option.ligo +++ b/src/test/contracts/option.ligo @@ -6,10 +6,8 @@ const s : foobar = Some(42) const n : foobar = None function assign (var m : int) : foobar is - var coco : foobar := None; - block -{ - coco := Some(m); - coco := None; -} -with coco + block { + var coco : foobar := None; + coco := Some(m); + coco := None; + } with coco diff --git a/src/test/contracts/set_arithmetic-1.ligo b/src/test/contracts/set_arithmetic-1.ligo index f5d332687..d0b16263e 100644 --- a/src/test/contracts/set_arithmetic-1.ligo +++ b/src/test/contracts/set_arithmetic-1.ligo @@ -1,16 +1,17 @@ // Test set iteration in PascaLIGO function iter_op (const s : set(int)) : int is - var r : int := 0 ; - function aggregate (const i : int) : unit is - begin - r := r + i ; - end with unit begin + var r : int := 0 ; + function aggregate (const i : int) : unit is + begin + r := r + i ; + end with unit ; set_iter(s , aggregate) ; end with r function fold_op (const s : set(int)) : int is - function aggregate (const i : int ; const j : int) : int is - block { skip } with i + j - block { skip } with set_fold(s , 15 , aggregate) + block { + function aggregate (const i : int ; const j : int) : int is + i + j + } with set_fold(s , 15 , aggregate) diff --git a/src/test/contracts/shadow.ligo b/src/test/contracts/shadow.ligo index 4232cb0a6..a1891c651 100644 --- a/src/test/contracts/shadow.ligo +++ b/src/test/contracts/shadow.ligo @@ -1,4 +1,5 @@ function foo (const i : int) : int is - function bar (const i : int) : int is - block { skip } with i ; - block { skip } with bar (0) + block { + function bar (const i : int) : int is + i ; + } with bar (0) diff --git a/src/test/contracts/simple_access.ligo b/src/test/contracts/simple_access.ligo index 6cfa85a1e..e26e23bc7 100644 --- a/src/test/contracts/simple_access.ligo +++ b/src/test/contracts/simple_access.ligo @@ -7,15 +7,15 @@ end type mpi is map(string,int) function main (const toto : tpi) : int is - var a : tpi := toto; - var b : rpi := record x = 0; y=1 ; end; - var m : mpi := map "y" -> 1; end; - begin - a.0 := 2; - b.x := a.0; - m["x"] := b.x; - end with - case m["x"] of - | Some (s) -> s - | None -> 42 - end + begin + var a : tpi := toto; + var b : rpi := record x = 0; y=1 ; end; + var m : mpi := map "y" -> 1; end; + a.0 := 2; + b.x := a.0; + m["x"] := b.x; + end with + case m["x"] of + | Some (s) -> s + | None -> 42 + end diff --git a/vendors/ligo-utils/simple-utils/region.ml b/vendors/ligo-utils/simple-utils/region.ml index 8e954d560..fb746b899 100644 --- a/vendors/ligo-utils/simple-utils/region.ml +++ b/vendors/ligo-utils/simple-utils/region.ml @@ -108,6 +108,8 @@ let make ~(start: Pos.t) ~(stop: Pos.t) = let ghost = make ~start:Pos.ghost ~stop:Pos.ghost +let wrap_ghost value = {value ; region = ghost} + let min = make ~start:Pos.min ~stop:Pos.min (* Comparisons *) diff --git a/vendors/ligo-utils/simple-utils/region.mli b/vendors/ligo-utils/simple-utils/region.mli index fb3b8e240..2dc6555a2 100644 --- a/vendors/ligo-utils/simple-utils/region.mli +++ b/vendors/ligo-utils/simple-utils/region.mli @@ -96,6 +96,11 @@ val make : start:Pos.t -> stop:Pos.t -> t val ghost : t (* Two [Pos.ghost] positions *) +(* This wraps a value with a ghost region. *) + +val wrap_ghost : 'a -> 'a reg + + (* Occasionnally, we may need a minimum region. It is here made of two minimal positions. *)