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 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