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