You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

125 lines
2.9 KiB

/*
* vim: set ft=rust:
* vim: set ft=reason:
*
* Copyright (c) 2009 - 2013 Monoidics ltd.
* Copyright (c) 2013 - present Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
open! IStd;
let module F = Format;
/** signed and unsigned integer literals */
/* the first bool indicates whether this is an unsigned value,
and the second whether it is a pointer */
type t = (bool, Int64.t, bool);
let area u i =>
switch (i < 0L, u) {
| (true, false) => 1 /* only representable as signed */
| (false, _) => 2 /* in the intersection between signed and unsigned */
| (true, true) => 3 /* only representable as unsigned */
};
let to_signed (unsigned, i, ptr) =>
if (area unsigned i == 3) {
None
} else {
Some
/* not representable as signed */
(false, i, ptr)
};
let compare (unsigned1, i1, _) (unsigned2, i2, _) =>
[%compare : (bool, Int64.t)] (unsigned1, i1) (unsigned2, i2);
let compare_value (unsigned1, i1, _) (unsigned2, i2, _) =>
[%compare : (int, Int64.t)] (area unsigned1 i1, i1) (area unsigned2 i2, i2);
let eq i1 i2 => compare_value i1 i2 == 0;
let neq i1 i2 => compare_value i1 i2 != 0;
let leq i1 i2 => compare_value i1 i2 <= 0;
let lt i1 i2 => compare_value i1 i2 < 0;
let geq i1 i2 => compare_value i1 i2 >= 0;
let gt i1 i2 => compare_value i1 i2 > 0;
let of_int64 i => (false, i, false);
let of_int32 i => of_int64 (Int64.of_int32 i);
let of_int64_unsigned i unsigned => (unsigned, i, false);
let of_int i => of_int64 (Int64.of_int i);
let to_int (_, i, _) => Int64.to_int_exn i;
let null = (false, 0L, true);
let zero = of_int 0;
let one = of_int 1;
let two = of_int 2;
let minus_one = of_int (-1);
let isone (_, i, _) => i == 1L;
let iszero (_, i, _) => i == 0L;
let isnull (_, i, ptr) => i == 0L && ptr;
let isminusone (unsigned, i, _) => not unsigned && i == (-1L);
let isnegative (unsigned, i, _) => not unsigned && i < 0L;
let neg (unsigned, i, ptr) => (unsigned, Int64.neg i, ptr);
let lift binop (unsigned1, i1, ptr1) (unsigned2, i2, ptr2) => (
unsigned1 || unsigned2,
binop i1 i2,
ptr1 || ptr2
);
let lift1 unop (unsigned, i, ptr) => (unsigned, unop i, ptr);
let add i1 i2 => lift Int64.(+) i1 i2;
let mul i1 i2 => lift Int64.( * ) i1 i2;
let div i1 i2 => lift Int64.(/) i1 i2;
let rem i1 i2 => lift Int64.rem i1 i2;
let logand i1 i2 => lift Int64.bit_and i1 i2;
let logor i1 i2 => lift Int64.bit_or i1 i2;
let logxor i1 i2 => lift Int64.bit_xor i1 i2;
let lognot i => lift1 Int64.bit_not i;
let sub i1 i2 => add i1 (neg i2);
let pp f (unsigned, n, ptr) =>
if (ptr && n == 0L) {
F.fprintf f "null"
} else if unsigned {
F.fprintf f "%Lu" n
} else {
F.fprintf f "%Ld" n
};
let to_string i => F.asprintf "%a" pp i;