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