summaryrefslogtreecommitdiff
path: root/src/bytecode_util.ml
diff options
context:
space:
mode:
authorAlasdair Armstrong2018-08-30 15:33:18 +0100
committerAlasdair Armstrong2018-08-30 15:34:46 +0100
commitd97e6b84bfb66c141e3dfadb8edbd9afada77664 (patch)
treef9086b2bea34d909410946c729e55be731782a31 /src/bytecode_util.ml
parenta5ad2059821b86ef26a86d78c40cc680c57aa94e (diff)
C: Fix an issue with struct field being generalised inside polymorphic constructors
Add a new printing function for debugging that recursively prints constructor types. Fix an interpreter bug when pattern matching on constructors with tuple types.
Diffstat (limited to 'src/bytecode_util.ml')
-rw-r--r--src/bytecode_util.ml37
1 files changed, 34 insertions, 3 deletions
diff --git a/src/bytecode_util.ml b/src/bytecode_util.ml
index 7bad6d0b..6334210e 100644
--- a/src/bytecode_util.ml
+++ b/src/bytecode_util.ml
@@ -194,6 +194,33 @@ and string_of_ctyp = function
| CT_ref ctyp -> "ref(" ^ string_of_ctyp ctyp ^ ")"
| CT_poly -> "*"
+(** This function is like string_of_ctyp, but recursively prints all
+ constructors in variants and structs. Used for debug output. *)
+and full_string_of_ctyp = function
+ | CT_int -> "mpz_t"
+ | CT_bits true -> "bv_t(dec)"
+ | CT_bits false -> "bv_t(inc)"
+ | CT_bits64 (n, true) -> "uint64_t(" ^ string_of_int n ^ ", dec)"
+ | CT_bits64 (n, false) -> "uint64_t(" ^ string_of_int n ^ ", int)"
+ | CT_int64 -> "int64_t"
+ | CT_bit -> "bit"
+ | CT_unit -> "unit"
+ | CT_bool -> "bool"
+ | CT_real -> "real"
+ | CT_tup ctyps -> "(" ^ Util.string_of_list ", " full_string_of_ctyp ctyps ^ ")"
+ | CT_enum (id, _) -> string_of_id id
+ | CT_struct (id, ctors) | CT_variant (id, ctors) ->
+ "struct " ^ string_of_id id
+ ^ "{ "
+ ^ Util.string_of_list ", " (fun (id, ctyp) -> string_of_id id ^ " : " ^ full_string_of_ctyp ctyp) ctors
+ ^ "}"
+ | CT_string -> "string"
+ | CT_vector (true, ctyp) -> "vector(dec, " ^ full_string_of_ctyp ctyp ^ ")"
+ | CT_vector (false, ctyp) -> "vector(inc, " ^ full_string_of_ctyp ctyp ^ ")"
+ | CT_list ctyp -> "list(" ^ full_string_of_ctyp ctyp ^ ")"
+ | CT_ref ctyp -> "ref(" ^ full_string_of_ctyp ctyp ^ ")"
+ | CT_poly -> "*"
+
let rec map_ctyp f = function
| (CT_int | CT_int64 | CT_bits _ | CT_bits64 _ | CT_bit | CT_unit | CT_bool | CT_real | CT_string | CT_poly | CT_enum _) as ctyp -> f ctyp
| CT_tup ctyps -> f (CT_tup (List.map (map_ctyp f) ctyps))
@@ -254,8 +281,12 @@ let rec ctyp_suprema = function
| CT_tup ctyps -> CT_tup (List.map ctyp_suprema ctyps)
| CT_string -> CT_string
| CT_enum (id, ids) -> CT_enum (id, ids)
- | CT_struct (id, ctors) -> CT_struct (id, List.map (fun (id, ctyp) -> (id, ctyp_suprema ctyp)) ctors)
- | CT_variant (id, ctors) -> CT_variant (id, List.map (fun (id, ctyp) -> (id, ctyp_suprema ctyp)) ctors)
+ (* Do we really never want to never call ctyp_suprema on constructor
+ fields? Doing it causes issues for structs (see
+ test/c/stack_struct.sail) but it might be wrong to not call it
+ for nested variants... *)
+ | CT_struct (id, ctors) -> CT_struct (id, ctors)
+ | CT_variant (id, ctors) -> CT_variant (id, ctors)
| CT_vector (d, ctyp) -> CT_vector (d, ctyp_suprema ctyp)
| CT_list ctyp -> CT_list (ctyp_suprema ctyp)
| CT_ref ctyp -> CT_ref (ctyp_suprema ctyp)
@@ -631,7 +662,7 @@ let ctype_def_map_ctyp f = function
| CTD_enum (id, ids) -> CTD_enum (id, ids)
| CTD_struct (id, ctors) -> CTD_struct (id, List.map (fun (field, ctyp) -> (field, f ctyp)) ctors)
| CTD_variant (id, ctors) -> CTD_variant (id, List.map (fun (field, ctyp) -> (field, f ctyp)) ctors)
-
+
(** Map over each ctyp in a cdef using map_instr_ctyp *)
let cdef_map_ctyp f = function
| CDEF_reg_dec (id, ctyp, instrs) -> CDEF_reg_dec (id, f ctyp, List.map (map_instr_ctyp f) instrs)