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.24 by schorsch, Thu Jul 17 09:21:29 2003 UTC vs.
Revision 2.34 by greg, Sun Jul 25 05:50:27 2010 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;
109      double  rval;
# 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 >    register EPNODE  *ep1,
121 >    register EPNODE  *ep2
122 > )
123   {
124          double  d;
125  
# Line 128 | Line 135 | register EPNODE  *ep1, *ep2;
135                  if (ep2->v.num == 0)
136                          return(ep1->v.num != 0);
137                  d = ep1->v.num / ep2->v.num;
138 <                return(d > 1.000000000001 | d < 0.999999999999);
138 >                return((d > 1.000000000001) | (d < 0.999999999999));
139  
140          case CHAN:
141          case ARG:
# 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 >    register EPNODE      *epar
171 > )
172   {
173      register EPNODE  *ep;
174  
# 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;
226  
# Line 217 | Line 228 | EPNODE *ep;
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;
244  
# Line 233 | Line 246 | EPNODE *ep;
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;
254  
# Line 242 | Line 256 | EPNODE *ep;
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;
264  
# Line 251 | Line 266 | EPNODE *ep;
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;
274      double  d;
# 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;
291      double  d;
# Line 277 | Line 294 | EPNODE *ep;
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   #endif
304      if (errno == EDOM || errno == ERANGE) {
305          wputs("Illegal power\n");
# Line 290 | Line 310 | EPNODE *ep;
310   }
311  
312   static double
313 < ebotch(ep)
314 < EPNODE  *ep;
313 > ebotch(
314 >    EPNODE      *ep
315 > )
316   {
317      eputs("Bad expression!\n");
318      quit(1);
# Line 300 | Line 321 | EPNODE *ep;
321  
322  
323   EPNODE *
324 < ekid(ep, n)                     /* return pointer to a node's nth kid */
325 < register EPNODE  *ep;
326 < register int  n;
324 > ekid(                   /* return pointer to a node's nth kid */
325 >    register EPNODE      *ep,
326 >    register int  n
327 > )
328   {
329  
330      for (ep = ep->v.kid; ep != NULL; ep = ep->sibling)
# Line 314 | Line 336 | register int  n;
336  
337  
338   int
339 < nekids(ep)                      /* return # of kids for node ep */
340 < register EPNODE  *ep;
339 > nekids(                 /* return # of kids for node ep */
340 >    register EPNODE      *ep
341 > )
342   {
343      register int  n = 0;
344  
# Line 327 | Line 350 | register EPNODE         *ep;
350  
351  
352   void
353 < initfile(fp, fn, ln)            /* prepare input file */
354 < FILE  *fp;
355 < char  *fn;
356 < int  ln;
353 > initfile(               /* prepare input file */
354 >    FILE  *fp,
355 >    char  *fn,
356 >    int  ln
357 > )
358   {
359      static char  inpbuf[MAXLINE];
360  
# Line 345 | Line 369 | int  ln;
369  
370  
371   void
372 < initstr(s, fn, ln)              /* prepare input string */
373 < char  *s;
374 < char  *fn;
375 < int  ln;
372 > initstr(                /* prepare input string */
373 >    char  *s,
374 >    char  *fn,
375 >    int  ln
376 > )
377   {
378      infp = NULL;
379      infile = fn;
# Line 360 | Line 385 | int  ln;
385  
386  
387   void
388 < getscanpos(fnp, lnp, spp, fpp)  /* return current scan position */
389 < char  **fnp;
390 < int  *lnp;
391 < char  **spp;
392 < FILE  **fpp;
388 > getscanpos(     /* return current scan position */
389 >    char  **fnp,
390 >    int  *lnp,
391 >    char  **spp,
392 >    FILE  **fpp
393 > )
394   {
395      if (fnp != NULL) *fnp = infile;
396      if (lnp != NULL) *lnp = lineno;
# Line 374 | Line 400 | FILE  **fpp;
400  
401  
402   int
403 < scan()                          /* scan next character, return literal next */
403 > scan(void)              /* scan next character, return literal next */
404   {
405      register int  lnext = 0;
406  
# Line 391 | Line 417 | scan()                         /* scan next character, return literal next
417              nextc = linbuf[linepos++];
418          if (!lnext)
419                  lnext = nextc;
420 +        if (nextc == eofc) {
421 +                nextc = EOF;
422 +                break;
423 +        }
424          if (nextc == '{') {
425              scan();
426              while (nextc != '}')
# Line 406 | Line 436 | scan()                         /* scan next character, return literal next
436  
437  
438   char *
439 < long2ascii(l)                         /* convert long to ascii */
440 < long  l;
439 > long2ascii(                           /* convert long to ascii */
440 >    long  l
441 > )
442   {
443      static char  buf[16];
444      register char  *cp;
# Line 432 | Line 463 | long  l;
463  
464  
465   void
466 < syntax(err)                     /* report syntax error and quit */
467 < char  *err;
466 > syntax(                 /* report syntax error and quit */
467 >    char  *err
468 > )
469   {
470      register int  i;
471  
# Line 458 | Line 490 | char  *err;
490  
491  
492   void
493 < addekid(ep, ekid)                       /* add a child to ep */
494 < register EPNODE  *ep;
495 < EPNODE  *ekid;
493 > addekid(                        /* add a child to ep */
494 >    register EPNODE      *ep,
495 >    EPNODE      *ekid
496 > )
497   {
498      if (ep->v.kid == NULL)
499          ep->v.kid = ekid;
# Line 474 | Line 507 | EPNODE *ekid;
507  
508  
509   char *
510 < getname()                       /* scan an identifier */
510 > getname(void)                   /* scan an identifier */
511   {
512      static char  str[RMAXWORD+1];
513      register int  i, lnext;
# Line 491 | Line 524 | getname()                      /* scan an identifier */
524  
525  
526   int
527 < getinum()                       /* scan a positive integer */
527 > getinum(void)                   /* scan a positive integer */
528   {
529      register int  n, lnext;
530  
# Line 506 | Line 539 | getinum()                      /* scan a positive integer */
539  
540  
541   double
542 < getnum()                        /* scan a positive float */
542 > getnum(void)                    /* scan a positive float */
543   {
544      register int  i, lnext;
545      char  str[RMAXWORD+1];
# Line 527 | Line 560 | getnum()                       /* scan a positive float */
560              lnext = scan();
561          }
562      }
563 <    if ((lnext == 'e' | lnext == 'E') && i < RMAXWORD) {
563 >    if ((lnext == 'e') | (lnext == 'E') && i < RMAXWORD) {
564          str[i++] = lnext;
565          lnext = scan();
566 <        if ((lnext == '-' | lnext == '+') && i < RMAXWORD) {
566 >        if ((lnext == '-') | (lnext == '+') && i < RMAXWORD) {
567              str[i++] = lnext;
568              lnext = scan();
569          }
# Line 548 | Line 581 | getnum()                       /* scan a positive float */
581  
582  
583   EPNODE *
584 < getE1()                         /* E1 -> E1 ADDOP E2 */
584 > getE1(void)                     /* E1 -> E1 ADDOP E2 */
585                                  /*       E2 */
586   {
587      register EPNODE  *ep1, *ep2;
# Line 570 | Line 603 | getE1()                                /* E1 -> E1 ADDOP E2 */
603  
604  
605   EPNODE *
606 < getE2()                         /* E2 -> E2 MULOP E3 */
606 > getE2(void)                     /* E2 -> E2 MULOP E3 */
607                                  /*       E3 */
608   {
609      register EPNODE  *ep1, *ep2;
# Line 582 | Line 615 | getE2()                                /* E2 -> E2 MULOP E3 */
615          scan();
616          addekid(ep2, ep1);
617          addekid(ep2, getE3());
618 <        if (esupport&E_RCONST &&
619 <                        ep1->type == NUM && ep1->sibling->type == NUM)
620 <                ep2 = rconst(ep2);
618 >        if (esupport&E_RCONST) {
619 >                EPNODE  *ep3 = ep1->sibling;
620 >                if (ep1->type == NUM && ep3->type == NUM) {
621 >                        ep2 = rconst(ep2);
622 >                } else if (ep3->type == NUM && ep3->v.num == 0) {
623 >                        if (ep2->type == '/')
624 >                                syntax("divide by zero constant");
625 >                        ep1->sibling = NULL;    /* (E2 * 0) */
626 >                        epfree(ep2);
627 >                        ep2 = ep3;
628 >                } else if (ep1->type == NUM && ep1->v.num == 0) {
629 >                        epfree(ep3);            /* (0 * E3) or (0 / E3) */
630 >                        ep1->sibling = NULL;
631 >                        efree((char *)ep2);
632 >                        ep2 = ep1;
633 >                }
634 >        }
635          ep1 = ep2;
636      }
637      return(ep1);
# Line 592 | Line 639 | getE2()                                /* E2 -> E2 MULOP E3 */
639  
640  
641   EPNODE *
642 < getE3()                         /* E3 -> E4 ^ E3 */
642 > getE3(void)                     /* E3 -> E4 ^ E3 */
643                                  /*       E4 */
644   {
645 <    register EPNODE  *ep1, *ep2;
645 >        register EPNODE  *ep1, *ep2;
646  
647 <    ep1 = getE4();
648 <    if (nextc == '^') {
647 >        ep1 = getE4();
648 >        if (nextc != '^')
649 >                return(ep1);
650          ep2 = newnode();
651          ep2->type = nextc;
652          scan();
653          addekid(ep2, ep1);
654          addekid(ep2, getE3());
655 <        if (esupport&E_RCONST &&
656 <                        ep1->type == NUM && ep1->sibling->type == NUM)
657 <                ep2 = rconst(ep2);
655 >        if (esupport&E_RCONST) {
656 >                EPNODE  *ep3 = ep1->sibling;
657 >                if (ep1->type == NUM && ep3->type == NUM) {
658 >                        ep2 = rconst(ep2);
659 >                } else if (ep1->type == NUM && ep1->v.num == 0) {
660 >                        epfree(ep3);            /* (0 ^ E3) */
661 >                        ep1->sibling = NULL;
662 >                        efree((char *)ep2);
663 >                        ep2 = ep1;
664 >                } else if ((ep3->type == NUM && ep3->v.num == 0) ||
665 >                                (ep1->type == NUM && ep1->v.num == 1)) {
666 >                        epfree(ep2);            /* (E4 ^ 0) or (1 ^ E3) */
667 >                        ep2 = newnode();
668 >                        ep2->type = NUM;
669 >                        ep2->v.num = 1;
670 >                }
671 >        }
672          return(ep2);
611    }
612    return(ep1);
673   }
674  
675  
676   EPNODE *
677 < getE4()                         /* E4 -> ADDOP E5 */
677 > getE4(void)                     /* E4 -> ADDOP E5 */
678                                  /*       E5 */
679   {
680      register EPNODE  *ep1, *ep2;
# Line 627 | Line 687 | getE4()                                /* E4 -> ADDOP E5 */
687                  return(ep2);
688          }
689          if (ep2->type == UMINUS) {      /* don't generate -(-E5) */
690 +            ep1 = ep2->v.kid;
691              efree((char *)ep2);
692 <            return(ep2->v.kid);
692 >            return(ep1);
693          }
694          ep1 = newnode();
695          ep1->type = UMINUS;
# Line 642 | Line 703 | getE4()                                /* E4 -> ADDOP E5 */
703  
704  
705   EPNODE *
706 < getE5()                         /* E5 -> (E1) */
706 > getE5(void)                     /* E5 -> (E1) */
707                                  /*       VAR */
708                                  /*       NUM */
709                                  /*       $N */
# Line 720 | Line 781 | getE5()                                /* E5 -> (E1) */
781  
782  
783   EPNODE *
784 < rconst(epar)                    /* reduce a constant expression */
785 < register EPNODE  *epar;
784 > rconst(                 /* reduce a constant expression */
785 >    register EPNODE      *epar
786 > )
787   {
788      register EPNODE  *ep;
789  
# Line 738 | Line 800 | register EPNODE         *epar;
800  
801  
802   int
803 < isconstvar(ep)                  /* is ep linked to a constant expression? */
804 < register EPNODE  *ep;
803 > isconstvar(                     /* is ep linked to a constant expression? */
804 >    register EPNODE      *ep
805 > )
806   {
807      register EPNODE  *ep1;
808  
# Line 763 | Line 826 | register EPNODE         *ep;
826  
827  
828   int
829 < isconstfun(ep)                  /* is ep linked to a constant function? */
830 < register EPNODE  *ep;
829 > isconstfun(                     /* is ep linked to a constant function? */
830 >    register EPNODE      *ep
831 > )
832   {
833      register EPNODE  *dp;
834      register LIBR  *lp;
835  
836      if (ep->type != VAR)
837          return(0);
838 <    if ((dp = ep->v.ln->def) != NULL)
838 >    if ((dp = ep->v.ln->def) != NULL) {
839          if (dp->v.kid->type == FUNC)
840              return(dp->type == ':');
841          else
842              return(0);          /* don't identify masked library functions */
843 +    }
844      if ((lp = ep->v.ln->lib) != NULL)
845          return(lp->atyp == ':');
846      return(0);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines