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