Merge branch 'feature/more-applications-pascaligo' into 'dev'

add and test more ways to do function application in pascaligo

See merge request ligolang/ligo!196
This commit is contained in:
Gabriel Alfour 2019-11-18 12:46:05 +00:00
commit 122d0d5520
7 changed files with 101 additions and 28 deletions

View File

@ -580,7 +580,7 @@ and selection =
and tuple_expr = (expr, comma) nsepseq par reg and tuple_expr = (expr, comma) nsepseq par reg
and fun_call = (fun_name * arguments) reg and fun_call = (expr * arguments) reg
and arguments = tuple_expr and arguments = tuple_expr

View File

@ -570,7 +570,7 @@ and selection =
and tuple_expr = (expr, comma) nsepseq par reg and tuple_expr = (expr, comma) nsepseq par reg
and fun_call = (fun_name * arguments) reg and fun_call = (expr * arguments) reg
and arguments = tuple_expr and arguments = tuple_expr

View File

@ -863,14 +863,12 @@ core_expr:
| Unit { EUnit $1 } | Unit { EUnit $1 }
| annot_expr { EAnnot $1 } | annot_expr { EAnnot $1 }
| tuple_expr { ETuple $1 } | tuple_expr { ETuple $1 }
| par(expr) { EPar $1 }
| list_expr { EList $1 } | list_expr { EList $1 }
| C_None { EConstr (NoneExpr $1) } | C_None { EConstr (NoneExpr $1) }
| fun_call { ECall $1 } | fun_call_or_par_or_projection { $1 }
| map_expr { EMap $1 } | map_expr { EMap $1 }
| set_expr { ESet $1 } | set_expr { ESet $1 }
| record_expr { ERecord $1 } | record_expr { ERecord $1 }
| projection { EProj $1 }
| Constr arguments { | Constr arguments {
let region = cover $1.region $2.region in let region = cover $1.region $2.region in
EConstr (ConstrApp {region; value = $1, Some $2}) EConstr (ConstrApp {region; value = $1, Some $2})
@ -882,6 +880,30 @@ core_expr:
let region = cover $1 $2.region in let region = cover $1 $2.region in
EConstr (SomeApp {region; value = $1,$2})} EConstr (SomeApp {region; value = $1,$2})}
fun_call_or_par_or_projection:
| par(expr) option(arguments) {
let parenthesized = EPar $1 in
match $2 with
| None -> parenthesized
| Some args -> (
let region_1 = $1.region in
let region = cover region_1 args.region in
ECall {region; value = parenthesized,args}
)
}
| projection option(arguments) {
let project = EProj $1 in
match $2 with
| None -> project
| Some args -> (
let region_1 = $1.region in
let region = cover region_1 args.region in
ECall {region; value = project,args}
)
}
| fun_call { ECall $1 }
annot_expr: annot_expr:
LPAR disj_expr COLON type_expr RPAR { LPAR disj_expr COLON type_expr RPAR {
let start = expr_to_region $2 let start = expr_to_region $2
@ -956,7 +978,7 @@ field_assignment:
fun_call: fun_call:
fun_name arguments { fun_name arguments {
let region = cover $1.region $2.region let region = cover $1.region $2.region
in {region; value = $1,$2}} in {region; value = (EVar $1),$2}}
tuple_expr: tuple_expr:
par(tuple_comp) { $1 } par(tuple_comp) { $1 }

View File

@ -655,8 +655,8 @@ and print_nil buffer value = print_token buffer value "nil"
and print_none_expr buffer value = print_token buffer value "None" and print_none_expr buffer value = print_token buffer value "None"
and print_fun_call buffer {value; _} = and print_fun_call buffer {value; _} =
let fun_name, arguments = value in let expr, arguments = value in
print_var buffer fun_name; print_expr buffer expr;
print_tuple_expr buffer arguments print_tuple_expr buffer arguments
and print_constr_app buffer {value; _} = and print_constr_app buffer {value; _} =
@ -1247,12 +1247,12 @@ and pp_var_binding buffer ~pad:(_,pc as pad) (source, image) =
pp_ident buffer ~pad:(mk_pad 2 0 pc) source; pp_ident buffer ~pad:(mk_pad 2 0 pc) source;
pp_ident buffer ~pad:(mk_pad 2 1 pc) image pp_ident buffer ~pad:(mk_pad 2 1 pc) image
and pp_fun_call buffer ~pad:(_,pc) (name, args) = and pp_fun_call buffer ~pad:(_,pc) (expr, args) =
let args = Utils.nsepseq_to_list args.value.inside in let args = Utils.nsepseq_to_list args.value.inside in
let arity = List.length args in let arity = List.length args in
let apply len rank = let apply len rank =
pp_expr buffer ~pad:(mk_pad len rank pc) pp_expr buffer ~pad:(mk_pad len rank pc)
in pp_ident buffer ~pad:(mk_pad (1+arity) 0 pc) name; in pp_expr buffer ~pad:(mk_pad (1+arity) 0 pc) expr;
List.iteri (apply arity) args List.iteri (apply arity) args
and pp_record_patch buffer ~pad:(_,pc as pad) patch = and pp_record_patch buffer ~pad:(_,pc as pad) patch =

View File

@ -253,17 +253,25 @@ let rec simpl_expression (t:Raw.expr) : expr result =
| Some s -> return @@ e_constant ~loc s [] | Some s -> return @@ e_constant ~loc s []
) )
| ECall x -> ( | ECall x -> (
let ((name, args) , loc) = r_split x in let ((f, args) , loc) = r_split x in
let (f , f_loc) = r_split name in
let (args , args_loc) = r_split args in let (args , args_loc) = r_split args in
let args' = npseq_to_list args.inside in let args' = npseq_to_list args.inside in
match List.assoc_opt f constants with match f with
| None -> | EVar name -> (
let%bind arg = simpl_tuple_expression ~loc:args_loc args' in let (f_name , f_loc) = r_split name in
return @@ e_application ~loc (e_variable ~loc:f_loc f) arg match List.assoc_opt f_name constants with
| Some s -> | None ->
let%bind lst = bind_map_list simpl_expression args' in let%bind arg = simpl_tuple_expression ~loc:args_loc args' in
return @@ e_constant ~loc s lst return @@ e_application ~loc (e_variable ~loc:f_loc f_name) arg
| Some s ->
let%bind lst = bind_map_list simpl_expression args' in
return @@ e_constant ~loc s lst
)
| f -> (
let%bind f' = simpl_expression f in
let%bind arg = simpl_tuple_expression ~loc:args_loc args' in
return @@ e_application ~loc f' arg
)
) )
| EPar x -> simpl_expression x.value.inside | EPar x -> simpl_expression x.value.inside
| EUnit reg -> | EUnit reg ->
@ -620,18 +628,26 @@ and simpl_single_instruction : Raw.instruction -> (_ -> expression result) resul
fun t -> fun t ->
match t with match t with
| ProcCall x -> ( | ProcCall x -> (
let ((name, args) , loc) = r_split x in let ((f, args) , loc) = r_split x in
let (f , f_loc) = r_split name in let (args , args_loc) = r_split args in
let (args , args_loc) = r_split args in let args' = npseq_to_list args.inside in
let args' = npseq_to_list args.inside in match f with
match List.assoc_opt f constants with | EVar name -> (
let (f_name , f_loc) = r_split name in
match List.assoc_opt f_name constants with
| None -> | None ->
let%bind arg = simpl_tuple_expression ~loc:args_loc args' in let%bind arg = simpl_tuple_expression ~loc:args_loc args' in
return_statement @@ e_application ~loc (e_variable ~loc:f_loc f) arg return_statement @@ e_application ~loc (e_variable ~loc:f_loc f_name) arg
| Some s -> | Some s ->
let%bind lst = bind_map_list simpl_expression args' in let%bind lst = bind_map_list simpl_expression args' in
return_statement @@ e_constant ~loc s lst return_statement @@ e_constant ~loc s lst
) )
| f -> (
let%bind f' = simpl_expression f in
let%bind arg = simpl_tuple_expression ~loc:args_loc args' in
return_statement @@ e_application ~loc f' arg
)
)
| Skip reg -> ( | Skip reg -> (
let loc = Location.lift reg in let loc = Location.lift reg in
return_statement @@ e_skip ~loc () return_statement @@ e_skip ~loc ()

View File

@ -0,0 +1,21 @@
// Test different ways of calling functions in PascaLIGO
type foo is record
bar : int -> int ;
end
function f (const i : int) : int is
begin
skip
end with i
function g (const i : unit) : int -> int is
begin skip end with f
const r : foo = record
bar = f ;
end
const x : int = f(42)
const y : int = r.bar(42)
const z : int = (g(unit))(42)

View File

@ -52,6 +52,19 @@ let complex_function () : unit result =
let make_expect = fun n -> (3 * n + 2) in let make_expect = fun n -> (3 * n + 2) in
expect_eq_n_int program "main" make_expect expect_eq_n_int program "main" make_expect
let application () : unit result =
let%bind program = type_file "./contracts/application.ligo" in
let%bind () =
let expected = e_int 42 in
expect_eq_evaluate program "x" expected in
let%bind () =
let expected = e_int 42 in
expect_eq_evaluate program "y" expected in
let%bind () =
let expected = e_int 42 in
expect_eq_evaluate program "z" expected in
ok ()
let variant () : unit result = let variant () : unit result =
let%bind program = type_file "./contracts/variant.ligo" in let%bind program = type_file "./contracts/variant.ligo" in
let%bind () = let%bind () =
@ -1183,6 +1196,7 @@ let main = test_suite "Integration (End to End)" [
test "assign" assign ; test "assign" assign ;
test "declaration local" declaration_local ; test "declaration local" declaration_local ;
test "complex function" complex_function ; test "complex function" complex_function ;
test "various applications" application ;
test "closure" closure ; test "closure" closure ;
test "shared function" shared_function ; test "shared function" shared_function ;
test "shared function (mligo)" shared_function_mligo ; test "shared function (mligo)" shared_function_mligo ;