1 /* Plural expression evaluation.
2    Copyright (C) 2000-2002 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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301,
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 unsigned long int plural_eval PARAMS ((struct expression *pexp,
25 					      unsigned long int n))
26      internal_function;
27 
28 STATIC
29 unsigned long int
30 internal_function
plural_eval(pexp,n)31 plural_eval (pexp, n)
32      struct expression *pexp;
33      unsigned long int n;
34 {
35   switch (pexp->nargs)
36     {
37     case 0:
38       switch (pexp->operation)
39 	{
40 	case var:
41 	  return n;
42 	case num:
43 	  return pexp->val.num;
44 	default:
45 	  break;
46 	}
47       /* NOTREACHED */
48       break;
49     case 1:
50       {
51 	/* pexp->operation must be lnot.  */
52 	unsigned long int arg = plural_eval (pexp->val.args[0], n);
53 	return ! arg;
54       }
55     case 2:
56       {
57 	unsigned long int leftarg = plural_eval (pexp->val.args[0], n);
58 	if (pexp->operation == lor)
59 	  return leftarg || plural_eval (pexp->val.args[1], n);
60 	else if (pexp->operation == land)
61 	  return leftarg && plural_eval (pexp->val.args[1], n);
62 	else
63 	  {
64 	    unsigned long int rightarg = plural_eval (pexp->val.args[1], n);
65 
66 	    switch (pexp->operation)
67 	      {
68 	      case mult:
69 		return leftarg * rightarg;
70 	      case divide:
71 #if !INTDIV0_RAISES_SIGFPE
72 		if (rightarg == 0)
73 		  raise (SIGFPE);
74 #endif
75 		return leftarg / rightarg;
76 	      case module:
77 #if !INTDIV0_RAISES_SIGFPE
78 		if (rightarg == 0)
79 		  raise (SIGFPE);
80 #endif
81 		return leftarg % rightarg;
82 	      case plus:
83 		return leftarg + rightarg;
84 	      case minus:
85 		return leftarg - rightarg;
86 	      case less_than:
87 		return leftarg < rightarg;
88 	      case greater_than:
89 		return leftarg > rightarg;
90 	      case less_or_equal:
91 		return leftarg <= rightarg;
92 	      case greater_or_equal:
93 		return leftarg >= rightarg;
94 	      case equal:
95 		return leftarg == rightarg;
96 	      case not_equal:
97 		return leftarg != rightarg;
98 	      default:
99 		break;
100 	      }
101 	  }
102 	/* NOTREACHED */
103 	break;
104       }
105     case 3:
106       {
107 	/* pexp->operation must be qmop.  */
108 	unsigned long int boolarg = plural_eval (pexp->val.args[0], n);
109 	return plural_eval (pexp->val.args[boolarg ? 1 : 2], n);
110       }
111     }
112   /* NOTREACHED */
113   return 0;
114 }
115