diff --git a/src/passes/operators/operators.ml b/src/passes/operators/operators.ml index 256c23bf3..e1bfb0417 100644 --- a/src/passes/operators/operators.ml +++ b/src/passes/operators/operators.ml @@ -64,6 +64,7 @@ module Simplify = struct ("size" , "SIZE") ; ("int" , "INT") ; ("abs" , "ABS") ; + ("is_nat", "ISNAT") ; ("amount" , "AMOUNT") ; ("balance", "BALANCE") ; ("now" , "NOW") ; @@ -207,6 +208,8 @@ module Simplify = struct ("abs" , "ABS") ; ("unit" , "UNIT") ; ("source" , "SOURCE") ; + + ("Michelson.is_nat" , "ISNAT") ; ] let type_constants = type_constants @@ -511,6 +514,10 @@ module Typer = struct let%bind () = assert_t_int t in ok @@ t_nat () + let is_nat = typer_1 "ISNAT" @@ fun t -> + let%bind () = assert_t_int t in + ok @@ t_option (t_nat ()) () + let neg = typer_1 "NEG" @@ fun t -> let%bind () = Assert.assert_true (eq_1 t (t_nat ()) || eq_1 t (t_int ())) in ok @@ t_int () @@ -775,6 +782,7 @@ module Typer = struct get_entrypoint ; neg ; abs ; + is_nat ; cons ; now ; slice ; @@ -844,6 +852,7 @@ module Compiler = struct ("ASSERT" , simple_unary @@ i_if (seq [i_push_unit]) (seq [i_push_unit ; i_failwith])) ; ("INT" , simple_unary @@ prim I_INT) ; ("ABS" , simple_unary @@ prim I_ABS) ; + ("ISNAT", simple_unary @@ prim I_ISNAT) ; ("CONS" , simple_binary @@ prim I_CONS) ; ("UNIT" , simple_constant @@ prim I_UNIT) ; ("BALANCE" , simple_constant @@ prim I_BALANCE) ; diff --git a/src/test/contracts/isnat.ligo b/src/test/contracts/isnat.ligo new file mode 100644 index 000000000..75215f28a --- /dev/null +++ b/src/test/contracts/isnat.ligo @@ -0,0 +1,2 @@ +function main (const i: int) : option(nat) is + block {skip} with is_nat(i) diff --git a/src/test/contracts/isnat.mligo b/src/test/contracts/isnat.mligo new file mode 100644 index 000000000..c5bea0294 --- /dev/null +++ b/src/test/contracts/isnat.mligo @@ -0,0 +1 @@ +let main (i: int) : nat option = Michelson.is_nat i diff --git a/src/test/integration_tests.ml b/src/test/integration_tests.ml index 106475b03..b509a845f 100644 --- a/src/test/integration_tests.ml +++ b/src/test/integration_tests.ml @@ -1211,6 +1211,33 @@ let balance_constant_mligo () : unit result = let input = e_tuple [e_unit () ; e_mutez 0] in let expected = e_tuple [e_list []; e_mutez 4000000000000] in expect_eq program "main" input expected + +let is_nat () : unit result = + let%bind program = type_file "./contracts/isnat.ligo" in + let%bind () = + let input = e_int 10 in + let expected = e_some (e_nat 10) in + expect_eq program "main" input expected + in + let%bind () = + let input = e_int (-10) in + let expected = e_none () in + expect_eq program "main" input expected + in ok () + +let is_nat_mligo () : unit result = + let%bind program = mtype_file "./contracts/isnat.mligo" in + let%bind () = + let input = e_int 10 in + let expected = e_some (e_nat 10) in + expect_eq program "main" input expected + in + let%bind () = + let input = e_int (-10) in + let expected = e_none () in + expect_eq program "main" input expected + in ok () + let simple_access_ligo () : unit result = let%bind program = type_file "./contracts/simple_access.ligo" in let make_input = e_tuple [e_int 0; e_int 1] in @@ -1313,6 +1340,8 @@ let main = test_suite "Integration (End to End)" [ test "let multiple (mligo)" mligo_let_multiple ; test "balance constant" balance_constant ; test "balance constant (mligo)" balance_constant_mligo ; + test "is_nat" is_nat ; + test "is_not (mligo)" is_nat_mligo ; test "simple_access (ligo)" simple_access_ligo; test "deep_access (ligo)" deep_access_ligo; test "entrypoints (ligo)" entrypoints_ligo ;