diff --git a/docs/whitedoc/michelson.rst b/docs/whitedoc/michelson.rst index 9d9fdc8be..11fbca525 100644 --- a/docs/whitedoc/michelson.rst +++ b/docs/whitedoc/michelson.rst @@ -730,11 +730,12 @@ Bitwise logical operators are also available on unsigned integers. > OR / x : y : S => (x | y) : S -- ``AND`` +- ``AND`` (also available when the top operand is signed) :: :: nat : nat : 'S -> nat : 'S + :: int : nat : 'S -> nat : 'S > AND / x : y : S => (x & y) : S @@ -749,7 +750,8 @@ Bitwise logical operators are also available on unsigned integers. - ``NOT`` The return type of ``NOT`` is an ``int`` and not a ``nat``. This is because the sign is also negated. The resulting integer is computed using two’s complement. For instance, the boolean negation - of ``0`` is ``-1``. + of ``0`` is ``-1``. To get a natural back, a possibility is to use + ``AND`` with an unsigned mask afterwards. :: diff --git a/src/proto_alpha/lib_protocol/src/script_int_repr.mli b/src/proto_alpha/lib_protocol/src/script_int_repr.mli index 6f01e4d95..24342440f 100644 --- a/src/proto_alpha/lib_protocol/src/script_int_repr.mli +++ b/src/proto_alpha/lib_protocol/src/script_int_repr.mli @@ -101,7 +101,6 @@ val int : n num -> z num Also applies to the sign. *) val lognot : _ num -> z num - (** Shifts the natural to the left of a number of bits between 0 and 256. Returns [None] if the amount is too high. *) val shift_left_n : n num -> n num -> n num option @@ -119,10 +118,10 @@ val shift_left : 'a num -> n num -> 'a num option val shift_right : 'a num -> n num -> 'a num option (** Applies a boolean or operation to each bit. *) -val logor : n num -> n num -> n num +val logor : 'a num -> 'a num -> 'a num (** Applies a boolean and operation to each bit. *) -val logand : n num -> n num -> n num +val logand : _ num -> n num -> n num (** Applies a boolean xor operation to each bit. *) val logxor : n num -> n num -> n num diff --git a/src/proto_alpha/lib_protocol/src/script_interpreter.ml b/src/proto_alpha/lib_protocol/src/script_interpreter.ml index 12b7da87d..39796bb6b 100644 --- a/src/proto_alpha/lib_protocol/src/script_interpreter.ml +++ b/src/proto_alpha/lib_protocol/src/script_interpreter.ml @@ -547,6 +547,8 @@ let rec interp consume_gas_binop descr (Script_int.logor, x, y) Interp_costs.logor rest ctxt | And_nat, Item (x, Item (y, rest)) -> consume_gas_binop descr (Script_int.logand, x, y) Interp_costs.logand rest ctxt + | And_int_nat, Item (x, Item (y, rest)) -> + consume_gas_binop descr (Script_int.logand, x, y) Interp_costs.logand rest ctxt | Xor_nat, Item (x, Item (y, rest)) -> consume_gas_binop descr (Script_int.logxor, x, y) Interp_costs.logxor rest ctxt | Not_int, Item (x, rest) -> diff --git a/src/proto_alpha/lib_protocol/src/script_ir_translator.ml b/src/proto_alpha/lib_protocol/src/script_ir_translator.ml index d203865ee..08664f2c5 100644 --- a/src/proto_alpha/lib_protocol/src/script_ir_translator.ml +++ b/src/proto_alpha/lib_protocol/src/script_ir_translator.ml @@ -173,6 +173,7 @@ let number_of_generated_growing_types : type b a. (b, a) instr -> int = function | Lsr_nat -> 0 | Or_nat -> 0 | And_nat -> 0 + | And_int_nat -> 0 | Xor_nat -> 0 | Not_nat -> 0 | Not_int -> 0 @@ -1955,6 +1956,10 @@ and parse_instr Item_t (Nat_t, Item_t (Nat_t, rest, _), _) -> typed ctxt loc And_nat (Item_t (Nat_t, rest, instr_annot)) + | Prim (loc, I_AND, [], instr_annot), + Item_t (Int_t, Item_t (Nat_t, rest, _), _) -> + typed ctxt loc And_int_nat + (Item_t (Nat_t, rest, instr_annot)) | Prim (loc, I_XOR, [], instr_annot), Item_t (Nat_t, Item_t (Nat_t, rest, _), _) -> typed ctxt loc Xor_nat diff --git a/src/proto_alpha/lib_protocol/src/script_typed_ir.ml b/src/proto_alpha/lib_protocol/src/script_typed_ir.ml index a89c378ae..86db84750 100644 --- a/src/proto_alpha/lib_protocol/src/script_typed_ir.ml +++ b/src/proto_alpha/lib_protocol/src/script_typed_ir.ml @@ -276,6 +276,8 @@ and ('bef, 'aft) instr = (n num * (n num * 'rest), n num * 'rest) instr | And_nat : (n num * (n num * 'rest), n num * 'rest) instr + | And_int_nat : + (z num * (n num * 'rest), n num * 'rest) instr | Xor_nat : (n num * (n num * 'rest), n num * 'rest) instr | Not_nat :