ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/calexpr.c
(Generate patch)

Comparing ray/src/common/calexpr.c (file contents):
Revision 2.17 by gwlarson, Mon Aug 17 17:57:30 1998 UTC vs.
Revision 2.20 by greg, Wed Mar 5 16:16:52 2003 UTC

# Line 1 | Line 1
1 /* Copyright (c) 1998 Silicon Graphics, Inc. */
2
1   #ifndef lint
2 < static char SCCSid[] = "$SunId$ SGI";
2 > static const char       RCSid[] = "$Id$";
3   #endif
6
4   /*
5   *  Compute data values using expression parser
6   *
# Line 16 | Line 13 | static char SCCSid[] = "$SunId$ SGI";
13   *  1/29/87  Made variables conditional (VARIABLE)
14   *
15   *  5/19/88  Added constant subexpression elimination (RCONST)
16 + *
17 + *  2/19/03     Eliminated conditional compiles in favor of esupport extern.
18   */
19  
20 + #include "copyright.h"
21 +
22   #include  <stdio.h>
23  
24   #include  <ctype.h>
# Line 26 | Line 27 | static char SCCSid[] = "$SunId$ SGI";
27  
28   #include  <math.h>
29  
30 + #include  <stdlib.h>
31 +
32   #include  "calcomp.h"
33  
34   #define  MAXLINE        256             /* maximum line length */
# Line 34 | Line 37 | static char SCCSid[] = "$SunId$ SGI";
37  
38   #define  isdecimal(c)   (isdigit(c) || (c) == '.')
39  
37 extern char  *savestr();
38 extern char  *emalloc(), *ecalloc();
39 extern EPNODE  *curfunc;
40 extern double  efunc(), evariable();
40   static double  euminus(), eargument(), enumber();
42 #ifdef  INCHAN
41   static double  echannel();
44 #endif
42   static double  eadd(), esubtr(), emult(), edivi(), epow();
43   static double  ebotch();
44  
45 < #ifdef  DCL_ATOF
46 < extern double  atof();
50 < #endif
45 > unsigned int  esupport =                /* what to support */
46 >                E_VARIABLE | E_FUNCTION | E_REDEFW;
47  
48   int  nextc;                             /* lookahead character */
49  
50   double  (*eoper[])() = {                /* expression operations */
51          ebotch,
56 #ifdef  VARIABLE
52          evariable,
58 #else
59        ebotch,
60 #endif
53          enumber,
54          euminus,
63 #ifdef  INCHAN
55          echannel,
65 #else
66        ebotch,
67 #endif
68 #ifdef  FUNCTION
56          efunc,
57          eargument,
71 #else
58          ebotch,
59          ebotch,
74 #endif
75        ebotch,
76        ebotch,
60          0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
61          0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
62          emult,
# Line 105 | Line 88 | char  *expr;
88      EPNODE  *ep;
89  
90      initstr(expr, NULL, 0);
108 #if  defined(VARIABLE) && defined(FUNCTION)
91      curfunc = NULL;
110 #endif
92      ep = getE1();
93      if (nextc != EOF)
94          syntax("unexpected character");
# Line 129 | Line 110 | char  *expr;
110   }
111  
112  
113 + int
114   epcmp(ep1, ep2)                 /* compare two expressions for equivalence */
115   register EPNODE  *ep1, *ep2;
116   {
# Line 176 | Line 158 | register EPNODE  *ep1, *ep2;
158   }
159  
160  
161 + void
162   epfree(epar)                    /* free a parse tree */
163   register EPNODE  *epar;
164   {
# Line 183 | Line 166 | register EPNODE         *epar;
166  
167      switch (epar->type) {
168  
186 #if  defined(VARIABLE) || defined(FUNCTION)
169          case VAR:
170              varfree(epar->v.ln);
171              break;
# Line 191 | Line 173 | register EPNODE         *epar;
173          case SYM:
174              freestr(epar->v.name);
175              break;
194 #endif
176  
177          case NUM:
178          case CHAN:
# Line 212 | Line 193 | register EPNODE         *epar;
193   }
194  
195                                  /* the following used to be a switch */
215 #ifdef  FUNCTION
196   static double
197   eargument(ep)
198   EPNODE  *ep;
199   {
200      return(argument(ep->v.chan));
201   }
222 #endif
202  
203   static double
204   enumber(ep)
# Line 237 | Line 216 | EPNODE *ep;
216      return(-evalue(ep1));
217   }
218  
240 #ifdef  INCHAN
219   static double
220   echannel(ep)
221   EPNODE  *ep;
222   {
223      return(chanvalue(ep->v.chan));
224   }
247 #endif
225  
226   static double
227   eadd(ep)
# Line 304 | Line 281 | EPNODE *ep;
281      if (!finite(d))
282          errno = EDOM;
283   #endif
284 <    if (errno) {
284 >    if (errno == EDOM || errno == ERANGE) {
285          wputs("Illegal power\n");
286          return(0.0);
287      }
# Line 348 | Line 325 | register EPNODE         *ep;
325   }
326  
327  
328 + void
329   initfile(fp, fn, ln)            /* prepare input file */
330   FILE  *fp;
331   char  *fn;
# Line 365 | Line 343 | int  ln;
343   }
344  
345  
346 + void
347   initstr(s, fn, ln)              /* prepare input string */
348   char  *s;
349   char  *fn;
# Line 379 | Line 358 | int  ln;
358   }
359  
360  
361 + void
362   getscanpos(fnp, lnp, spp, fpp)  /* return current scan position */
363   char  **fnp;
364   int  *lnp;
# Line 450 | Line 430 | long  l;
430   }
431  
432  
433 + void
434   syntax(err)                     /* report syntax error and quit */
435   char  *err;
436   {
# Line 475 | Line 456 | char  *err;
456   }
457  
458  
459 + void
460   addekid(ep, ekid)                       /* add a child to ep */
461   register EPNODE  *ep;
462   EPNODE  *ekid;
# Line 490 | Line 472 | EPNODE *ekid;
472   }
473  
474  
493 #if  defined(VARIABLE) || defined(FUNCTION)
475   char *
476   getname()                       /* scan an identifier */
477   {
# Line 506 | Line 487 | getname()                      /* scan an identifier */
487  
488      return(str);
489   }
509 #endif
490  
491  
492   int
# Line 579 | Line 559 | getE1()                                /* E1 -> E1 ADDOP E2 */
559          scan();
560          addekid(ep2, ep1);
561          addekid(ep2, getE2());
562 < #ifdef  RCONST
563 <        if (ep1->type == NUM && ep1->sibling->type == NUM)
562 >        if (esupport&E_RCONST &&
563 >                        ep1->type == NUM && ep1->sibling->type == NUM)
564                  ep2 = rconst(ep2);
585 #endif
565          ep1 = ep2;
566      }
567      return(ep1);
# Line 602 | Line 581 | getE2()                                /* E2 -> E2 MULOP E3 */
581          scan();
582          addekid(ep2, ep1);
583          addekid(ep2, getE3());
584 < #ifdef  RCONST
585 <        if (ep1->type == NUM && ep1->sibling->type == NUM)
584 >        if (esupport&E_RCONST &&
585 >                        ep1->type == NUM && ep1->sibling->type == NUM)
586                  ep2 = rconst(ep2);
608 #endif
587          ep1 = ep2;
588      }
589      return(ep1);
# Line 625 | Line 603 | getE3()                                /* E3 -> E4 ^ E3 */
603          scan();
604          addekid(ep2, ep1);
605          addekid(ep2, getE3());
606 < #ifdef  RCONST
607 <        if (ep1->type == NUM && ep1->sibling->type == NUM)
606 >        if (esupport&E_RCONST &&
607 >                        ep1->type == NUM && ep1->sibling->type == NUM)
608                  ep2 = rconst(ep2);
631 #endif
609          return(ep2);
610      }
611      return(ep1);
# Line 684 | Line 661 | getE5()                                /* E5 -> (E1) */
661          return(ep1);
662      }
663  
664 < #ifdef  INCHAN
688 <    if (nextc == '$') {
664 >    if (esupport&E_INCHAN && nextc == '$') {
665          scan();
666          ep1 = newnode();
667          ep1->type = CHAN;
668          ep1->v.chan = getinum();
669          return(ep1);
670      }
695 #endif
671  
672 < #if  defined(VARIABLE) || defined(FUNCTION)
673 <    if (isalpha(nextc) || nextc == CNTXMARK) {
674 <        nam = getname();
675 < #if  defined(VARIABLE) && defined(FUNCTION)
676 <        ep1 = NULL;
677 <        if (curfunc != NULL)
672 >  if (esupport&(E_VARIABLE|E_FUNCTION) &&
673 >                (isalpha(nextc) || nextc == CNTXMARK)) {
674 >      nam = getname();
675 >      ep1 = NULL;
676 >      if ((esupport&(E_VARIABLE|E_FUNCTION)) == (E_VARIABLE|E_FUNCTION)
677 >                        && curfunc != NULL)
678              for (i = 1, ep2 = curfunc->v.kid->sibling;
679                                  ep2 != NULL; i++, ep2 = ep2->sibling)
680                  if (!strcmp(ep2->v.name, nam)) {
# Line 708 | Line 683 | getE5()                                /* E5 -> (E1) */
683                      ep1->v.chan = i;
684                      break;
685                  }
686 <        if (ep1 == NULL)
712 < #endif
713 <        {
686 >        if (ep1 == NULL) {
687              ep1 = newnode();
688              ep1->type = VAR;
689              ep1->v.ln = varinsert(nam);
690          }
691 < #ifdef  FUNCTION
719 <        if (nextc == '(') {
691 >        if (esupport&E_FUNCTION && nextc == '(') {
692              ep2 = newnode();
693              ep2->type = FUNC;
694              addekid(ep2, ep1);
# Line 728 | Line 700 | getE5()                                /* E5 -> (E1) */
700              if (nextc != ')')
701                  syntax("')' expected");
702              scan();
703 <        }
732 < #ifndef  VARIABLE
733 <        else
703 >        } else if (!(esupport&E_VARIABLE))
704              syntax("'(' expected");
705 < #endif
736 < #endif
737 < #ifdef  RCONST
738 <        if (isconstvar(ep1))
705 >        if (esupport&E_RCONST && isconstvar(ep1))
706              ep1 = rconst(ep1);
740 #endif
707          return(ep1);
708      }
743 #endif
709  
710      if (isdecimal(nextc)) {
711          ep1 = newnode();
# Line 752 | Line 717 | getE5()                                /* E5 -> (E1) */
717   }
718  
719  
755 #ifdef  RCONST
720   EPNODE *
721   rconst(epar)                    /* reduce a constant expression */
722   register EPNODE  *epar;
# Line 763 | Line 727 | register EPNODE         *epar;
727      ep->type = NUM;
728      errno = 0;
729      ep->v.num = evalue(epar);
730 <    if (errno)
730 >    if (errno == EDOM || errno == ERANGE)
731          syntax("bad constant expression");
732      epfree(epar);
733  
# Line 771 | Line 735 | register EPNODE         *epar;
735   }
736  
737  
738 + int
739   isconstvar(ep)                  /* is ep linked to a constant expression? */
740   register EPNODE  *ep;
741   {
777 #ifdef  VARIABLE
742      register EPNODE  *ep1;
779 #ifdef  FUNCTION
743  
744 <    if (ep->type == FUNC) {
744 >    if (esupport&E_FUNCTION && ep->type == FUNC) {
745          if (!isconstfun(ep->v.kid))
746                  return(0);
747          for (ep1 = ep->v.kid->sibling; ep1 != NULL; ep1 = ep1->sibling)
# Line 786 | Line 749 | register EPNODE         *ep;
749                  return(0);
750          return(1);
751      }
789 #endif
752      if (ep->type != VAR)
753          return(0);
754      ep1 = ep->v.ln->def;
755      if (ep1 == NULL || ep1->type != ':')
756          return(0);
757 < #ifdef  FUNCTION
796 <    if (ep1->v.kid->type != SYM)
757 >    if (esupport&E_FUNCTION && ep1->v.kid->type != SYM)
758          return(0);
798 #endif
759      return(1);
800 #else
801    return(ep->type == FUNC);
802 #endif
760   }
761  
762  
763 < #if  defined(FUNCTION) && defined(VARIABLE)
763 > int
764   isconstfun(ep)                  /* is ep linked to a constant function? */
765   register EPNODE  *ep;
766   {
# Line 812 | Line 769 | register EPNODE         *ep;
769  
770      if (ep->type != VAR)
771          return(0);
772 <    if ((dp = ep->v.ln->def) != NULL && dp->v.kid->type == FUNC)
773 <        return(dp->type == ':');
772 >    if ((dp = ep->v.ln->def) != NULL)
773 >        if (dp->v.kid->type == FUNC)
774 >            return(dp->type == ':');
775 >        else
776 >            return(0);          /* don't identify masked library functions */
777      if ((lp = ep->v.ln->lib) != NULL)
778          return(lp->atyp == ':');
779      return(0);
780   }
821 #endif
822 #endif

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines