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
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;
|