Michelson: add ISNAT instruction

This commit is contained in:
Benjamin Canou 2018-04-12 21:10:58 +02:00 committed by Grégoire Henry
parent 3cc88d0d81
commit 60136c13b2
8 changed files with 26 additions and 1 deletions

View File

@ -243,6 +243,7 @@ module Script : sig
| I_LOOP_LEFT | I_LOOP_LEFT
| I_ADDRESS | I_ADDRESS
| I_CONTRACT | I_CONTRACT
| I_ISNAT
| T_bool | T_bool
| T_contract | T_contract
| T_int | T_int

View File

@ -96,6 +96,7 @@ type prim =
| I_LOOP_LEFT | I_LOOP_LEFT
| I_ADDRESS | I_ADDRESS
| I_CONTRACT | I_CONTRACT
| I_ISNAT
| T_bool | T_bool
| T_contract | T_contract
| T_int | T_int
@ -220,6 +221,7 @@ let string_of_prim = function
| I_LOOP_LEFT -> "LOOP_LEFT" | I_LOOP_LEFT -> "LOOP_LEFT"
| I_ADDRESS -> "ADDRESS" | I_ADDRESS -> "ADDRESS"
| I_CONTRACT -> "CONTRACT" | I_CONTRACT -> "CONTRACT"
| I_ISNAT -> "ISNAT"
| T_bool -> "bool" | T_bool -> "bool"
| T_contract -> "contract" | T_contract -> "contract"
| T_int -> "int" | T_int -> "int"
@ -325,6 +327,7 @@ let prim_of_string = function
| "LOOP_LEFT" -> ok I_LOOP_LEFT | "LOOP_LEFT" -> ok I_LOOP_LEFT
| "ADDRESS" -> ok I_ADDRESS | "ADDRESS" -> ok I_ADDRESS
| "CONTRACT" -> ok I_CONTRACT | "CONTRACT" -> ok I_CONTRACT
| "ISNAT" -> ok I_ISNAT
| "bool" -> ok T_bool | "bool" -> ok T_bool
| "contract" -> ok T_contract | "contract" -> ok T_contract
| "int" -> ok T_int | "int" -> ok T_int
@ -474,6 +477,7 @@ let prim_encoding =
("LOOP_LEFT", I_LOOP_LEFT) ; ("LOOP_LEFT", I_LOOP_LEFT) ;
("ADDRESS", I_ADDRESS) ; ("ADDRESS", I_ADDRESS) ;
("CONTRACT", I_CONTRACT) ; ("CONTRACT", I_CONTRACT) ;
("ISNAT", I_ISNAT) ;
("bool", T_bool) ; ("bool", T_bool) ;
("contract", T_contract) ; ("contract", T_contract) ;
("int", T_int) ; ("int", T_int) ;

View File

@ -94,6 +94,7 @@ type prim =
| I_LOOP_LEFT | I_LOOP_LEFT
| I_ADDRESS | I_ADDRESS
| I_CONTRACT | I_CONTRACT
| I_ISNAT
| T_bool | T_bool
| T_contract | T_contract
| T_int | T_int

View File

@ -43,6 +43,8 @@ let mul_n = mul
let ediv_n = ediv let ediv_n = ediv
let abs x = Z.abs x let abs x = Z.abs x
let is_nat x =
if Compare.Z.(x < Z.zero) then None else Some x
let neg x = Z.neg x let neg x = Z.neg x
let int x = x let int x = x

View File

@ -88,6 +88,9 @@ val ediv: _ num -> _ num -> (z num * n num) option
(** Compute the absolute value of a relative, turning it into a natural. *) (** Compute the absolute value of a relative, turning it into a natural. *)
val abs : z num -> n num val abs : z num -> n num
(** Partial identity over [N]. *)
val is_nat : z num -> n num option
(** Negates a number. *) (** Negates a number. *)
val neg : _ num -> z num val neg : _ num -> z num

View File

@ -451,6 +451,8 @@ let rec interp
| Not, Item (x, rest) -> | Not, Item (x, rest) ->
consume_gas_unop descr (not, x) Interp_costs.bool_unop rest ctxt consume_gas_unop descr (not, x) Interp_costs.bool_unop rest ctxt
(* integer operations *) (* integer operations *)
| Is_nat, Item (x, rest) ->
consume_gas_unop descr (Script_int.is_nat, x) Interp_costs.abs rest ctxt
| Abs_int, Item (x, rest) -> | Abs_int, Item (x, rest) ->
consume_gas_unop descr (Script_int.abs, x) Interp_costs.abs rest ctxt consume_gas_unop descr (Script_int.abs, x) Interp_costs.abs rest ctxt
| Int_nat, Item (x, rest) -> | Int_nat, Item (x, rest) ->

View File

@ -151,6 +151,7 @@ let number_of_generated_growing_types : type b a. (b, a) instr -> int = function
| And -> 0 | And -> 0
| Xor -> 0 | Xor -> 0
| Not -> 0 | Not -> 0
| Is_nat -> 0
| Neg_nat -> 0 | Neg_nat -> 0
| Neg_int -> 0 | Neg_int -> 0
| Abs_int -> 0 | Abs_int -> 0
@ -306,7 +307,8 @@ let namespace = function
| I_ITER | I_ITER
| I_LOOP_LEFT | I_LOOP_LEFT
| I_ADDRESS | I_ADDRESS
| I_CONTRACT -> Instr_namespace | I_CONTRACT
| I_ISNAT -> Instr_namespace
| T_bool | T_bool
| T_contract | T_contract
| T_int | T_int
@ -1845,6 +1847,14 @@ and parse_instr
Item_t (Int_t, rest, _) -> Item_t (Int_t, rest, _) ->
typed ctxt loc Abs_int typed ctxt loc Abs_int
(Item_t (Nat_t, rest, instr_annot)) (Item_t (Nat_t, rest, instr_annot))
| Prim (loc, I_ISNAT, [], Some instr_annot),
Item_t (Int_t, rest, None) ->
typed ctxt loc Is_nat
(Item_t (Option_t Nat_t, rest, Some instr_annot))
| Prim (loc, I_ISNAT, [], None),
Item_t (Int_t, rest, annot) ->
typed ctxt loc Is_nat
(Item_t (Option_t Nat_t, rest, annot))
| Prim (loc, I_INT, [], instr_annot), | Prim (loc, I_INT, [], instr_annot),
Item_t (Nat_t, rest, _) -> Item_t (Nat_t, rest, _) ->
typed ctxt loc Int_nat typed ctxt loc Int_nat

View File

@ -232,6 +232,8 @@ and ('bef, 'aft) instr =
| Not : | Not :
(bool * 'rest, bool * 'rest) instr (bool * 'rest, bool * 'rest) instr
(* integer operations *) (* integer operations *)
| Is_nat :
(z num * 'rest, n num option * 'rest) instr
| Neg_nat : | Neg_nat :
(n num * 'rest, z num * 'rest) instr (n num * 'rest, z num * 'rest) instr
| Neg_int : | Neg_int :