*** empty log message ***
[m17n/m17n-im-config.git] / intl / eval-plural.h
1 /* Plural expression evaluation.
2    Copyright (C) 2000-2003 Free Software Foundation, Inc.
3
4    This program is free software; you can redistribute it and/or modify it
5    under the terms of the GNU Library General Public License as published
6    by the Free Software Foundation; either version 2, or (at your option)
7    any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Library General Public License for more details.
13
14    You should have received a copy of the GNU Library General Public
15    License along with this program; if not, write to the Free Software
16    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
17    USA.  */
18
19 #ifndef STATIC
20 #define STATIC static
21 #endif
22
23 /* Evaluate the plural expression and return an index value.  */
24 STATIC
25 unsigned long int
26 internal_function
27 plural_eval (struct expression *pexp, unsigned long int n)
28 {
29   switch (pexp->nargs)
30     {
31     case 0:
32       switch (pexp->operation)
33         {
34         case var:
35           return n;
36         case num:
37           return pexp->val.num;
38         default:
39           break;
40         }
41       /* NOTREACHED */
42       break;
43     case 1:
44       {
45         /* pexp->operation must be lnot.  */
46         unsigned long int arg = plural_eval (pexp->val.args[0], n);
47         return ! arg;
48       }
49     case 2:
50       {
51         unsigned long int leftarg = plural_eval (pexp->val.args[0], n);
52         if (pexp->operation == lor)
53           return leftarg || plural_eval (pexp->val.args[1], n);
54         else if (pexp->operation == land)
55           return leftarg && plural_eval (pexp->val.args[1], n);
56         else
57           {
58             unsigned long int rightarg = plural_eval (pexp->val.args[1], n);
59
60             switch (pexp->operation)
61               {
62               case mult:
63                 return leftarg * rightarg;
64               case divide:
65 #if !INTDIV0_RAISES_SIGFPE
66                 if (rightarg == 0)
67                   raise (SIGFPE);
68 #endif
69                 return leftarg / rightarg;
70               case module:
71 #if !INTDIV0_RAISES_SIGFPE
72                 if (rightarg == 0)
73                   raise (SIGFPE);
74 #endif
75                 return leftarg % rightarg;
76               case plus:
77                 return leftarg + rightarg;
78               case minus:
79                 return leftarg - rightarg;
80               case less_than:
81                 return leftarg < rightarg;
82               case greater_than:
83                 return leftarg > rightarg;
84               case less_or_equal:
85                 return leftarg <= rightarg;
86               case greater_or_equal:
87                 return leftarg >= rightarg;
88               case equal:
89                 return leftarg == rightarg;
90               case not_equal:
91                 return leftarg != rightarg;
92               default:
93                 break;
94               }
95           }
96         /* NOTREACHED */
97         break;
98       }
99     case 3:
100       {
101         /* pexp->operation must be qmop.  */
102         unsigned long int boolarg = plural_eval (pexp->val.args[0], n);
103         return plural_eval (pexp->val.args[boolarg ? 1 : 2], n);
104       }
105     }
106   /* NOTREACHED */
107   return 0;
108 }