Write blockless function test and make it pass

This commit is contained in:
John David Pressman 2019-10-19 10:46:24 -07:00
parent ec67d37f20
commit daad15c57d
7 changed files with 73 additions and 86 deletions

View File

@ -211,31 +211,16 @@ and type_tuple = (type_expr, comma) nsepseq par reg
(* Function and procedure declarations *)
and fun_decl =
BlockFun of block_fun
| BlocklessFun of blockless_fun
and block_fun = {
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;
kwd_with : kwd_with;
return : expr;
terminator : semi option }
and blockless_fun = {
kwd_function : kwd_function;
name : variable;
param : parameters;
colon : colon;
ret_type : type_expr;
kwd_is : kwd_is;
kwd_expr : kwd_expr;
local_decls : local_decl list option;
block : block reg option;
kwd_with : kwd_with option;
return : expr;
terminator : semi option }

View File

@ -202,31 +202,16 @@ and type_tuple = (type_expr, comma) nsepseq par reg
(* Function declarations *)
and fun_decl =
BlockFun of block_fun
| BlocklessFun of blockless_fun
and block_fun = {
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;
kwd_with : kwd_with;
return : expr;
terminator : semi option }
and blockless_fun = {
kwd_function : kwd_function;
name : variable;
param : parameters;
colon : colon;
ret_type : type_expr;
kwd_is : kwd_is;
kwd_expr : kwd_expr;
local_decls : local_decl list option;
block : block reg option;
kwd_with : kwd_with option;
return : expr;
terminator : semi option }

View File

@ -258,19 +258,18 @@ fun_decl:
colon = $4;
ret_type = $5;
kwd_is = $6;
local_decls = $7;
block = $8;
kwd_with = $9;
local_decls = Some $7;
block = Some $8;
kwd_with = Some $9;
return = $10;
terminator = $11}
in {region = region;
value = BlockFun value} }
in {region;value}}
| Function fun_name parameters COLON type_expr Is
Expr expr option(SEMI) {
expr option(SEMI) {
let stop =
match $9 with
match $8 with
Some region -> region
| None -> expr_to_region $8 in
| None -> expr_to_region $7 in
let region = cover $1 stop
and value = {
kwd_function = $1;
@ -279,12 +278,13 @@ fun_decl:
colon = $4;
ret_type = $5;
kwd_is = $6;
kwd_expr = $7;
return = $8;
terminator = $9;
local_decls = None;
block = None;
kwd_with = None;
return = $7;
terminator = $8;
}
in {region = region;
value = BlocklessFun value} }
in {region;value}}
parameters:
par(nsepseq(param_decl,SEMI)) { $1 }

View File

@ -168,7 +168,10 @@ and print_fun_decl buffer {value; _} =
print_token buffer kwd_is "is";
print_local_decls buffer local_decls;
print_block buffer block;
match kwd_with with
| Some kwd_with ->
print_token buffer kwd_with "with";
| None -> ();
print_expr buffer return;
print_terminator buffer terminator
@ -196,12 +199,16 @@ and print_param_var buffer {value; _} =
print_token buffer colon ":";
print_type_expr buffer param_type
and print_block buffer {value; _} =
and print_block buffer reg =
match reg with
| Some reg ->
let value = reg.value in
let {opening; statements; terminator; closing} = value in
print_block_opening buffer opening;
print_statements buffer statements;
print_terminator buffer terminator;
print_block_closing buffer closing
| None -> ()
and print_block_opening buffer = function
Block (kwd_block, lbrace) ->
@ -215,7 +222,10 @@ and print_block_closing buffer = function
| End kwd_end -> print_token buffer kwd_end "end"
and print_local_decls buffer sequence =
match sequence with
| Some sequence ->
List.iter (print_local_decl buffer) sequence
| None -> ()
and print_local_decl buffer = function
LocalFun decl -> print_fun_decl buffer decl
@ -272,9 +282,8 @@ and print_if_clause buffer = function
| ClauseBlock block -> print_clause_block buffer block
and print_clause_block buffer = function
LongBlock block ->
print_block buffer block
| ShortBlock {value; _} ->
LongBlock block -> print_block buffer (Some block)
| ShortBlock {value; _} ->
let {lbrace; inside; rbrace} = value in
let statements, terminator = inside in
print_token buffer lbrace "{";
@ -325,7 +334,7 @@ and print_while_loop buffer value =
let {kwd_while; cond; block} = value in
print_token buffer kwd_while "while";
print_expr buffer cond;
print_block buffer block
print_block buffer (Some block)
and print_for_loop buffer = function
ForInt for_int -> print_for_int buffer for_int
@ -337,7 +346,7 @@ and print_for_int buffer ({value; _} : for_int reg) =
print_var_assign buffer assign;
print_token buffer kwd_to "to";
print_expr buffer bound;
print_block buffer block
print_block buffer (Some block)
and print_var_assign buffer {value; _} =
let {name; assign; expr} = value in
@ -356,7 +365,7 @@ and print_for_collect buffer ({value; _} : for_collect reg) =
print_token buffer kwd_in "in";
print_collection buffer collection;
print_expr buffer expr;
print_block buffer block
print_block buffer (Some block)
and print_collection buffer = function
Map kwd_map ->
@ -845,7 +854,10 @@ and pp_fun_decl buffer ~pad:(_,pc) decl =
let () =
let pad = mk_pad 6 4 pc in
pp_node buffer ~pad "<block>";
let statements = decl.block.value.statements in
let statements =
match decl.block with
| Some block -> block.value.statements
| None -> Instr (Skip Region.ghost), [] in
pp_statements buffer ~pad statements in
let () =
let _, pc as pad = mk_pad 6 5 pc in
@ -1225,9 +1237,12 @@ and pp_set_remove buffer ~pad:(_,pc) rem =
pp_path buffer ~pad:(mk_pad 2 1 pc) rem.set
and pp_local_decls buffer ~pad:(_,pc) decls =
match decls with
| Some decls ->
let apply len rank =
pp_local_decl buffer ~pad:(mk_pad len rank pc)
in List.iteri (List.length decls |> apply) decls
| None -> ()
and pp_local_decl buffer ~pad:(_,pc as pad) = function
LocalFun {value; _} ->

