mpri-funcprog-project/src/kremlin/Constant.ml

67 lines
1.6 KiB
OCaml

(** Machine integers. Don't repeat the same thing everywhere. *)
type t = width * string
[@@deriving show]
and width =
| UInt8 | UInt16 | UInt32 | UInt64 | Int8 | Int16 | Int32 | Int64
| Bool
| CInt (** Checked signed integers. *)
let bytes_of_width (w: width) =
match w with
| UInt8 -> 1
| UInt16 -> 2
| UInt32 -> 4
| UInt64 -> 8
| Int8 -> 1
| Int16 -> 2
| Int32 -> 4
| Int64 -> 8
| CInt -> 4
| _ -> invalid_arg "bytes_of_width"
type op =
(* Arithmetic operations *)
| Add | AddW | Sub | SubW | Div | DivW | Mult | MultW | Mod
(* Bitwise operations *)
| BOr | BAnd | BXor | BShiftL | BShiftR | BNot
(* Arithmetic comparisons / boolean comparisons *)
| Eq | Neq | Lt | Lte | Gt | Gte
(* Boolean operations *)
| And | Or | Xor | Not
(* Effectful operations *)
| Assign | PreIncr | PreDecr | PostIncr | PostDecr
(* Misc *)
| Comma
[@@deriving show { with_path = false }]
let unsigned_of_signed = function
| Int8 -> UInt8
| Int16 -> UInt16
| Int32 -> UInt32
| Int64 -> UInt64
| CInt | UInt8 | UInt16 | UInt32 | UInt64 | Bool -> raise (Invalid_argument "unsigned_of_signed")
let is_signed = function
| Int8 | Int16 | Int32 | Int64 | CInt -> true
| UInt8 | UInt16 | UInt32 | UInt64 -> false
| Bool -> raise (Invalid_argument "is_signed")
let is_unsigned w = not (is_signed w)
let without_wrap = function
| AddW -> Add
| SubW -> Sub
| MultW -> Mult
| DivW -> Div
| _ -> raise (Invalid_argument "without_wrap")
let uint8_of_int i =
assert (i < (1 lsl 8) && i >= 0);
UInt8, string_of_int i
let uint32_of_int i =
assert (i < (1 lsl 32) && i >= 0);
UInt32, string_of_int i