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
plural_eval(struct expression * pexp,unsigned long int n)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 }
109