Home | History | Annotate | Download | only in intl
      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