summaryrefslogtreecommitdiff
path: root/src/lib/process.ml
blob: a74c44bd664d366b43c448fda428f0c6ac6b05b2 (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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
open StdLabels

module M(T:Sounds.T) = struct

  type voyel = T.t Modifiers.Sig.voyel

  type group = voyel * T.t Modifiers.Sig.consonants option
  type modifier = T.t Modifiers.Sig.modifier

  (** Apply all the modifiers to the syllabic group in order to correct the
      relation between the elements

      This is just a fold_left list, and the order matter : for example
      nasalisation shall be applied after the S vocalisation

  *)
  let apply_modifiers
    : group * T.t option option -> modifier list -> group * T.t option option
    = fun e m ->
      List.fold_left m
        ~init:e
        ~f:(fun e f -> f (module T:Sounds.T with type t = T.t) e)

  let change_voyel
    = fun init ->
      let (((v1, v2), _) , ending) = init in
      match ending with
      | None -> v2
      | Some _ -> v1

  let rec _rebuild ~(m:modifier list) acc ending_consonant : group list -> T.t list
    = function
      | [] -> acc
      | hd::tl ->

        let modifier = (Modifiers.vocalize_s) :: (Modifiers.nasal) :: m in
        let (voyel, consonants), ending_consonant =
          apply_modifiers
            (hd, ending_consonant)
            modifier  in
        let voyel = change_voyel ((voyel, consonants), ending_consonant) in

        (* Add the last consonant and the voyel *)
        let m, acc = match ending_consonant with
          | None -> modifier, voyel::acc
          | Some s ->
            let default = modifier, voyel :: acc in
            match s with
            | None -> default
            | Some s ->

              modifier, voyel :: s::acc  in

        match consonants with
        | None -> _rebuild ~m acc None tl
        | Some {ending; opening; following} ->

          let acc = match following with
            | None -> acc
            | Some s -> s::acc in

          match opening with
          | [] ->_rebuild ~m acc ending tl
          | opening -> _rebuild ~m (opening @ acc) ending tl

  (** Rebuild the list in the normal order

      The voyels have to be choosen, depending either they are followed by a
      consonant or not

      Some consonants may be changed depending of the following voyel

      The list has to be reversed

      and so one

  *)
  let rebuild
    : T.t Modifiers.Sig.consonants option -> group list -> T.t list
    = fun  ending elems ->
      let elems' = match ending with
        | None -> elems
        | Some _ -> ((T.none, T.none), ending)::elems in
      _rebuild ~m:[Modifiers.mute_consonant] [] None elems'

end