xref: /openbsd-src/gnu/gcc/intl/eval-plural.h (revision 404b540a9034ac75a6199ad1a32d1bbc7a0d4210)
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