18d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S/* Plural expression evaluation.
28d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S   Copyright (C) 2000-2003 Free Software Foundation, Inc.
38d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S
48d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S   This program is free software; you can redistribute it and/or modify it
58d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S   under the terms of the GNU Library General Public License as published
68d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S   by the Free Software Foundation; either version 2, or (at your option)
78d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S   any later version.
88d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S
98d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S   This program is distributed in the hope that it will be useful,
108d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S   but WITHOUT ANY WARRANTY; without even the implied warranty of
118d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
128d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S   Library General Public License for more details.
138d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S
148d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S   You should have received a copy of the GNU Library General Public
158d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S   License along with this program; if not, write to the Free Software
168d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
178d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S   USA.  */
188d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S
198d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S#ifndef STATIC
208d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S#define STATIC static
218d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S#endif
228d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S
238d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S/* Evaluate the plural expression and return an index value.  */
248d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha SSTATIC
258d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha Sunsigned long int
268d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha Sinternal_function
278d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha Splural_eval (struct expression *pexp, unsigned long int n)
288d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S{
298d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S  switch (pexp->nargs)
308d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S    {
318d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S    case 0:
328d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S      switch (pexp->operation)
338d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S	{
348d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S	case var:
358d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S	  return n;
368d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S	case num:
378d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S	  return pexp->val.num;
388d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S	default:
398d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S	  break;
408d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S	}
418d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S      /* NOTREACHED */
428d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S      break;
438d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S    case 1:
448d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S      {
458d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S	/* pexp->operation must be lnot.  */
468d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S	unsigned long int arg = plural_eval (pexp->val.args[0], n);
478d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S	return ! arg;
488d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S      }
498d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S    case 2:
508d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S      {
518d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S	unsigned long int leftarg = plural_eval (pexp->val.args[0], n);
528d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S	if (pexp->operation == lor)
538d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S	  return leftarg || plural_eval (pexp->val.args[1], n);
548d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S	else if (pexp->operation == land)
558d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S	  return leftarg && plural_eval (pexp->val.args[1], n);
568d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S	else
578d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S	  {
588d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S	    unsigned long int rightarg = plural_eval (pexp->val.args[1], n);
598d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S
608d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S	    switch (pexp->operation)
618d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S	      {
628d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S	      case mult:
638d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S		return leftarg * rightarg;
648d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S	      case divide:
658d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S#if !INTDIV0_RAISES_SIGFPE
668d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S		if (rightarg == 0)
678d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S		  raise (SIGFPE);
688d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S#endif
698d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S		return leftarg / rightarg;
708d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S	      case module:
718d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S#if !INTDIV0_RAISES_SIGFPE
728d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S		if (rightarg == 0)
738d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S		  raise (SIGFPE);
748d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S#endif
758d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S		return leftarg % rightarg;
768d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S	      case plus:
778d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S		return leftarg + rightarg;
788d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S	      case minus:
798d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S		return leftarg - rightarg;
808d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S	      case less_than:
818d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S		return leftarg < rightarg;
828d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S	      case greater_than:
838d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S		return leftarg > rightarg;
848d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S	      case less_or_equal:
858d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S		return leftarg <= rightarg;
868d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S	      case greater_or_equal:
878d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S		return leftarg >= rightarg;
888d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S	      case equal:
898d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S		return leftarg == rightarg;
908d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S	      case not_equal:
918d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S		return leftarg != rightarg;
928d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S	      default:
938d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S		break;
948d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S	      }
958d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S	  }
968d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S	/* NOTREACHED */
978d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S	break;
988d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S      }
998d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S    case 3:
1008d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S      {
1018d3d303c7942ced6a987a52db8977d768dc3605fHamsalekha S	/* 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