summaryrefslogtreecommitdiff
path: root/src/Modules.ml
blob: e4cb06c1dbf0ccdaf3a4aed201558764f367d0db (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
open Types
open CfimAst

(** Module declaration *)
type declaration =
  | Type of TypeDefId.id
  | Fun of FunDefId.id
  | RecTypes of TypeDefId.id list
  | RecFuns of FunDefId.id list

type cfim_module = {
  declarations : declaration list;
  types : type_def list;
  functions : fun_def list;
}
(** CFIM module *)

type 'id decl_group = NonRec of 'id | Rec of 'id list [@@deriving show]

type types_decl_group = TypeDefId.id decl_group [@@deriving show]

type funs_decl_group = FunDefId.id decl_group [@@deriving show]

(** Split a module's declarations between types and functions *)
let split_declarations (decls : declaration list) :
    types_decl_group list * funs_decl_group list =
  let rec split decls =
    match decls with
    | [] -> ([], [])
    | d :: decls' -> (
        let types, funs = split decls' in
        match d with
        | Type id -> (NonRec id :: types, funs)
        | Fun id -> (types, NonRec id :: funs)
        | RecTypes ids -> (Rec ids :: types, funs)
        | RecFuns ids -> (types, Rec ids :: funs))
  in
  split decls

(** Split a module's declarations into two maps from type/fun ids to
    declaration groups.
 *)
let split_declarations_to_group_maps (decls : declaration list) :
    types_decl_group TypeDefId.Map.t * funs_decl_group FunDefId.Map.t =
  let module G (M : Map.S) = struct
    let add_group (map : M.key decl_group M.t) (group : M.key decl_group) :
        M.key decl_group M.t =
      match group with
      | NonRec id -> M.add id group map
      | Rec ids -> List.fold_left (fun map id -> M.add id group map) map ids

    let create_map (groups : M.key decl_group list) : M.key decl_group M.t =
      List.fold_left add_group M.empty groups
  end in
  let types, funs = split_declarations decls in
  let module TG = G (TypeDefId.Map) in
  let types = TG.create_map types in
  let module FG = G (FunDefId.Map) in
  let funs = FG.create_map funs in
  (types, funs)