View File

@ -544,22 +544,16 @@ and simpl_fun_declaration :
loc:_ -> Raw.fun_decl -> ((name * type_expression option) * expression) result =
fun ~loc x ->
let open! Raw in
let (name, param, ret_type, return) =
match x with
| BlockFun f -> (f.name, f.param, f.ret_type, f.return)
| BlocklessFun f -> (f.name, f.param, f.ret_type, f.return)
let {name;param;ret_type;local_decls;block;return} : fun_decl = x in
let local_decls =
match local_decls with
| Some local_decls -> local_decls
| None -> []
in
let block =
match x with
| BlockFun f -> f.block
| BlocklessFun _ ->
{region = Region.ghost;
value = {
opening = Raw.keyword;
statements = [(Raw.kwd_skip * Raw.SEMI)];
terminator = Some Raw.SEMI;
closing = Raw.kwd_end;
}
let statements =
match block with
| Some block -> npseq_to_list block.value.statements
| None -> []
in
(match param.value.inside with
a, [] -> (
@ -570,7 +564,7 @@ and simpl_fun_declaration :
bind_map_list simpl_local_declaration local_decls in
let%bind instructions = bind_list
@@ List.map simpl_statement
@@ npseq_to_list block.value.statements in
@@ statements in
let%bind result = simpl_expression return in
let%bind output_type = simpl_type_expression ret_type in
let body = local_declarations @ instructions in
@ -601,7 +595,7 @@ and simpl_fun_declaration :
bind_map_list simpl_local_declaration local_decls in
let%bind instructions = bind_list
@@ List.map simpl_statement
@@ npseq_to_list block.value.statements in
@@ statements in
let%bind result = simpl_expression return in
let%bind output_type = simpl_type_expression ret_type in
let body = tpl_declarations @ local_declarations @ instructions in

View File

@ -0,0 +1,2 @@
function blockless (const n: int) : int is
n + 10;

View File

@ -15,6 +15,11 @@ let function_ () : unit result =
let make_expect = fun n -> n in
expect_eq_n_int program "main" make_expect
let blockless () : unit result =
let%bind program = type_file "./contracts/blockless.ligo" in
let make_expect = fun n-> n + 10 in
expect_eq_n_int program "blockless" make_expect
(* Procedures are not supported yet
let procedure () : unit result =
let%bind program = type_file "./contracts/procedure.ligo" in
@ -894,6 +899,7 @@ let tez_mligo () : unit result =
let main = test_suite "Integration (End to End)" [
test "type alias" type_alias ;
test "function" function_ ;
test "blockless function" blockless;
(* test "procedure" procedure ; *)
test "assign" assign ;
test "declaration local" declaration_local ;