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.26 by schorsch, Sun Jul 27 22:12:01 2003 UTC vs.
Revision 2.37 by greg, Mon Mar 4 18:16:18 2019 UTC

# Line 26 | Line 26 | static const char      RCSid[] = "$Id$";
26   #include  <math.h>
27   #include  <stdlib.h>
28  
29 + #include  "rtmisc.h"
30 + #include  "rtio.h"
31   #include  "rterror.h"
32   #include  "calcomp.h"
33  
# Line 45 | Line 47 | static double  ebotch(EPNODE *);
47   unsigned int  esupport =                /* what to support */
48                  E_VARIABLE | E_FUNCTION ;
49  
50 + int  eofc = 0;                          /* optional end-of-file character */
51   int  nextc;                             /* lookahead character */
52  
53 < double  (*eoper[])() = {                /* expression operations */
53 > double  (*eoper[])(EPNODE *) = {        /* expression operations */
54          ebotch,
55          evariable,
56          enumber,
# Line 82 | Line 85 | static int  linepos;                   /* position in buffer */
85  
86  
87   EPNODE *
88 < eparse(expr)                    /* parse an expression string */
89 < char  *expr;
88 > eparse(                 /* parse an expression string */
89 >    char  *expr
90 > )
91   {
92      EPNODE  *ep;
93  
# Line 97 | Line 101 | char  *expr;
101  
102  
103   double
104 < eval(expr)                      /* evaluate an expression string */
105 < char  *expr;
104 > eval(                   /* evaluate an expression string */
105 >    char  *expr
106 > )
107   {
108 <    register EPNODE  *ep;
108 >    EPNODE  *ep;
109      double  rval;
110  
111      ep = eparse(expr);
# Line 111 | Line 116 | char  *expr;
116  
117  
118   int
119 < epcmp(ep1, ep2)                 /* compare two expressions for equivalence */
120 < register EPNODE  *ep1, *ep2;
119 > epcmp(                  /* compare two expressions for equivalence */
120 >    EPNODE  *ep1,
121 >    EPNODE  *ep2
122 > )
123   {
124          double  d;
125  
# Line 138 | Line 145 | register EPNODE  *ep1, *ep2;
145          case ':':
146                  return(epcmp(ep1->v.kid->sibling, ep2->v.kid->sibling));
147  
148 <        case TICK:
148 >        case CLKT:
149          case SYM:                       /* should never get this one */
150                  return(0);
151  
# Line 159 | Line 166 | register EPNODE  *ep1, *ep2;
166  
167  
168   void
169 < epfree(epar)                    /* free a parse tree */
170 < register EPNODE  *epar;
169 > epfree(                 /* free a parse tree */
170 >    EPNODE       *epar
171 > )
172   {
173 <    register EPNODE  *ep;
173 >    EPNODE  *ep;
174  
175      switch (epar->type) {
176  
# Line 177 | Line 185 | register EPNODE         *epar;
185          case NUM:
186          case CHAN:
187          case ARG:
188 <        case TICK:
188 >        case CLKT:
189              break;
190  
191          default:
# Line 194 | Line 202 | register EPNODE         *epar;
202  
203                                  /* the following used to be a switch */
204   static double
205 < eargument(ep)
206 < EPNODE  *ep;
205 > eargument(
206 >    EPNODE      *ep
207 > )
208   {
209      return(argument(ep->v.chan));
210   }
211  
212   static double
213 < enumber(ep)
214 < EPNODE  *ep;
213 > enumber(
214 >    EPNODE      *ep
215 > )
216   {
217      return(ep->v.num);
218   }
219  
220   static double
221 < euminus(ep)
222 < EPNODE  *ep;
221 > euminus(
222 >    EPNODE      *ep
223 > )
224   {
225 <    register EPNODE  *ep1 = ep->v.kid;
225 >    EPNODE  *ep1 = ep->v.kid;
226  
227      return(-evalue(ep1));
228   }
229  
230   static double
231 < echannel(ep)
232 < EPNODE  *ep;
231 > echannel(
232 >    EPNODE      *ep
233 > )
234   {
235      return(chanvalue(ep->v.chan));
236   }
237  
238   static double
239 < eadd(ep)
240 < EPNODE  *ep;
239 > eadd(
240 >    EPNODE      *ep
241 > )
242   {
243 <    register EPNODE  *ep1 = ep->v.kid;
243 >    EPNODE  *ep1 = ep->v.kid;
244  
245      return(evalue(ep1) + evalue(ep1->sibling));
246   }
247  
248   static double
249 < esubtr(ep)
250 < EPNODE  *ep;
249 > esubtr(
250 >    EPNODE      *ep
251 > )
252   {
253 <    register EPNODE  *ep1 = ep->v.kid;
253 >    EPNODE  *ep1 = ep->v.kid;
254  
255      return(evalue(ep1) - evalue(ep1->sibling));
256   }
257  
258   static double
259 < emult(ep)
260 < EPNODE  *ep;
259 > emult(
260 >    EPNODE      *ep
261 > )
262   {
263 <    register EPNODE  *ep1 = ep->v.kid;
263 >    EPNODE  *ep1 = ep->v.kid;
264  
265      return(evalue(ep1) * evalue(ep1->sibling));
266   }
267  
268   static double
269 < edivi(ep)
270 < EPNODE  *ep;
269 > edivi(
270 >    EPNODE      *ep
271 > )
272   {
273 <    register EPNODE  *ep1 = ep->v.kid;
273 >    EPNODE  *ep1 = ep->v.kid;
274      double  d;
275  
276      d = evalue(ep1->sibling);
# Line 267 | Line 283 | EPNODE *ep;
283   }
284  
285   static double
286 < epow(ep)
287 < EPNODE  *ep;
286 > epow(
287 >    EPNODE      *ep
288 > )
289   {
290 <    register EPNODE  *ep1 = ep->v.kid;
290 >    EPNODE  *ep1 = ep->v.kid;
291      double  d;
292      int  lasterrno;
293  
294      lasterrno = errno;
295      errno = 0;
296      d = pow(evalue(ep1), evalue(ep1->sibling));
297 < #ifdef  IEEE
298 <    if (!finite(d))
299 <        errno = EDOM;
297 > #ifdef  isnan
298 >    if (errno == 0) {
299 >        if (isnan(d))
300 >            errno = EDOM;
301 >        else if (isinf(d))
302 >            errno = ERANGE;
303 >    }
304   #endif
305      if (errno == EDOM || errno == ERANGE) {
306          wputs("Illegal power\n");
# Line 290 | Line 311 | EPNODE *ep;
311   }
312  
313   static double
314 < ebotch(ep)
315 < EPNODE  *ep;
314 > ebotch(
315 >    EPNODE      *ep
316 > )
317   {
318      eputs("Bad expression!\n");
319      quit(1);
# Line 300 | Line 322 | EPNODE *ep;
322  
323  
324   EPNODE *
325 < ekid(ep, n)                     /* return pointer to a node's nth kid */
326 < register EPNODE  *ep;
327 < register int  n;
325 > ekid(                   /* return pointer to a node's nth kid */
326 >    EPNODE       *ep,
327 >    int  n
328 > )
329   {
330  
331      for (ep = ep->v.kid; ep != NULL; ep = ep->sibling)
# Line 314 | Line 337 | register int  n;
337  
338  
339   int
340 < nekids(ep)                      /* return # of kids for node ep */
341 < register EPNODE  *ep;
340 > nekids(                 /* return # of kids for node ep */
341 >    EPNODE       *ep
342 > )
343   {
344 <    register int  n = 0;
344 >    int  n = 0;
345  
346      for (ep = ep->v.kid; ep != NULL; ep = ep->sibling)
347          n++;
# Line 327 | Line 351 | register EPNODE         *ep;
351  
352  
353   void
354 < initfile(fp, fn, ln)            /* prepare input file */
355 < FILE  *fp;
356 < char  *fn;
357 < int  ln;
354 > initfile(               /* prepare input file */
355 >    FILE  *fp,
356 >    char  *fn,
357 >    int  ln
358 > )
359   {
360      static char  inpbuf[MAXLINE];
361  
# Line 345 | Line 370 | int  ln;
370  
371  
372   void
373 < initstr(s, fn, ln)              /* prepare input string */
374 < char  *s;
375 < char  *fn;
376 < int  ln;
373 > initstr(                /* prepare input string */
374 >    char  *s,
375 >    char  *fn,
376 >    int  ln
377 > )
378   {
379      infp = NULL;
380      infile = fn;
# Line 360 | Line 386 | int  ln;
386  
387  
388   void
389 < getscanpos(fnp, lnp, spp, fpp)  /* return current scan position */
390 < char  **fnp;
391 < int  *lnp;
392 < char  **spp;
393 < FILE  **fpp;
389 > getscanpos(     /* return current scan position */
390 >    char  **fnp,
391 >    int  *lnp,
392 >    char  **spp,
393 >    FILE  **fpp
394 > )
395   {
396      if (fnp != NULL) *fnp = infile;
397      if (lnp != NULL) *lnp = lineno;
# Line 374 | Line 401 | FILE  **fpp;
401  
402  
403   int
404 < scan()                          /* scan next character, return literal next */
404 > scan(void)              /* scan next character, return literal next */
405   {
406 <    register int  lnext = 0;
406 >    int  lnext = 0;
407  
408      do {
409          if (linbuf[linepos] == '\0')
# Line 391 | Line 418 | scan()                         /* scan next character, return literal next
418              nextc = linbuf[linepos++];
419          if (!lnext)
420                  lnext = nextc;
421 +        if (nextc == eofc) {
422 +                nextc = EOF;
423 +                break;
424 +        }
425          if (nextc == '{') {
426              scan();
427              while (nextc != '}')
# Line 406 | Line 437 | scan()                         /* scan next character, return literal next
437  
438  
439   char *
440 < long2ascii(l)                         /* convert long to ascii */
441 < long  l;
440 > long2ascii(                           /* convert long to ascii */
441 >    long  l
442 > )
443   {
444      static char  buf[16];
445 <    register char  *cp;
445 >    char  *cp;
446      int  neg = 0;
447  
448      if (l == 0)
# Line 432 | Line 464 | long  l;
464  
465  
466   void
467 < syntax(err)                     /* report syntax error and quit */
468 < char  *err;
467 > syntax(                 /* report syntax error and quit */
468 >    char  *err
469 > )
470   {
471 <    register int  i;
471 >    int  i;
472  
473      if (infile != NULL || lineno != 0) {
474          if (infile != NULL) eputs(infile);
# Line 458 | Line 491 | char  *err;
491  
492  
493   void
494 < addekid(ep, ekid)                       /* add a child to ep */
495 < register EPNODE  *ep;
496 < EPNODE  *ekid;
494 > addekid(                        /* add a child to ep */
495 >    EPNODE       *ep,
496 >    EPNODE      *ekid
497 > )
498   {
499      if (ep->v.kid == NULL)
500          ep->v.kid = ekid;
# Line 474 | Line 508 | EPNODE *ekid;
508  
509  
510   char *
511 < getname()                       /* scan an identifier */
511 > getname(void)                   /* scan an identifier */
512   {
513      static char  str[RMAXWORD+1];
514 <    register int  i, lnext;
514 >    int  i, lnext;
515  
516      lnext = nextc;
517      for (i = 0; i < RMAXWORD && isid(lnext); i++, lnext = scan())
# Line 491 | Line 525 | getname()                      /* scan an identifier */
525  
526  
527   int
528 < getinum()                       /* scan a positive integer */
528 > getinum(void)                   /* scan a positive integer */
529   {
530 <    register int  n, lnext;
530 >    int  n, lnext;
531  
532      n = 0;
533      lnext = nextc;
# Line 506 | Line 540 | getinum()                      /* scan a positive integer */
540  
541  
542   double
543 < getnum()                        /* scan a positive float */
543 > getnum(void)                    /* scan a positive float */
544   {
545 <    register int  i, lnext;
545 >    int  i, lnext;
546      char  str[RMAXWORD+1];
547  
548      i = 0;
# Line 548 | Line 582 | getnum()                       /* scan a positive float */
582  
583  
584   EPNODE *
585 < getE1()                         /* E1 -> E1 ADDOP E2 */
585 > getE1(void)                     /* E1 -> E1 ADDOP E2 */
586                                  /*       E2 */
587   {
588 <    register EPNODE  *ep1, *ep2;
588 >    EPNODE  *ep1, *ep2;
589  
590      ep1 = getE2();
591      while (nextc == '+' || nextc == '-') {
# Line 570 | Line 604 | getE1()                                /* E1 -> E1 ADDOP E2 */
604  
605  
606   EPNODE *
607 < getE2()                         /* E2 -> E2 MULOP E3 */
607 > getE2(void)                     /* E2 -> E2 MULOP E3 */
608                                  /*       E3 */
609   {
610 <    register EPNODE  *ep1, *ep2;
610 >    EPNODE  *ep1, *ep2;
611  
612      ep1 = getE3();
613      while (nextc == '*' || nextc == '/') {
# Line 582 | Line 616 | getE2()                                /* E2 -> E2 MULOP E3 */
616          scan();
617          addekid(ep2, ep1);
618          addekid(ep2, getE3());
619 <        if (esupport&E_RCONST &&
620 <                        ep1->type == NUM && ep1->sibling->type == NUM)
621 <                ep2 = rconst(ep2);
619 >        if (esupport&E_RCONST) {
620 >                EPNODE  *ep3 = ep1->sibling;
621 >                if (ep1->type == NUM && ep3->type == NUM) {
622 >                        ep2 = rconst(ep2);
623 >                } else if (ep3->type == NUM) {
624 >                        if (ep2->type == '/') {
625 >                                if (ep3->v.num == 0)
626 >                                        syntax("divide by zero constant");
627 >                                ep2->type = '*';        /* for speed */
628 >                                ep3->v.num = 1./ep3->v.num;
629 >                        } else if (ep3->v.num == 0) {
630 >                                ep1->sibling = NULL;    /* (E2 * 0) */
631 >                                epfree(ep2);
632 >                                ep2 = ep3;
633 >                        }
634 >                } else if (ep1->type == NUM && ep1->v.num == 0) {
635 >                        epfree(ep3);            /* (0 * E3) or (0 / E3) */
636 >                        ep1->sibling = NULL;
637 >                        efree((char *)ep2);
638 >                        ep2 = ep1;
639 >                }
640 >        }
641          ep1 = ep2;
642      }
643      return(ep1);
# Line 592 | Line 645 | getE2()                                /* E2 -> E2 MULOP E3 */
645  
646  
647   EPNODE *
648 < getE3()                         /* E3 -> E4 ^ E3 */
648 > getE3(void)                     /* E3 -> E4 ^ E3 */
649                                  /*       E4 */
650   {
651 <    register EPNODE  *ep1, *ep2;
651 >        EPNODE  *ep1, *ep2;
652  
653 <    ep1 = getE4();
654 <    if (nextc == '^') {
653 >        ep1 = getE4();
654 >        if (nextc != '^')
655 >                return(ep1);
656          ep2 = newnode();
657          ep2->type = nextc;
658          scan();
659          addekid(ep2, ep1);
660          addekid(ep2, getE3());
661 <        if (esupport&E_RCONST &&
662 <                        ep1->type == NUM && ep1->sibling->type == NUM)
663 <                ep2 = rconst(ep2);
661 >        if (esupport&E_RCONST) {
662 >                EPNODE  *ep3 = ep1->sibling;
663 >                if (ep1->type == NUM && ep3->type == NUM) {
664 >                        ep2 = rconst(ep2);
665 >                } else if (ep1->type == NUM && ep1->v.num == 0) {
666 >                        epfree(ep3);            /* (0 ^ E3) */
667 >                        ep1->sibling = NULL;
668 >                        efree((char *)ep2);
669 >                        ep2 = ep1;
670 >                } else if ((ep3->type == NUM && ep3->v.num == 0) ||
671 >                                (ep1->type == NUM && ep1->v.num == 1)) {
672 >                        epfree(ep2);            /* (E4 ^ 0) or (1 ^ E3) */
673 >                        ep2 = newnode();
674 >                        ep2->type = NUM;
675 >                        ep2->v.num = 1;
676 >                }
677 >        }
678          return(ep2);
611    }
612    return(ep1);
679   }
680  
681  
682   EPNODE *
683 < getE4()                         /* E4 -> ADDOP E5 */
683 > getE4(void)                     /* E4 -> ADDOP E5 */
684                                  /*       E5 */
685   {
686 <    register EPNODE  *ep1, *ep2;
686 >    EPNODE  *ep1, *ep2;
687  
688      if (nextc == '-') {
689          scan();
# Line 627 | Line 693 | getE4()                                /* E4 -> ADDOP E5 */
693                  return(ep2);
694          }
695          if (ep2->type == UMINUS) {      /* don't generate -(-E5) */
696 +            ep1 = ep2->v.kid;
697              efree((char *)ep2);
698 <            return(ep2->v.kid);
698 >            return(ep1);
699          }
700          ep1 = newnode();
701          ep1->type = UMINUS;
# Line 642 | Line 709 | getE4()                                /* E4 -> ADDOP E5 */
709  
710  
711   EPNODE *
712 < getE5()                         /* E5 -> (E1) */
712 > getE5(void)                     /* E5 -> (E1) */
713                                  /*       VAR */
714                                  /*       NUM */
715                                  /*       $N */
# Line 651 | Line 718 | getE5()                                /* E5 -> (E1) */
718   {
719          int      i;
720          char  *nam;
721 <        register EPNODE  *ep1, *ep2;
721 >        EPNODE  *ep1, *ep2;
722  
723          if (nextc == '(') {
724                  scan();
# Line 720 | Line 787 | getE5()                                /* E5 -> (E1) */
787  
788  
789   EPNODE *
790 < rconst(epar)                    /* reduce a constant expression */
791 < register EPNODE  *epar;
790 > rconst(                 /* reduce a constant expression */
791 >    EPNODE       *epar
792 > )
793   {
794 <    register EPNODE  *ep;
794 >    EPNODE  *ep;
795  
796      ep = newnode();
797      ep->type = NUM;
# Line 738 | Line 806 | register EPNODE         *epar;
806  
807  
808   int
809 < isconstvar(ep)                  /* is ep linked to a constant expression? */
810 < register EPNODE  *ep;
809 > isconstvar(                     /* is ep linked to a constant expression? */
810 >    EPNODE       *ep
811 > )
812   {
813 <    register EPNODE  *ep1;
813 >    EPNODE  *ep1;
814  
815      if (esupport&E_FUNCTION && ep->type == FUNC) {
816          if (!isconstfun(ep->v.kid))
# Line 763 | Line 832 | register EPNODE         *ep;
832  
833  
834   int
835 < isconstfun(ep)                  /* is ep linked to a constant function? */
836 < register EPNODE  *ep;
835 > isconstfun(                     /* is ep linked to a constant function? */
836 >    EPNODE       *ep
837 > )
838   {
839 <    register EPNODE  *dp;
840 <    register LIBR  *lp;
839 >    EPNODE  *dp;
840 >    LIBR  *lp;
841  
842      if (ep->type != VAR)
843          return(0);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines