summaryrefslogtreecommitdiff
path: root/src/lib/process.ml
blob: 7ab20fe8870cf01dbc3c80a5f0664c601f024d4e (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
open StdLabels

type voyel = Sounds.t

type group = voyel * Modifiers.Sig.consonants option
type modifier = Sounds.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 * Sounds.t option option -> modifier list -> group * Sounds.t option option
  = fun e m ->
    List.fold_left m
      ~init:e
      ~f:(fun e f -> f e)

let rec _rebuild ~(m:modifier list) acc ending_consonant : group list -> Sounds.t list
  = function
    | [] -> acc
    | hd::tl ->
      let modifier = match tl with
        | [] -> Modifiers.nasal::m
        | _ -> (Modifiers.vocalize_s) :: (Modifiers.nasal) :: m in
      let (voyel, consonants), ending_consonant =
        apply_modifiers
          (hd, ending_consonant)
          modifier  in

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

      (* Apply the modifiers to the previous syllabe.

         Only transform the e into eu / E if there is previous syllabe with
         voyel. *)
      let modifiers = if voyel = Sounds.none then
          [Modifiers.ending_e]
        else
          [Modifiers.e] in

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

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

        match opening with
        | [] ->_rebuild ~m:modifiers acc ending tl
        | opening -> _rebuild ~m:modifiers (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
  : Modifiers.Sig.consonants option -> group list -> Sounds.t list
  = fun  ending elems ->
    let elems' = (Sounds.none, ending)::elems in
    _rebuild ~m:[Modifiers.mute_consonant;Modifiers.ending_e;] [] None elems'