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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131 | with Ada.Characters.Handling;
with Ada.Text_IO;
package body WL.Random.Names is
------------------
-- Load_Lexicon --
------------------
function Load_Lexicon
(Vowels_Path : String;
Consonants_Path : String)
return Name_Generator
is
begin
return Gen : Name_Generator do
Load_Lexicon (Gen, Vowels_Path, Consonants_Path);
end return;
end Load_Lexicon;
------------------
-- Load_Lexicon --
------------------
procedure Load_Lexicon
(Generator : out Name_Generator;
Vowels_Path : String;
Consonants_Path : String)
is
procedure Load_Info
(Path : String;
Target : in out Lexeme_Info_Vectors.Vector'Class);
---------------
-- Load_Info --
---------------
procedure Load_Info
(Path : String;
Target : in out Lexeme_Info_Vectors.Vector'Class)
is
use Ada.Text_IO;
File : File_Type;
begin
Open (File, In_File, Path);
while not End_Of_File (File) loop
declare
Full_Line : constant String := Get_Line (File);
Last_CR : constant Boolean :=
Full_Line'Length > 0
and then Character'Pos
(Full_Line (Full_Line'Last)) = 13;
Line : constant String :=
(if Last_CR
then Full_Line
(Full_Line'First .. Full_Line'Last - 1)
else Full_Line);
Lex : constant String := Line (Line'First + 1 .. Line'Last);
Flags : constant Natural :=
Natural'Value (Line (Line'First .. Line'First));
Info : Lexeme_Info;
begin
Info.Can_End := Flags mod 2 = 1;
Info.Can_Begin := (Flags / 2) mod 2 = 1;
Info.Can_Middle := (Flags / 4) mod 2 = 1;
Info.Lexeme (1 .. Lex'Length) := Lex;
Target.Append (Info);
end;
end loop;
Close (File);
end Load_Info;
begin
Load_Info (Vowels_Path, Generator.Vowels);
Load_Info (Consonants_Path, Generator.Consonants);
end Load_Lexicon;
-----------------
-- Random_Name --
-----------------
function Random_Name
(Generator : Name_Generator)
return String
is
Next_Is_Vowel : Boolean := Random_Number (1, 2) = 1;
Syllable_Count : constant Positive := Random_Number (3, 5);
Name_Length : Natural := 0;
Name : String (1 .. Syllable_Count * 3);
begin
for I in 1 .. Syllable_Count loop
loop
declare
Info : constant Lexeme_Info :=
(if Next_Is_Vowel
then Generator.Vowels
(Random_Number (1, Generator.Vowels.Last_Index))
else Generator.Consonants
(Random_Number
(1, Generator.Consonants.Last_Index)));
OK : Boolean;
begin
if I = 1 then
OK := Info.Can_Begin;
elsif I = Syllable_Count then
OK := Info.Can_End;
else
OK := Info.Can_Middle;
end if;
if OK then
for I in Info.Lexeme'Range loop
exit when Info.Lexeme (I) = ' ';
Name_Length := Name_Length + 1;
Name (Name_Length) := Info.Lexeme (I);
end loop;
exit;
end if;
end;
end loop;
Next_Is_Vowel := not Next_Is_Vowel;
end loop;
Name (1) := Ada.Characters.Handling.To_Upper (Name (1));
return Name (1 .. Name_Length);
end Random_Name;
end WL.Random.Names;
|