File Coverage

blib/lib/Lingua/Zompist/Barakhinei.pm
Criterion Covered Total %
statement 289 344 84.0
branch 223 328 67.9
condition 118 291 40.5
subroutine 15 15 100.0
pod 9 9 100.0
total 654 987 66.2


line stmt bran cond sub pod time code
1             package Lingua::Zompist::Barakhinei;
2             # vim:set sw=2 cin cinkeys-=0#:
3              
4 11     11   356299 use 5.005;
  11         48  
  11         520  
5 11     11   81 use strict;
  11         30  
  11         771  
6             # use re 'debug';
7              
8             require Exporter;
9 11     11   71 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
  11         25  
  11         1244  
10 11     11   75 use vars qw($gendertab $pluraltab $rootconstab $subjtab);
  11         36  
  11         886  
11 11     11   58 use vars qw($cadhctab $cadhgtab $cadhutab);
  11         31  
  11         619  
12 11     11   56 use vars qw($classtab);
  11         20  
  11         108899  
13             @ISA = qw(Exporter);
14              
15             # Items to export into callers namespace by default. Note: do not export
16             # names by default without a very good reason. Use EXPORT_OK instead.
17             # Do not simply export all your public functions/methods/constants.
18              
19             # This allows declaration use Lingua::Zompist::Barakhinei ':all';
20             # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
21             # will save memory.
22             %EXPORT_TAGS = (
23             'tabs' => [ qw(
24             $gendertab
25             $pluraltab
26             $rootconstab
27             $subjtab
28             $cadhutab
29             $cadhgtab
30             $cadhctab
31             ) ],
32             'all' => [ qw(
33             demeric
34             scrifel
35             izhcrifel
36             budemeric
37             buscrifel
38             befel
39             part
40             noun
41             adj
42             ) ],
43             );
44              
45             push @{$EXPORT_TAGS{'all'}}, @{$EXPORT_TAGS{'tabs'}};
46              
47             @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
48              
49             @EXPORT = qw(
50            
51             );
52             $VERSION = '0.02';
53              
54             my %verb = (demeric => \&demeric,
55             scrifel => \&scrifel,
56             izhcrifel => \&izhcrifel,
57             budemeric => \&budemeric,
58             buscrifel => \&buscrifel,
59             befel => \&befel,
60             part => \&part,
61             );
62              
63             my @persons = qw(sû lê ât ta mukh kâ);
64              
65             my @cases = qw(nom gen acc dat);
66              
67             my @numbers = qw(sing pl);
68              
69             # Some handy things for -i- insertion and moving stress
70             my $cons = qr/(?:[ctdsknlr]h|[pbtdkgfvszhmnlr])/;
71             my $consend = qr/[hpbtdkgfvszhmnlr]$/;
72             my $vow = qr/[aeiouâêîôûAEIOUÂÊÎÔÛ]/;
73              
74             # spirant forms
75             my %spir = (
76             d => 'dh',
77             t => 'th',
78             p => 'v',
79             );
80              
81              
82             # Verbs with stems ending in -c in Cadhinor
83             $cadhctab = {
84             'dichi' => 'DUCIR',
85             'faichi' => 'FAUCIR',
86             'farki' => 'FARCIR',
87             'fênki' => 'VENCIR',
88             'foka' => 'VOCAN',
89             'hashki' => 'HASCIR',
90             'hêshki' => 'HESCIR',
91             'kaoka' => 'CAUCAN',
92             'kashki' => 'KASCIR',
93             'kêshkê' => 'KESCEN',
94             'krêshki' => 'CRESCIR',
95             'lachê' => 'LACEN',
96             'lêshkê' => 'LESCEN',
97             'manka' => 'MANCAN',
98             'oloka' => 'OLOCAN',
99             'prechê' => 'PRECER',
100             'rashki' => 'RASCIR',
101             'shkolichê' => 'SCOLICER',
102             'snuka' => 'SNUCAN',
103             'tôshkê' => 'TOSCEN',
104             'trankê' => 'TRANCEN',
105             };
106              
107             # Verbs with stems ending in -g in Cadhinor
108             $cadhgtab = {
109             'benhi' => 'BENGIR',
110             'briga' => 'BRIGAN',
111             'fachi' => 'VAGIR',
112             'glonhê' => 'GLONGEC',
113             'grochê' => 'GROGEC',
114             'hachê' => 'IAGEN',
115             'ilhê' => 'ULGEC',
116             'klachê' => 'CLAGER',
117             'kochi' => 'COGIR',
118             'krechê' => 'CREGEN',
119             'lega' => 'LEGAN',
120             'mêrgê' => 'MERGEN',
121             'nochê' => 'NOGEN',
122             'puga' => 'PUGAN',
123             'trachê' => 'TRAGEN',
124             'troga' => 'TROGAN',
125             };
126              
127             # Verbs with stems ending in -uC in Cadhinor
128             $cadhutab = {
129             'burukha' => 'BURUKHAN',
130             'chidê' => 'CIUDER',
131             'chura' => 'TURAN',
132             'dhirê' => 'DHUREC',
133             'dichi' => 'DUCIR',
134             'dimê' => 'DUMEC',
135             'faichi' => 'FAUCIR',
136             'faoba' => 'FAUBAN',
137             'fedhura' => 'VETHURAN',
138             'fura' => 'FURAN',
139             'glunti' => 'GLUNTIR',
140             'gushta' => 'GUSTAN',
141             'hizi' => 'IUSIR',
142             'idura' => 'IDURAN',
143             'ilhê' => 'ULGEC',
144             'ilubra' => 'ILUBRAN',
145             'ishkuza' => 'ISKUSAN',
146             'izubrê' => 'ISUBREN',
147             'kaoka' => 'CAUCAN',
148             'kitê' => 'CUTEC',
149             'kupi' => 'CULPIR',
150             'kurê' => 'CURREC',
151             'laoda' => 'LAUDAN',
152             'laota' => 'LAUTAN',
153             'liri' => 'LURIR',
154             'lôndura' => 'LONDURAN',
155             'meundê' => 'MEHUNDEN',
156             'niri' => 'NURIR',
157             'plii' => 'PLUHIR',
158             'pua' => 'PUHAN',
159             'puga' => 'PUGAN',
160             'raola' => 'RAULAN',
161             'rênlaoda' => 'RENLAUDAN',
162             'rêshkuli' => 'RESCULLIR',
163             'ridhê' => 'RUTHER',
164             'rizundê' => 'RISUNDEN',
165             'shkechubrê' => 'SCEIUBREN',
166             'shpiri' => 'SPURIR',
167             'sidi' => 'SUDIR',
168             'snuka' => 'SNUCAN',
169             'subra' => 'SUBRAN',
170             'sudri' => 'SUDRIR',
171             'taobrê' => 'TAUBREN',
172             'traoda' => 'TRAUDAN',
173             'ubri' => 'UBRIR',
174             };
175              
176             # Verb classes
177             $classtab = {
178             }; # %class
179              
180             # Separate subjunctive stems
181             $subjtab = {
182             'achupua' => 'achupoa',
183             'da' => 'dona',
184             'dichi' => 'doki',
185             'feriê' => 'fêrsê',
186             'fôtê' => 'fêlsê',
187             'hizi' => 'hôrsi',
188             'ihmêta' => 'ihmêrsa',
189             'kêshkê' => 'kêsê',
190             'kolaoda' => 'koloda',
191             'kudichi' => 'kudoki',
192             'laoda' => 'loda',
193             'lega' => 'loga',
194             'lêshkê' => 'lêsê',
195             'mêta' => 'mêrsa',
196             'noê' => 'nozê',
197             'pua' => 'poa',
198             'puga' => 'poga',
199             'rênlaoda' => 'rênloda',
200             'rênlelê' => 'rênlêlsê',
201             'shterê' => 'shtêrsê',
202             'sôtê' => 'sêlsê',
203             'subra' => 'sôbra',
204             'tôshkê' => 'tôsê',
205             }; # $subjtab
206              
207              
208             my %demeric = (
209             'epeza' => [ qw( ûzâ ûzê epê epeza epezu ûzôn ) ],
210             'eza' => [ qw( sâ sê ê eza ezu sôn ) ],
211             'fâli' => [ qw( fâl fêl fêl fâlu fâlu fâlîn ) ],
212             'foli' => [ qw( ful ful fut folu folu folîn ) ],
213             'hizi' => [ qw( huz hu hut hizu hizu hizîn ) ],
214             'kedhê' => [ qw( kedhâ kedhê kedhu kedha kedhu kên ) ],
215             'lhibê' => [ qw( lhua lhû lhu lhubu lhubu lôn ) ],
216             'nhê' => [ qw( nhe ni ni nheza nhezu nhên ) ],
217             'oi' => [ qw( oh fi fit ou ou oîn ) ],
218             'shkrivê' => [ qw( shkriva shkri shkri shkrivu shkrivu shkrivôn ) ],
219             'shtanê' => [ qw( shtâ shtê shtê shtana shtanu shtôn ) ],
220             'rênshtanê' => [ qw( rênshtâ rênshtê rênshtê rênshtana rênshtanu rênshtôn ) ],
221             );
222              
223             sub demeric {
224 23     23 1 67 my $verb = shift;
225 23         41 my $class = shift;
226 23         40 my $stem = $verb;
227 23         119 my $table;
228              
229 23 100       167 return $demeric{$verb} if exists $demeric{$verb};
230              
231 12 50 33     48 if(! defined($class) && exists $classtab->{$verb}) {
232 0         0 $class = $classtab->{$verb};
233             }
234              
235 12 50 33     60 $class = 2 if !defined($class) && $verb =~ /a$/;
236 12 50 33     40 $class = 3 if !defined($class) && $verb =~ /ê$/;
237 12 50 33     37 $class = 4 if !defined($class) && $verb =~ /i$/;
238 12 50       31 $class = 0 unless defined $class;
239              
240 12 100 66     166 if($class == 1 && $stem =~ s/ê$//) {
    100 66        
    100 33        
    100          
    50          
241 2         26 $table = [ map "$stem$_", qw( a û ê u u ôn ) ];
242             } elsif($stem =~ s/a$//) {
243 3         33 $table = [ map "$stem$_", qw( â ê ê a u ôn ) ];
244             } elsif($class == 3 && $stem =~ s/ê$//) {
245 2         18 $table = [ map "$stem$_", qw( â ê ê a u ên ) ];
246             } elsif($stem =~ s/i$//) {
247 2         19 $table = [ map "$stem$_", '', qw( û i u u în ) ];
248             } elsif($class == 5 && $stem =~ s/ê$//) {
249 3         30 $table = [ map "$stem$_", '', qw( û ê u u un ) ];
250             } else {
251 0         0 return;
252             }
253              
254             # Cadhinor verbs in -c- and -g-
255 12 100 100     137 if($class == 1 || $class == 4 || $class == 5) {
    50 100        
      66        
256 7         13 for(@{$table}[0,3,4,5]) {
  7         22  
257 28 100       104 if(exists $cadhctab->{$verb}) {
    100          
258 4         25 s/ch([auoâô]?n?)$/k$1/;
259             } elsif(exists $cadhgtab->{$verb}) {
260 8         54 s/ch([auoâô]?n?)$/g$1/;
261             }
262             }
263 7         16 for(@{$table}[1,2]) {
  7         189  
264 14 100       56 if(exists $cadhctab->{$verb}) {
    100          
265 2         6 s/k([eiêîû]n?)$/ch$1/;
266             } elsif(exists $cadhgtab->{$verb}) {
267 4         13 s/g([eiêîû]n?)$/ch$1/;
268             }
269             }
270             } elsif($class == 2 || $class == 3) {
271 5         11 for(@{$table}[0]) {
  5         17  
272 5 100       37 if(exists $cadhctab->{$verb}) {
    100          
273 1         5 s/ch([auoâô]?n?)$/k$1/;
274             } elsif(exists $cadhgtab->{$verb}) {
275 1         10 s/ch([auoâô]?n?)$/g$1/;
276             }
277             }
278 5         12 for(@{$table}[1,2]) {
  5         14  
279 10 100       40 if(exists $cadhctab->{$verb}) {
    100          
280 2         17 s/k([eiêîû]n?)$/ch$1/;
281             } elsif(exists $cadhgtab->{$verb}) {
282 2         5 s/g([eiêîû]n?)$/ch$1/;
283             }
284             }
285             }
286              
287 12         29 for(@$table) {
288 72         168 s/shtu$/kchu/;
289 72         84 s/sht$/ch/;
290 72         1145 s/g$/k/;
291 72         118 s/b$/p/;
292             }
293              
294             # spirantise -d -t -p in 4th and 5th conjugation
295 12 100 100     148 if(($class == 4 || $class == 5) && $verb =~ /$vow[dtp][êai]$/o) {
      100        
296 1         2 for($table->[0]) {
297 1         14 s/d$/dh/;
298 1         3 s/t$/th/;
299 1         3 s/p$/f/;
300             }
301              
302 1         4 for(@{$table}[3,4,5]) {
  1         3  
303 3         21 s/d(un?|în)$/dh$1/;
304 3         7 s/t(un?|în)$/th$1/;
305 3         6 s/p(un?|în)$/v$1/;
306             }
307             }
308              
309             # front and back vowel alternations for Cadhinor verbs in -u-
310 12 100       47 if(exists $cadhutab->{$verb}) {
311 2         6 for(@$table) {
312 12         262 s/i($cons+[aouâôû]?)$/o$1/;
313 12         107 s/u($cons+[êiî]n?)$/i$1/;
314             }
315             }
316              
317 12         294 return $table;
318             } # demeric
319              
320             my %scrifel = (
321             'epeza' => [ qw( ûzi ûzi epâ ûzu ûzê ûzîn ) ],
322             'eza' => [ qw( fuch fuch fâ fu fuê fûn ) ],
323             'kedhê' => [ qw( kedhi kedhi kiâ kedhu kedhê kedhîn ) ],
324             );
325              
326             sub scrifel {
327 15     15 1 43 my $verb = shift;
328 15         27 my $class = shift;
329 15         25 my $stem = $verb;
330 15         18 my $table;
331              
332 15 100       73 return $scrifel{$verb} if exists $scrifel{$verb};
333              
334 12 50 33     43 if(! defined($class) && exists $classtab->{$verb}) {
335 0         0 $class = $classtab->{$verb};
336             }
337              
338 12 50 33     59 $class = 2 if !defined($class) && $verb =~ /a$/;
339 12 50 33     36 $class = 3 if !defined($class) && $verb =~ /ê$/;
340 12 50 33     33 $class = 4 if !defined($class) && $verb =~ /i$/;
341 12 50       30 $class = 0 unless defined $class;
342              
343 12 100 66     156 if($class == 1 && $stem =~ s/ê$//) {
    100 66        
    100 33        
    100          
    50          
344 4         30 $table = [ map "$stem$_", qw( i î ), '', qw( ê ê în ) ];
345             } elsif($stem =~ s/a$//) {
346 2         16 $table = [ map "$stem$_", qw( i i â u ê în ) ];
347             } elsif($class == 3 && $stem =~ s/ê$//) {
348 2         24 $table = [ map "$stem$_", qw( i i â u ê în ) ];
349             } elsif($stem =~ s/i$//) {
350 2         22 $table = [ map "$stem$_", qw( i ê â ê ê ên ) ];
351             } elsif($class == 5 && $stem =~ s/ê$//) {
352 2         15 $table = [ map "$stem$_", qw( i ê ), '', qw( ê ê ên ) ];
353             } else {
354 0         0 return;
355             }
356              
357             # Cadhinor verbs in -c- and -g-
358 12 100 100     101 if($class == 1 || $class == 2 || $class == 3) {
    100 100        
359 8         19 for(@$table) {
360 48 100       286 if(exists $cadhctab->{$verb}) {
    100          
361 6         6 s/ch([êâu]?)$/k$1/;
362 6         20 s/k([iî]n?)$/ch$1/;
363             } elsif(exists $cadhgtab->{$verb}) {
364 12         51 s/ch([êâu]?)$/g$1/;
365 12         29 s/g([iî]n?)$/ch$1/;
366             }
367             }
368             } elsif($class == 4) {
369 2         5 for(@{$table}[2]) {
  2         8  
370 2 100       15 if(exists $cadhctab->{$verb}) {
    50          
371 1         8 s/ch(â)$/k$1/;
372             } elsif(exists $cadhgtab->{$verb}) {
373 0         0 s/ch(â)$/g$1/;
374             }
375             }
376             }
377              
378 12         25 for(@$table) {
379 72         76 s/shtu$/kchu/;
380 72         78 s/g$/k/;
381 72         96 s/b$/p/;
382             }
383              
384             # -sht --> -ch in III.sg for 1st conjugation
385             # spirantise -d -t -p in 1st conjugation
386 12 100       32 if($class == 1) {
387 4         9 for($table->[2]) {
388 4         8 s/sht$/ch/;
389              
390 4 100       56 if($verb =~ /$vow[dtp][êai]$/o) {
391 1         5 s/d$/dh/;
392 1         3 s/t$/th/;
393 1         3 s/p$/f/;
394             }
395             }
396             }
397              
398             # front and back vowel alternations for Cadhinor verbs in -u-
399 12 100       41 if(exists $cadhutab->{$verb}) {
400 1         3 for(@$table) {
401 6         87 s/i($cons+[uâ]?)$/o$1/;
402 6         52 s/u($cons+[êiî]n?)$/i$1/;
403             }
404             }
405              
406 12         84 return $table;
407             } # scrifel
408              
409             my %izhcrifel = (
410             'eza' => [ qw( firi firi furâ furu furê firiôn ) ],
411             );
412              
413             sub izhcrifel {
414 6     6 1 26 my $verb = shift;
415 6         12 my $class = shift;
416 6         11 my $stem = $verb;
417 6         10 my $table;
418              
419 6 100       35 return $izhcrifel{$verb} if exists $izhcrifel{$verb};
420              
421 5 50 33     39 if(! defined($class) && exists $classtab->{$verb}) {
422 0         0 $class = $classtab->{$verb};
423             }
424              
425 5 50 33     47 $class = 2 if !defined($class) && $verb =~ /a$/;
426 5 50 33     21 $class = 3 if !defined($class) && $verb =~ /ê$/;
427 5 50 33     14 $class = 4 if !defined($class) && $verb =~ /i$/;
428 5 50       13 $class = 0 unless defined $class;
429              
430 5 100 66     79 if($class == 1 && $stem =~ s/ê$//) {
    100 66        
    100 33        
    100          
    50          
431 1         25 $table = [ map "$stem$_", qw( ri rî êr rê rê rîn ) ];
432             } elsif($stem =~ s/a$//) {
433 1         7 $table = [ map "$stem$_", qw( ri ri râ ru rê rîn ) ];
434             } elsif($class == 3 && $stem =~ s/ê$//) {
435 1         10 $table = [ map "$stem$_", qw( ri ri râ ru rê rîn ) ];
436             } elsif($stem =~ s/i$//) {
437 1         9 $table = [ map "$stem$_", qw( ri rê râ rê rê rên ) ];
438             } elsif($class == 5 && $stem =~ s/ê$//) {
439 1         10 $table = [ map "$stem$_", qw( ri rê êr rê rê rên ) ];
440             } else {
441 0         0 return;
442             }
443              
444 5         41 return $table;
445             } # izhcrifel
446              
447             my %budemeric = (
448             'eza' => [ qw( êshta êshtê êshtê êshta êshtu êshtôn ) ],
449             );
450              
451             sub budemeric {
452 6     6 1 24 my $verb = shift;
453 6         15 my $class = shift;
454 6         13 my $stem = $verb;
455 6         9 my $table;
456              
457 6 100       31 return $budemeric{$verb} if exists $budemeric{$verb};
458              
459 5 50       17 return demeric($subjtab->{$verb}, $class) if exists $subjtab->{$verb};
460              
461 5 50 33     45 if(! defined($class) && exists $classtab->{$verb}) {
462 0         0 $class = $classtab->{$verb};
463             }
464              
465 5 50 33     18 $class = 2 if !defined($class) && $verb =~ /a$/;
466 5 50 33     14 $class = 3 if !defined($class) && $verb =~ /ê$/;
467 5 50 33     19 $class = 4 if !defined($class) && $verb =~ /i$/;
468 5 50       13 $class = 0 unless defined $class;
469              
470 5 100 66     85 if($class == 1 && $stem =~ s/ê$/t/) {
    100 66        
    100 33        
    100          
    50          
471 1         32 $table = [ map "$stem$_", qw( a ê ê u u ôn ) ];
472             } elsif($stem =~ s/a$/m/) {
473 1         10 $table = [ map "$stem$_", qw( â ê ê a u ôn ) ];
474             } elsif($class == 3 && $stem =~ s/ê$/m/) {
475 1         9 $table = [ map "$stem$_", qw( â ê ê a u ên ) ];
476             } elsif($stem =~ s/i$/t/) {
477 1         42 $table = [ map "$stem$_", '', '', qw( i u u în ) ];
478 1         4 for(@$table) {
479 6         12 s/t$/ech/;
480 6         11 s/tu$/chu/;
481 6         26 s/t(ti|chu|tîn)$/$1/; # for beshti
482             }
483             } elsif($class == 5 && $stem =~ s/ê$/t/) {
484 1         11 $table = [ map "$stem$_", '', '', qw( i u u în ) ];
485 1         4 for(@$table) {
486 6         12 s/t$/ech/;
487 6         13 s/tu$/chu/;
488             }
489             } else {
490 0         0 return;
491             }
492              
493 5         44 return $table;
494             } # budemeric
495              
496              
497             my %buscrifel = (
498             'eza' => [ qw( êshka êshkê êshkê êshka êshku êshkôn ) ],
499             );
500              
501             sub buscrifel {
502 6     6 1 25 my $verb = shift;
503 6         14 my $class = shift;
504 6         13 my $stem = $verb;
505 6         9 my $table;
506              
507 6 100       37 return $buscrifel{$verb} if exists $buscrifel{$verb};
508              
509 5 50       21 return scrifel($subjtab->{$verb}, $class) if exists $subjtab->{$verb};
510              
511 5 50 33     49 if(! defined($class) && exists $classtab->{$verb}) {
512 0         0 $class = $classtab->{$verb};
513             }
514              
515 5 50 33     20 $class = 2 if !defined($class) && $verb =~ /a$/;
516 5 50 33     18 $class = 3 if !defined($class) && $verb =~ /ê$/;
517 5 50 33     18 $class = 4 if !defined($class) && $verb =~ /i$/;
518 5 50       12 $class = 0 unless defined $class;
519              
520 5 100 66     83 if($class == 1 && $stem =~ s/ê$/k/) {
    100 66        
    100 33        
    100          
    50          
521 1         25 $table = [ map "$stem$_", qw( a ê ê u u ôn ) ];
522 1         3 for(@$table) {
523 6         15 s/kê$/chê/;
524             }
525             } elsif($stem =~ s/a$/n/) {
526 1         11 $table = [ map "$stem$_", qw( â ê ê a u ôn ) ];
527             } elsif($class == 3 && $stem =~ s/ê$/n/) {
528 1         11 $table = [ map "$stem$_", qw( â ê ê a u ên ) ];
529             } elsif($stem =~ s/i$/r/) {
530 1         10 $table = [ map "$stem$_", '', '', qw( i u u în ) ];
531 1         5 for(@$table) {
532 6         16 s/r$/ir/;
533             }
534             } elsif($class == 5 && $stem =~ s/ê$/r/) {
535 1         10 $table = [ map "$stem$_", '', '', qw( i u u în ) ];
536 1         6 for(@$table) {
537 6         16 s/r$/ir/;
538             }
539             } else {
540 0         0 return;
541             }
542              
543 5         45 return $table;
544             } # bucrifel
545              
546              
547             my %befel = (
548             );
549              
550             sub befel {
551 6     6 1 21 my $verb = shift;
552 6         12 my $class = shift;
553 6         11 my $stem = $verb;
554 6         11 my $table;
555              
556 6 50       26 return $befel{$verb} if exists $befel{$verb};
557              
558 6 50 33     24 if(! defined($class) && exists $classtab->{$verb}) {
559 0         0 $class = $classtab->{$verb};
560             }
561              
562 6 50 33     44 $class = 2 if !defined($class) && $verb =~ /a$/;
563 6 50 33     18 $class = 3 if !defined($class) && $verb =~ /ê$/;
564 6 50 33     15 $class = 4 if !defined($class) && $verb =~ /i$/;
565 6 50       15 $class = 0 unless defined $class;
566              
567 6 100 66     83 if($class == 1 && $stem =~ s/ê$//) {
    100 66        
    100 33        
    100          
    50          
568 1         11 $table = [ map "$stem$_", '', '', 'a', '', 'êl', 'an' ];
569             } elsif($stem =~ s/a$//) {
570 2         18 $table = [ map "$stem$_", '', '', 'a', '', 'el', 'an' ];
571             } elsif($class == 3 && $stem =~ s/ê$//) {
572 1         9 $table = [ map "$stem$_", '', '', 'a', '', 'el', 'an' ];
573             } elsif($stem =~ s/i$//) {
574 1         9 $table = [ map "$stem$_", '', '', 'a', '', 'u', 'an' ];
575             } elsif($class == 5 && $stem =~ s/ê$//) {
576 1         12 $table = [ map "$stem$_", '', '', 'a', '', 'u', 'an' ];
577             } else {
578 0         0 return;
579             }
580              
581 6         24 for(@$table) {
582             # Cadhinor verbs in -c- and -g-
583 36 50       110 if(exists $cadhctab->{$verb}) {
    50          
584 0         0 s/k([eiêîû]?)$/ch/;
585             } elsif(exists $cadhgtab->{$verb}) {
586 0         0 s/g([eiêîû]?)$/ch/;
587             }
588              
589 36         45 s/shtu$/kchu/;
590 36         58 s/sht(an?)$/kch$1/;
591 36         45 s/sht$/ch/;
592 36         57 s/g$/k/;
593 36         64 s/b$/p/;
594             }
595              
596             # front and back vowel alternation in II.sg of 2nd and 3rd conjugation
597 6 100 100     36 if($verb =~ /a$/ || $class == 3) {
598 3         7 for($table->[1]) {
599 3         71 s/u($cons+)$/i$1/;
600             }
601             }
602              
603             # front and back vowel alternations in III.sg + III.pl
604             # and spirantisation
605 6         10 for(@{$table}[2,5]) {
  6         14  
606 12         23 s/([dtp])(an?)$/$spir{$1}$2/;
607 12         105 s/u($cons+an?)$/i$1/;
608             }
609              
610             # I.sg and I.pl don't exist
611 6         13 @{$table}[0,3] = (undef, undef);
  6         12  
612              
613 6         39 return $table;
614             } # befel
615              
616              
617             my %part = (
618             );
619              
620             # Participles
621             sub part {
622 10     10 1 32 my $verb = shift;
623 10         16 my $class = shift;
624 10         18 my $stem = $verb;
625              
626 10         15 my($present, $past);
627              
628 10 50       37 if(exists $part{$verb}) {
629 0         0 ($present, $past) = @{ $part{$verb} };
  0         0  
630             } else {
631 10 50 33     41 if(! defined($class) && exists $classtab->{$verb}) {
632 0         0 $class = $classtab->{$verb};
633             }
634              
635 10 50 33     53 $class = 2 if !defined($class) && $verb =~ /a$/;
636 10 50 33     31 $class = 3 if !defined($class) && $verb =~ /ê$/;
637 10 50 33     26 $class = 4 if !defined($class) && $verb =~ /i$/;
638 10 50       23 $class = 0 unless defined $class;
639              
640 10 100 66     138 if($class == 1 && $stem =~ s/ê$//) {
    100 66        
    100 33        
    100          
    50          
641 2         14 ($past, $present) = map "$stem$_", 'êl', 'il';
642             } elsif($stem =~ s/a$//) {
643 2         13 ($past, $present) = map "$stem$_", 'u', 'ê';
644             } elsif($class == 3 && $stem =~ s/ê$//) {
645 2         15 ($past, $present) = map "$stem$_", 'u', 'ê';
646             } elsif($stem =~ s/i$//) {
647 2         14 ($past, $present) = map "$stem$_", 'u', 'i';
648             } elsif($class == 5 && $stem =~ s/ê$//) {
649 2         15 ($past, $present) = map "$stem$_", 'êl', 'ê';
650             } else {
651 0         0 return;
652             }
653             }
654              
655 10         30 for($past, $present) {
656             # Cadhinor verbs in -c- and -g-
657 20 50       77 if(exists $cadhctab->{$verb}) {
    50          
658 0         0 s/ch([auoâô])$/k/;
659 0         0 s/k([eiêîû])$/ch/;
660             } elsif(exists $cadhgtab->{$verb}) {
661 0         0 s/ch([auoâô]?)$/g/;
662 0         0 s/g([eiêîû])$/ch/;
663             }
664              
665 20         54 s/shtu$/kchu/;
666             }
667              
668 10 100       77 return wantarray ? ($present, $past) : [ $present, $past ];
669             }
670              
671              
672              
673             $gendertab = {
674             'âshta' => 'masc',
675             'eli' => 'masc',
676             'lônd' => 'masc',
677              
678             'kal' => 'neut',
679             'manu' => 'neut',
680             'nôshti' => 'neut',
681             'shkor' => 'neut',
682             'shpâ' => 'neut',
683              
684             'chir' => 'fem',
685             'elorê' => 'fem',
686             'kabrâ' => 'fem',
687             'medhi' => 'fem',
688             'nor' => 'fem',
689              
690             'achel' => 'fem',
691             'acher' => 'masc',
692             'Achirê' => 'fem',
693             'âdh' => 'masc',
694             'âdhechu' => 'masc',
695             'adipa' => 'masc',
696             'adlelek' => 'fem',
697             'adlelu' => 'fem',
698             'air' => 'fem',
699             }; # $gendertab
700              
701             $pluraltab = {
702             'âshta' => 'âshtâ',
703             'eli' => 'eliri',
704             'lônd' => 'lôndi',
705              
706             'kal' => 'kalo',
707             'manu' => 'mani',
708             'nôshti' => 'nôkchu',
709             'shkor' => 'shkoru',
710             'shpâ' => 'shpao',
711              
712             'chir' => 'chirâ',
713             'elorê' => 'eloriê',
714             'kabrâ' => 'kabrachâ',
715             'medhi' => 'medhiê',
716             'nor' => 'norê',
717              
718             'âdhechu' => 'âdhechuni',
719             }; # $pluraltab
720              
721             sub noun {
722 64     64 1 216 my $noun = shift;
723 64         157 my $gender = shift;
724 64         130 my $plural = shift;
725 64         105 my $table;
726              
727             # is it a pronoun?
728             # nom acc dat gen nom acc/dat gen
729 64 100       418 return [ qw( sû sêth sû (eri) ta tâ (tandê) ) ] if $noun eq 'sû';
730 63 100       252 return [ qw( lê êk lê (leri) mukh mî (mundê) ) ] if $noun eq 'lê';
731 62 100       191 return [ qw( ât âtô âta âti kâ kâ (kandê) ) ] if $noun eq 'ât';
732 61 100       194 return [ qw( tot tô tota toti kâ kâ (kandê) ) ] if $noun eq 'tot';
733 60 100       156 return [ qw( kêt kêtô kêta kêti ), (undef) x 3 ] if $noun eq 'kêt';
734 59 100       142 return [ qw( ta tâ tao (tandê) ), (undef) x 3 ] if $noun eq 'ta';
735 58 100       169 return [ qw( mukh mî mî (mundê) ), (undef) x 3 ] if $noun eq 'mukh';
736 57 100       139 return [ qw( kâ kâ kâ (kandê) ), (undef) x 3 ] if $noun eq 'kâ';
737 56 100       121 return [ '', qw( zêth zeu zei ), '', qw( zaa zai ) ] if $noun eq 'zê';
738 55 100       267 return [ '', qw( zaa zau zai ), (undef) x 3 ] if $noun eq 'za';
739              
740             # otherwise it's a noun.
741              
742             # irregular oblique stem
743 54 50       135 return [ qw( pû pû pea peo pei peî peich ) ] if $noun eq 'pû';
744              
745 54 100 66     331 if(!defined($gender) && exists $gendertab->{$noun}) {
746 26         68 $gender = $gendertab->{$noun};
747             }
748              
749 54 50       140 if(!defined($gender)) {
750             # try to guess based on the ending
751 0 0 0     0 if($noun =~ /a$/) {
    0 0        
    0 0        
    0 0        
    0 0        
    0 0        
    0 0        
      0        
      0        
      0        
752 0         0 $gender = 'masc';
753             } elsif($noun =~ /ê$/) {
754 0         0 $gender = 'fem';
755             } elsif($noun =~ /$consend/o && defined $plural && $plural =~ /i$/) {
756 0         0 $gender = 'masc'; # can't detect anisosyllabic nouns as they
757             # could be neuter
758             } elsif($noun =~ /(?:$cons|i)$/o && defined $plural && $plural =~ /[ou]$/) {
759 0         0 $gender = 'neut';
760             } elsif($noun =~ /â$/ && defined $plural && $plural =~ /ao$/) {
761 0         0 $gender = 'neut';
762             } elsif($noun =~ /(?:$cons|i)$/o && defined $plural && $plural =~ /[âê]$/) {
763 0         0 $gender = 'fem';
764             } elsif($noun =~ /â$/ && defined $plural && $plural =~ /ach$/) {
765 0         0 $gender = 'fem';
766             } else {
767 0         0 return;
768             }
769             }
770              
771 54 100 66     270 if(!defined($plural) && exists $pluraltab->{$noun}) {
772 26         60 $plural = $pluraltab->{$noun};
773             }
774              
775 54 50       120 if(!defined($plural)) {
776             # try to guess based on the ending
777 0 0 0     0 if($noun =~ /$consend/o && $gender eq 'masc') {
    0 0        
    0 0        
    0 0        
    0 0        
    0 0        
    0 0        
    0 0        
    0 0        
    0 0        
    0 0        
    0 0        
778 0         0 $plural = $noun . 'i'; # assume isosyllabic
779             } elsif($noun =~ /a$/ && $gender eq 'masc') {
780 0         0 ($plural = $noun) =~ s/a$/â/;
781             } elsif($noun =~ /u$/ && $gender eq 'masc') {
782 0         0 $plural = $noun . 'li'; # assume from -ul
783             } elsif($noun =~ /$consend/o && $gender eq 'neut') {
784 0         0 $plural = $noun . 'o'; # more than twice as comman as -u
785             } elsif($noun =~ /i$/ && $gender eq 'neut') {
786 0         0 ($plural = $noun) =~ s/i$/u/;
787             } elsif($noun =~ /u$/ && $gender eq 'neut') {
788 0         0 ($plural = $noun) =~ s/u$/i/;
789             } elsif($noun =~ /â$/ && $gender eq 'neut') {
790 0         0 ($plural = $noun) =~ s/â$/ao/;
791             } elsif($noun =~ /$consend/o && $gender eq 'fem') {
792 0         0 $plural = $noun . 'â'; # "very common"
793             } elsif($noun =~ /u$/ && $gender eq 'fem') {
794 0         0 $plural = $noun . 'lâ'; # assume from -ul
795             } elsif($noun =~ /i$/ && $gender eq 'fem') {
796 0         0 $plural = $noun . 'ê';
797             } elsif($noun =~ /ê$/ && $gender eq 'fem') {
798 0         0 ($plural = $noun) =~ s/ê/iê/;
799             } elsif($noun =~ /â$/ && $gender eq 'fem') {
800 0         0 ($plural = $noun) =~ s/â/achâ/;
801             } else {
802 0         0 return;
803             }
804             }
805              
806 54         109 my $sgstem = $noun;
807 54         85 my $plstem = $plural;
808              
809 54 100       227 if($gender eq 'masc') {
    100          
    50          
810 14 50 33     188 if($sgstem =~ /u$/ && $plstem =~ s/li$//) {
    100 33        
    50          
811 0         0 $table = [ map("$sgstem$_", '', '', 'la', 'lo'),
812             map("$plstem$_", 'li', 'lî', 'lich') ];
813             } elsif($plstem =~ s/i$//) {
814 10         120 $table = [ map("$sgstem$_", '', '', 'a', 'o'),
815             map("$plstem$_", 'i', 'î', 'ich') ];
816             } elsif($sgstem =~ s/a$// && $plstem =~ s/â$//) {
817 4         46 $table = [ map("$sgstem$_", 'a', '', 'a', 'o'),
818             map("$plstem$_", 'â', 'î', 'ach') ];
819             } else {
820 0         0 return;
821             }
822             } elsif($gender eq 'neut') {
823 20 100 100     15582 if($sgstem =~ /$consend/o && $plstem =~ s/o$//) {
    100 66        
    100 66        
    100 66        
    50 33        
824 4         67 $table = [ map("$sgstem$_", '', 'u', 'u', 'o'),
825             map("$plstem$_", 'o', 'oi', 'och') ];
826             } elsif($sgstem =~ /$consend/o && $plstem =~ s/u$//) {
827 4         47 $table = [ map("$sgstem$_", '', 'u', 'u', 'o'),
828             map("$plstem$_", 'u', 'î', 'ich') ];
829             } elsif($sgstem =~ s/i$// && $plstem =~ s/u$//) {
830 4         561 $table = [ map("$sgstem$_", 'i', 'i', 'i', 'io'),
831             map("$plstem$_", 'u', 'î', 'ich') ];
832             } elsif($sgstem =~ s/u$// && $plstem =~ s/i$//) {
833 4         46 $table = [ map("$sgstem$_", 'u', '', 'u', 'o'),
834             map("$plstem$_", 'i', 'î', 'ich') ];
835             } elsif($sgstem =~ s/â$// && $plstem =~ s/ao$//) {
836 4         52 $table = [ map("$sgstem$_", 'â', 'â', 'â', 'ach'),
837             map("$plstem$_", 'ao', 'aoi', 'aoch') ];
838             } else {
839 0         0 return;
840             }
841             } elsif($gender eq 'fem') {
842 20 100 100     417 if($sgstem =~ /$consend/o && $plstem =~ s/â$//) {
    100 66        
    100 66        
    100 66        
    50 33        
    0 0        
    0 0        
843 4         45 $table = [ map("$sgstem$_", '', 'a', 'ê', 'ach'),
844             map("$plstem$_", 'â', 'êi', 'ech') ];
845             } elsif($sgstem =~ /$consend/o && $plstem =~ s/ê$//) {
846 4         49 $table = [ map("$sgstem$_", '', 'e', 'ê', 'ech'),
847             map("$plstem$_", 'ê', 'êi', 'ech') ];
848             } elsif($sgstem =~ /i$/ && $plstem =~ s/iê/i/) {
849 4         46 $table = [ map("$sgstem$_", '', '', 'ê', 'ch'),
850             map("$plstem$_", 'ê', 'a', 'ech') ];
851             } elsif($sgstem =~ s/ê$// && $plstem =~ s/ê$//) {
852 4         50 $table = [ map("$sgstem$_", 'ê', 'e', 'ê', 'ech'),
853             map("$plstem$_", 'ê', 'a', 'ech') ];
854             } elsif($sgstem =~ s/â$// && $plstem =~ s/â$//) {
855 4         43 $table = [ map("$sgstem$_", 'â', 'a', 'ê', 'ach'),
856             map("$plstem$_", 'â', 'a', 'ech') ];
857             } elsif($sgstem =~ /u$/ && $plstem =~ s/lâ$//) {
858 0         0 $table = [ map("$sgstem$_", '', 'la', 'lê', 'lach'),
859             map("$plstem$_", 'lâ', 'lêi', 'lech') ];
860             } elsif($sgstem =~ /u$/ && $plstem =~ s/â$//) { # chizu; others?
861 0         0 $table = [ map("$sgstem$_", '', 'a', 'ê', 'ach'),
862             map("$plstem$_", 'â', 'êi', 'ech') ];
863             } else {
864 0         0 return;
865             }
866             } else {
867 0         0 return;
868             }
869              
870 54         479 return $table;
871             }
872              
873              
874             # Lost consonants which are restored in all but s.nom. and m.s.acc.
875              
876             $rootconstab = {
877             'andû' => 'r',
878             'aveku' => 'r',
879             'dhu' => 'n',
880             'di' => 'n',
881             'du' => 'r',
882             'glûmu' => 'l',
883             'kê' => 'r',
884             'kônu' => 'l',
885             'kû' => 'r',
886             'melhu' => 'r',
887             'mu' => 'r',
888             'na' => 'n',
889             'osôku' => 'l',
890             'rhu' => 'm',
891             }; # $rootconstab
892              
893             sub adj {
894 8     8 1 32 my $adj = shift;
895 8         15 my $rootcons = shift;
896 8         18 my $stem = $adj;
897 8         12 my $table;
898              
899 8 100 100     60 if(!defined($rootcons) && exists $rootconstab->{$adj}) {
900 1         3 $rootcons = $rootconstab->{$adj};
901             }
902              
903 8 100       25 $rootcons = '' unless defined $rootcons;
904              
905 8 100 100     111 if($stem =~ /$consend/o || length $rootcons) {
    100          
    50          
    0          
906 4         94 $table = [ [ $stem, $stem, map "$stem$rootcons$_", qw( a o i î ich ) ],
907             [ $stem, map "$stem$rootcons$_", qw( u u o o î ich ) ],
908             [ $stem, map "$stem$rootcons$_", qw( a ê ach â êi ech ) ] ];
909             } elsif($stem =~ s/ê$//) {
910 2         44 $table = [ [ map "$stem$_", qw( ê ê a o ê î êch ) ],
911             [ map "$stem$_", qw( e ê ê o e ê ech ) ],
912             [ map "$stem$_", qw( ê e ê ech ê êi ech ) ] ];
913             } elsif($stem =~ s/i$//) {
914 2         46 $table = [ [ map "$stem$_", 'i', '', qw( i io i î ich ) ],
915             [ map "$stem$_", qw( i i i io u î ich ) ],
916             [ map "$stem$_", qw( i i iê ich iê ia iech ) ] ];
917             } elsif($stem =~ s/â$//) {
918 0         0 $table = [ [ map "$stem$_", qw( â â â ach ao aoi aoch ) ],
919             [ map "$stem$_", qw( â â â ach ao aoi aoch ) ],
920             [ map "$stem$_", qw( â a ê ach achâ acha achech ) ] ];
921             } else {
922 0         0 return;
923             }
924              
925 8         109 return $table;
926             }
927              
928             1;
929             __END__