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