@ -9,17 +9,18 @@
type t =
| Function of { return : t option ; args : t vector }
| Integer of { bits : int }
| Float of { bits : int ; enc: [ ` IEEE | ` Extended | ` Pair ] }
| Integer of { bits : int ; siz : int }
| Float of { bits : int ; siz: int ; enc: [ ` IEEE | ` Extended | ` Pair ] }
| Pointer of { elt : t }
| Array of { elt : t ; len : int }
| Tuple of { elts : t vector ; packed: bool }
| Array of { elt : t ; len : int ; siz : int }
| Tuple of { elts : t vector ; siz: int ; packed: bool }
| Struct of
{ name : string
; elts : t vector (* possibly cyclic, name unique *)
[ @ compare . ignore ] [ @ equal . ignore ] [ @ sexp_drop_if fun _ -> true ]
; siz : int
; packed : bool }
| Opaque of { name : string }
| Opaque of { name : string ; siz : int }
[ @@ deriving compare , equal , hash , sexp ]
let rec pp fs typ =
@ -77,34 +78,34 @@ let invariant t =
(* * Constructors *)
let function_ ~ return ~ args = Function { return ; args } | > check invariant
let integer ~ bits = Integer { bits } | > check invariant
let float ~ bits ~ enc = Float { bits ; enc } | > check invariant
let integer ~ bits ~siz = Integer { bits ; siz } | > check invariant
let float ~ bits ~ siz ~ enc = Float { bits ; siz ; enc } | > check invariant
let pointer ~ elt = Pointer { elt } | > check invariant
let array ~ elt ~ len = Array { elt ; len } | > check invariant
let tuple elts ~ packed = Tuple { elts ; packed } | > check invariant
let opaque ~ name = Opaque { name } | > check invariant
let array ~ elt ~ len ~siz = Array { elt ; len ; siz } | > check invariant
let tuple elts ~ siz ~ packed = Tuple { elts ; siz ; packed } | > check invariant
let opaque ~ name ~siz = Opaque { name ; siz } | > check invariant
let struct_ =
let defns : ( string , t ) Hashtbl . t = Hashtbl . create ( module String ) in
let dummy_typ = Opaque { name = " dummy " } in
fun ~ name ~ packed elt_thks ->
let dummy_typ = Opaque { name = " dummy " ; siz = 0 } in
fun ~ name ~ siz ~ packed elt_thks ->
match Hashtbl . find defns name with
| Some typ -> typ
| None ->
(* Add placeholder defn to prevent computing [elts] in calls to
[ struct ] from [ elts ] for recursive occurrences of [ name ] . * )
let elts = Array . create ~ len : ( Vector . length elt_thks ) dummy_typ in
let typ = Struct { name ; elts = Vector . of_array elts ; packed} in
let typ = Struct { name ; elts = Vector . of_array elts ; siz; packed} in
Hashtbl . set defns ~ key : name ~ data : typ ;
Vector . iteri elt_thks ~ f : ( fun i ( lazy elt ) -> elts . ( i ) <- elt ) ;
typ | > check invariant
(* * Constants *)
let bool = integer ~ bits : 1
let byt = integer ~ bits : 8
let int = integer ~ bits : 32
let siz = integer ~ bits : 64
let bool = integer ~ bits : 1 ~ siz : 1
let byt = integer ~ bits : 8 ~ siz : 1
let int = integer ~ bits : 32 ~ siz : 4
let siz = integer ~ bits : 64 ~ siz : 8
(* * [ptr] is semantically equivalent to [siz], but has a distinct
representation because the element type is important for [ Global ] s * )
@ -112,6 +113,17 @@ let ptr = pointer ~elt:byt
(* * Queries *)
let size_of = function
| Function _ -> None
| Integer { siz }
| Float { siz }
| Array { siz }
| Tuple { siz }
| Struct { siz }
| Opaque { siz } ->
Some siz
| Pointer _ -> Some 8
let rec prim_bit_size_of = function
| Integer { bits } | Float { bits } -> Some bits
| Pointer _ -> prim_bit_size_of siz
@ -130,12 +142,8 @@ let rec equivalent t0 t1 =
| _ -> equal t0 t1
let castable t0 t1 =
match ( t0 , t1 ) with
| ( ( Pointer _ | Integer _ | Float _ | Array _ )
, ( Pointer _ | Integer _ | Float _ | Array _ ) ) -> (
match ( prim_bit_size_of t0 , prim_bit_size_of t1 ) with
| Some n0 , Some n1 -> n0 = n1
| _ -> false )
match ( size_of t0 , size_of t1 ) with
| Some m , Some n -> m = n
| _ -> equal t0 t1
let rec convertible t0 t1 =