diff options
author | Son Ho | 2021-11-17 16:30:57 +0100 |
---|---|---|
committer | Son Ho | 2021-11-17 16:30:57 +0100 |
commit | dabf9836f8bf59d4590e4bef126299492c9b53de (patch) | |
tree | 15b01173bbd98f1baad08e8c11a6eae5ce758345 /src/CfimOfJson.ml | |
parent | 2903cd956575624313d29e1a3ecd1abcbaab4dc3 (diff) |
Start implementing by hand the json deserializers
Diffstat (limited to '')
-rw-r--r-- | src/CfimOfJson.ml | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/src/CfimOfJson.ml b/src/CfimOfJson.ml new file mode 100644 index 00000000..156cf42a --- /dev/null +++ b/src/CfimOfJson.ml @@ -0,0 +1,166 @@ +(** Functions to load CFIM ASTs from json. + + Initially, we used `ppx_derive_yojson` to automate this. + However, `ppx_derive_yojson` expects formatting to be slightly + different from what `serde_rs` generates. + + For instance, if you consider the following rust definition: + ``` + enum t = | V + ``` + Serializing `t::V` with `serde_rs` will generate: `"V"`. + + However, if you consider the following OCaml definition: + ``` + type t = V + ``` + Serializing `V` will generate: `["V"]`. + + As we consider that the `serde_rs` formatting is more logical, we decided + to implement our own deserializing functions. Moreover, it allows us to + generate a friendlier debugging output in case the deserialization functions + fail. + *) + +open Yojson.Safe +open Identifiers +open Types + +type json = t + +let ( let* ) o f = match o with Error e -> Error e | Ok x -> f x + +let rec of_json_list (a_of_json : json -> ('a, string) result) (jsl : json list) + : ('a list, string) result = + match jsl with + | [] -> Ok [] + | x :: jsl' -> + let* x = a_of_json x in + let* jsl' = of_json_list a_of_json jsl' in + Ok (x :: jsl') + +let list_of_json (a_of_json : json -> ('a, string) result) (js : json) : + ('a list, string) result = + match js with + | `List jsl -> of_json_list a_of_json jsl + | _ -> Error ("list_of_json: not a list: " ^ show js) + +let string_of_json (js : json) : (string, string) result = + match js with + | `String str -> Ok str + | _ -> Error ("string_of_json: not a string: " ^ show js) + +let option_of_json (a_of_json : json -> ('a, string) result) (js : json) : + ('a option, string) result = + match js with + | `Variant ("Some", Some x) -> + let* x = a_of_json x in + Ok (Some x) + | `Variant ("None", None) -> Ok None + | _ -> Error ("option_of_json failed on: " ^ show js) + +let string_option_of_json (js : json) : (string option, string) result = + option_of_json string_of_json js + +let name_of_json (js : json) : (name, string) result = + list_of_json string_of_json js + +let type_var_of_json (js : json) : (type_var, string) result = + match js with + | `Assoc [ ("index", index); ("name", name) ] -> + let* index = TypeVarId.id_of_json index in + let* name = string_of_json name in + Ok { tv_index = index; tv_name = name } + | _ -> Error ("type_var_of_json failed on:" ^ show js) + +let region_var_of_json (js : json) : (region_var, string) result = + match js with + | `Assoc [ ("index", index); ("name", name) ] -> + let* index = RegionVarId.id_of_json index in + let* name = string_option_of_json name in + Ok { rv_index = index; rv_name = name } + | _ -> Error ("region_var_of_json failed on:" ^ show js) + +let region_of_json (js : json) : (RegionVarId.id region, string) result = + match js with + | `Variant ("Static", None) -> Ok Static + | `Variant ("Var", Some rid) -> + let* rid = RegionVarId.id_of_json rid in + Ok (Var rid) + | _ -> Error ("region_of_json failed on:" ^ show js) + +let erased_region_of_json (js : json) : (erased_region, string) result = + match js with + | `Variant ("Erased", None) -> Ok Erased + | _ -> Error ("erased_region_of_json failed on:" ^ show js) + +let integer_type_of_json (js : json) : (integer_type, string) result = + match js with + | `Variant ("Isize", None) -> Ok Isize + | `Variant ("I8", None) -> Ok I8 + | `Variant ("I16", None) -> Ok I16 + | `Variant ("I32", None) -> Ok I32 + | `Variant ("I64", None) -> Ok I64 + | `Variant ("I128", None) -> Ok I128 + | `Variant ("Usize", None) -> Ok Usize + | `Variant ("U8", None) -> Ok U8 + | `Variant ("U16", None) -> Ok U16 + | `Variant ("U32", None) -> Ok U32 + | `Variant ("U64", None) -> Ok U64 + | `Variant ("U128", None) -> Ok U128 + | _ -> Error ("integer_type_of_json failed on:" ^ show js) + +let ref_kind_of_json (js : json) : (ref_kind, string) result = + match js with + | `Variant ("Mut", None) -> Ok Mut + | `Variant ("Shared", None) -> Ok Shared + | _ -> Error ("ref_kind_of_json failed on:" ^ show js) + +let assumed_ty_of_json (js : json) : (assumed_ty, string) result = + match js with + | `Variant ("Box", None) -> Ok Box + | _ -> Error ("assumed_ty_of_json failed on:" ^ show js) + +let rec ty_of_json (r_of_json : json -> ('r, string) result) (js : json) : + ('r ty, string) result = + match js with + | `Variant ("Adt", Some (`Tuple [ id; regions; types ])) -> + let* id = TypeDefId.id_of_json id in + let* regions = list_of_json r_of_json regions in + let* types = list_of_json (ty_of_json r_of_json) types in + Ok (Adt (id, regions, types)) + | `Variant ("TypeVar", Some id) -> + let* id = TypeVarId.id_of_json id in + Ok (TypeVar id) + | `Variant ("Bool", None) -> Ok Bool + | `Variant ("Char", None) -> Ok Char + | `Variant ("Never", None) -> Ok Never + | `Variant ("Integer", Some int_ty) -> + let* int_ty = integer_type_of_json int_ty in + Ok (Integer int_ty) + | `Variant ("Str", None) -> Ok Str + | `Variant ("Array", Some ty) -> + let* ty = ty_of_json r_of_json ty in + Ok (Array ty) + | `Variant ("Slice", Some ty) -> + let* ty = ty_of_json r_of_json ty in + Ok (Slice ty) + | `Variant ("Ref", Some (`Tuple [ region; ty; ref_kind ])) -> + let* region = r_of_json region in + let* ty = ty_of_json r_of_json ty in + let* ref_kind = ref_kind_of_json ref_kind in + Ok (Ref (region, ty, ref_kind)) + | `Variant ("Tuple", Some types) -> + let* types = list_of_json (ty_of_json r_of_json) types in + Ok (Tuple types) + | `Variant ("Assumed", Some (`Tuple [ assumed_ty; regions; types ])) -> + let* assumed_ty = assumed_ty_of_json assumed_ty in + let* regions = list_of_json r_of_json regions in + let* types = list_of_json (ty_of_json r_of_json) types in + Ok (Assumed (assumed_ty, regions, types)) + | _ -> Error ("ty_of_json failed on:" ^ show js) + +(* +open Values +open Expressions +open CfimAst*) |