diff --git a/.gitignore b/.gitignore index 682093b54..cf5ed1f94 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ Version.ml /_opam/ /*.pp.ligo **/.DS_Store +.vscode/ \ No newline at end of file diff --git a/src/passes/1-parser/pascaligo/AST.ml b/src/passes/1-parser/pascaligo/AST.ml index c572160ac..97eab1c20 100644 --- a/src/passes/1-parser/pascaligo/AST.ml +++ b/src/passes/1-parser/pascaligo/AST.ml @@ -211,18 +211,17 @@ and type_tuple = (type_expr, comma) nsepseq par reg (* Function and procedure 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; - kwd_with : kwd_with; - return : expr; - terminator : semi option -} + kwd_function : kwd_function; + name : variable; + param : parameters; + colon : colon; + ret_type : type_expr; + kwd_is : kwd_is; + local_decls : local_decl list option; + block : block reg option; + kwd_with : kwd_with option; + return : expr; + terminator : semi option } and parameters = (param_decl, semi) nsepseq par reg diff --git a/src/passes/1-parser/pascaligo/AST.mli b/src/passes/1-parser/pascaligo/AST.mli index cbb5ffd36..a41fb005f 100644 --- a/src/passes/1-parser/pascaligo/AST.mli +++ b/src/passes/1-parser/pascaligo/AST.mli @@ -201,19 +201,18 @@ 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; - kwd_with : kwd_with; - return : expr; - terminator : semi option -} +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 option; + block : block reg option; + kwd_with : kwd_with option; + return : expr; + terminator : semi option } and parameters = (param_decl, semi) nsepseq par reg diff --git a/src/passes/1-parser/pascaligo/Parser.mly b/src/passes/1-parser/pascaligo/Parser.mly index a22c005e7..38b86357b 100644 --- a/src/passes/1-parser/pascaligo/Parser.mly +++ b/src/passes/1-parser/pascaligo/Parser.mly @@ -258,12 +258,33 @@ 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; value}} + 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 + let region = cover $1 stop + and value = { + kwd_function = $1; + name = $2; + param = $3; + colon = $4; + ret_type = $5; + kwd_is = $6; + local_decls = None; + block = None; + kwd_with = None; + return = $7; + terminator = $8; + } + in {region;value}} parameters: par(nsepseq(param_decl,SEMI)) { $1 } diff --git a/src/passes/1-parser/pascaligo/ParserLog.ml b/src/passes/1-parser/pascaligo/ParserLog.ml index aed9454da..e09149bce 100644 --- a/src/passes/1-parser/pascaligo/ParserLog.ml +++ b/src/passes/1-parser/pascaligo/ParserLog.ml @@ -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; - print_token buffer kwd_with "with"; + 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; _} = - 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 +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 = - List.iter (print_local_decl 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 @@ -279,9 +289,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 "{"; @@ -332,7 +341,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 @@ -344,7 +353,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 @@ -363,7 +372,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 -> @@ -853,7 +862,10 @@ and pp_fun_decl buffer ~pad:(_,pc) decl = let () = let pad = mk_pad 6 4 pc in pp_node buffer ~pad ""; - 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 @@ -1248,9 +1260,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 = - let apply len rank = - pp_local_decl buffer ~pad:(mk_pad len rank pc) - in List.iteri (List.length decls |> apply) 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; _} -> diff --git a/src/passes/2-simplify/pascaligo.ml b/src/passes/2-simplify/pascaligo.ml index 0e9ddaf7e..d094f3819 100644 --- a/src/passes/2-simplify/pascaligo.ml +++ b/src/passes/2-simplify/pascaligo.ml @@ -551,6 +551,16 @@ and simpl_fun_declaration : fun ~loc x -> let open! Raw in 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 statements = + match block with + | Some block -> npseq_to_list block.value.statements + | None -> [] + in (match param.value.inside with a, [] -> ( let%bind input = simpl_param a in @@ -560,7 +570,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 @@ -591,7 +601,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 diff --git a/src/test/contracts/blockless.ligo b/src/test/contracts/blockless.ligo new file mode 100644 index 000000000..103b926f0 --- /dev/null +++ b/src/test/contracts/blockless.ligo @@ -0,0 +1,2 @@ +function blockless (const n: int) : int is + n + 10; diff --git a/src/test/integration_tests.ml b/src/test/integration_tests.ml index ba4fc9520..e4f0047fe 100644 --- a/src/test/integration_tests.ml +++ b/src/test/integration_tests.ml @@ -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 @@ -901,6 +906,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 ;