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