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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
open StdLabels
module M(T:Sounds.T) = struct
type voyel = (T.t * T.t )
type consonants =
{ ending : T.t option option
; opening : T.t list
; following : T.t option }
type group = voyel * consonants option
type modifier = (group * T.t option option) -> (group * T.t option option)
(** 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 e)
(** The Nasal modifier transform a voyel followed by N and a consonant
into a nasal voyel.
Does this min that nasal voyel are not a distinct element, but just a
merge from two distinct elements ? *)
let nasal
: modifier
= fun init ->
let (((v1, v2), c) , ending) = init in
let ending = Option.bind ending (fun x -> x) in
match ending with
| None -> init
| Some ending ->
match T.is_nasal ending with
| false -> init
| true ->
(* Remove the ending consonant, and transform the voyel into
the nasal form *)
( ( (T.nasal v1, T.nasal v2)
, c )
, None )
let vocalize_s
: modifier
= fun init ->
let (((v1, v2), c) , ending) = init in
match c with
| None -> init
| Some op -> match op.opening, op.ending with
| hd::[], None when T.code hd = T.SZ ->
let c = Some { op with opening = [T.z ()] } in
(((v1, v2), c) , ending)
| _ -> init
let rec _rebuild ~(m:modifier list) acc ending_consonant : group list -> T.t list
= function
| [] -> acc
| hd::tl ->
let modifier_ = vocalize_s :: nasal :: m in
let (voyel, consonants), ending_consonant =
apply_modifiers
(hd, ending_consonant)
modifier_ in
(* Add the last consonant and the voyel *)
let m, acc = match ending_consonant with
| None -> modifier_, (snd voyel)::acc
| Some s ->
let default = modifier_, (fst voyel) :: acc in
match s with
| None -> default
| Some s ->
modifier_, (fst 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 option option -> group list -> T.t list
= fun ending elems ->
_rebuild ~m:[] [] ending elems
end
|